pxt-microbit 4.1.4 → 4.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/built/common-sim.d.ts +51 -2
  2. package/built/common-sim.js +296 -6
  3. package/built/hexcache/{6526a3337377701ca7bf1d9940f76fdccac145405380ee3ecc2c96f6049e34ce.hex → 0a7e07c684763d50c302169904fdbb9fc387e1f105f5c8a62f369eab7e443b53.hex} +9 -9
  4. package/built/hexcache/{8fc8a1499d69a5d8cc851cf49d16112b3021ab801238204dacf84073acf90e7c.hex → 13247a2921d73de268c2d92a591f952d610020f3c1938dde251c0139d1823417.hex} +9 -9
  5. package/built/hexcache/3237486a484d0d476c16429f4d524f5d3e2b2fd99336859f0cbb588ceb17e16b.hex +14849 -0
  6. package/built/hexcache/72b9e94993590d9bbc5283b9e11d7f3a19235783f6a54231bf9cc657c64d7bc1.hex +14318 -0
  7. package/built/sim-strings.json +3 -3
  8. package/built/sim.js +10 -12
  9. package/built/target-strings.json +2 -1
  10. package/built/target.js +117 -46
  11. package/built/target.json +117 -46
  12. package/built/targetlight.json +5 -5
  13. package/built/web/blockly.css +1 -1
  14. package/built/web/rtlblockly.css +1 -1
  15. package/built/web/rtlsemantic.css +16 -16
  16. package/built/web/semantic.css +16 -16
  17. package/docs/blocks/comments.md +131 -0
  18. package/docs/blocks/loops.md +12 -0
  19. package/docs/device/usb/webusb.md +31 -9
  20. package/docs/device/usb/windows-chrome.md +14 -24
  21. package/docs/device/usb/windows-edge.md +11 -13
  22. package/docs/device/usb.md +10 -4
  23. package/docs/device.md +28 -12
  24. package/docs/docs.md +1 -1
  25. package/docs/extensions.md +126 -2
  26. package/docs/projects/SUMMARY.md +7 -1
  27. package/docs/projects/micro-chat.md +8 -8
  28. package/docs/projects/mood-radio.md +3 -1
  29. package/docs/projects/multi-dice.md +8 -6
  30. package/docs/projects/plot-acceleration.md +2 -2
  31. package/docs/projects/v2-blow-away.md +317 -0
  32. package/docs/projects/v2-clap-lights.md +195 -0
  33. package/docs/projects/v2-countdown.md +151 -0
  34. package/docs/projects/v2-morse-chat.md +297 -0
  35. package/docs/projects/v2-pet-hamster.md +165 -0
  36. package/docs/projects.md +8 -2
  37. package/docs/reference/basic/forever.md +17 -4
  38. package/docs/reference/basic/show-number.md +1 -1
  39. package/docs/reference/game/change.md +10 -6
  40. package/docs/reference/game/get.md +6 -6
  41. package/docs/reference/game/set.md +29 -12
  42. package/docs/reference/loops/every-interval.md +42 -0
  43. package/docs/reference/radio/on-received-buffer.md +1 -0
  44. package/docs/reference/radio/on-received-number.md +2 -0
  45. package/docs/reference/radio/on-received-string.md +1 -0
  46. package/docs/reference/radio/on-received-value.md +1 -0
  47. package/docs/reference/radio/received-packet.md +1 -0
  48. package/docs/reference/radio/send-buffer.md +1 -0
  49. package/docs/reference/radio/send-string.md +1 -0
  50. package/docs/reference/radio/set-group.md +8 -0
  51. package/docs/reference/radio/write-received-packet-to-serial.md +1 -0
  52. package/docs/reference/radio/write-value-to-serial.md +1 -0
  53. package/docs/tutorials-v2.md +39 -0
  54. package/package.json +5 -5
  55. package/sim/public/icons/jacdac.svg +1 -1
  56. package/targetconfig.json +49 -9
  57. package/built/hexcache/02e34856c566087a1e5f0212e31686199c414ee7c8a2b9c36be7167d71548860.hex +0 -13960
  58. package/built/hexcache/447fa4d5b24ea1ca19eab3745af559cd49d5831ea3e3d6750812b3af3de0f2c4.hex +0 -14499
@@ -1075,8 +1075,8 @@ declare namespace pxsim.visuals {
1075
1075
  }
1076
1076
  }
1077
1077
  declare namespace pxsim.settings {
1078
- function _set(key: string, buf: RefBuffer): 0 | -1;
1079
- function _remove(key: string): 0 | -1;
1078
+ function _set(key: string, buf: RefBuffer): -1 | 0;
1079
+ function _remove(key: string): -1 | 0;
1080
1080
  function _exists(key: string): boolean;
1081
1081
  function _get(key: string): RefBuffer;
1082
1082
  function _userClean(): void;
@@ -1179,3 +1179,52 @@ declare namespace pxsim.TouchButtonMethods {
1179
1179
  declare namespace pxsim.AnalogInOutPinMethods {
1180
1180
  function touchButton(name: pins.AnalogInOutPin): TouchButton;
1181
1181
  }
1182
+ declare namespace pxsim {
1183
+ interface WifiSocketBoard extends CommonBoard {
1184
+ wifiSocketState: WifiSocketState;
1185
+ }
1186
+ class WifiSocket {
1187
+ private fd;
1188
+ ws: WebSocket;
1189
+ _err: number;
1190
+ buffers: Uint8Array[];
1191
+ readers: (() => void)[];
1192
+ bytesAvail: number;
1193
+ reqInit: RequestInit;
1194
+ reqUrl: string;
1195
+ reqSent: boolean;
1196
+ constructor(fd: number);
1197
+ openReq(host: string, port: number): Promise<number>;
1198
+ _queue(data: string | Uint8Array | ArrayBuffer): void;
1199
+ openWS(url: string, proto: string[]): Promise<number>;
1200
+ waitRead(): Promise<void>;
1201
+ read(maxlen: number): number | RefBuffer;
1202
+ private handleFetch;
1203
+ write(buf: RefBuffer): Promise<number>;
1204
+ close(): void;
1205
+ }
1206
+ class WifiSocketState {
1207
+ sockets: WifiSocket[];
1208
+ }
1209
+ }
1210
+ declare namespace pxsim._wifi {
1211
+ type int32 = number;
1212
+ export function _allowed(): boolean;
1213
+ export function socketAlloc(): int32;
1214
+ export function socketConnectTLS(fd: int32, host: string, port: int32): Promise<int32>;
1215
+ export function socketWrite(fd: int32, data: RefBuffer): Promise<int32>;
1216
+ export function socketRead(fd: int32, size: int32): Promise<number | RefBuffer>;
1217
+ export function socketBytesAvailable(fd: int32): int32;
1218
+ export function socketClose(fd: int32): int32;
1219
+ export function eventID(): int32;
1220
+ export function scanStart(): void;
1221
+ export function scanResults(): RefBuffer;
1222
+ export function connect(ssid: string, pass: string): int32;
1223
+ export function disconnect(): int32;
1224
+ export function isConnected(): boolean;
1225
+ export function _raiseEvent(id: number): void;
1226
+ export {};
1227
+ }
1228
+ declare namespace pxsim.crypto {
1229
+ function _sha256(bufs: RefCollection): Promise<RefBuffer>;
1230
+ }
@@ -604,22 +604,20 @@ var pxsim;
604
604
  }
605
605
  control.profilingEnabled = profilingEnabled;
606
606
  function __log(priority, str) {
607
- let prefix = "";
608
607
  switch (priority) {
609
608
  case 0:
610
- prefix = "d>";
609
+ console.debug("d>" + str);
611
610
  break;
612
611
  case 1:
613
- prefix = "l>";
612
+ console.log("l>" + str);
614
613
  break;
615
614
  case 2:
616
- prefix = "w>";
615
+ console.warn("w>" + str);
617
616
  break;
618
617
  case 3:
619
- prefix = "e>";
618
+ console.error("e>" + str);
620
619
  break;
621
620
  }
622
- console.log(prefix + str);
623
621
  pxsim.runtime.board.writeSerial(str);
624
622
  }
625
623
  control.__log = __log;
@@ -4689,3 +4687,295 @@ var pxsim;
4689
4687
  AnalogInOutPinMethods.touchButton = touchButton;
4690
4688
  })(AnalogInOutPinMethods = pxsim.AnalogInOutPinMethods || (pxsim.AnalogInOutPinMethods = {}));
4691
4689
  })(pxsim || (pxsim = {}));
4690
+ var pxsim;
4691
+ (function (pxsim) {
4692
+ class WifiSocket {
4693
+ constructor(fd) {
4694
+ this.fd = fd;
4695
+ this.buffers = [];
4696
+ this.readers = [];
4697
+ this.bytesAvail = 0;
4698
+ this.reqInit = {
4699
+ headers: {},
4700
+ credentials: "omit",
4701
+ mode: "cors",
4702
+ cache: "no-cache",
4703
+ redirect: "manual",
4704
+ referrer: "",
4705
+ };
4706
+ this.reqSent = false;
4707
+ }
4708
+ async openReq(host, port) {
4709
+ if (!/^[\w\-\.]+$/.test(host))
4710
+ throw new Error("bad host");
4711
+ this.reqUrl = "https://" + host + ":" + port + "/";
4712
+ return 0;
4713
+ }
4714
+ _queue(data) {
4715
+ let buf;
4716
+ if (data instanceof ArrayBuffer)
4717
+ buf = new Uint8Array(data);
4718
+ else if (data instanceof Uint8Array)
4719
+ buf = data;
4720
+ else
4721
+ buf = pxsim.U.stringToUint8Array(pxsim.U.toUTF8(data));
4722
+ this.buffers.push(buf);
4723
+ if (buf.length && this.bytesAvail == 0)
4724
+ pxsim._wifi._raiseEvent(1000 + this.fd);
4725
+ this.bytesAvail += buf.length;
4726
+ const rr = this.readers;
4727
+ this.readers = [];
4728
+ for (const r of rr)
4729
+ r();
4730
+ }
4731
+ openWS(url, proto) {
4732
+ this.ws = new WebSocket(url, proto);
4733
+ this.ws.binaryType = "arraybuffer";
4734
+ return new Promise((resolve) => {
4735
+ this.ws.onopen = () => {
4736
+ this.ws.onerror = err => {
4737
+ console.log("ws error", err);
4738
+ this._err = -2;
4739
+ };
4740
+ resolve(0);
4741
+ };
4742
+ this.ws.onclose = () => {
4743
+ console.log("ws close");
4744
+ this._err = -20;
4745
+ };
4746
+ this.ws.onmessage = ev => {
4747
+ this._queue(ev.data);
4748
+ };
4749
+ this.ws.onerror = () => resolve(-1);
4750
+ });
4751
+ }
4752
+ waitRead() {
4753
+ return new Promise(resolve => {
4754
+ this.readers.push(resolve);
4755
+ });
4756
+ }
4757
+ read(maxlen) {
4758
+ if (this._err)
4759
+ return this._err;
4760
+ let b = this.buffers[0];
4761
+ if (b) {
4762
+ if (b.length <= maxlen) {
4763
+ this.buffers.shift();
4764
+ }
4765
+ else {
4766
+ this.buffers[0] = b.slice(maxlen);
4767
+ b = b.slice(0, maxlen);
4768
+ }
4769
+ this.bytesAvail -= b.length;
4770
+ return new pxsim.RefBuffer(b);
4771
+ }
4772
+ return null;
4773
+ }
4774
+ async handleFetch() {
4775
+ // we ignore post for now
4776
+ this.reqSent = true;
4777
+ const resp = await fetch(this.reqUrl, this.reqInit);
4778
+ this._queue(`HTTP/1.1 ${resp.status} ${resp.statusText}\r\n`);
4779
+ resp.headers.forEach((v, k) => {
4780
+ if (k.toLowerCase() == "content-length")
4781
+ return;
4782
+ this._queue(`${k}: ${v}\r\n`);
4783
+ });
4784
+ const data = await resp.arrayBuffer();
4785
+ this._queue(`Content-Length: ${data.byteLength}\r\n`);
4786
+ this._queue(`\r\n`);
4787
+ this._queue(data);
4788
+ return 0;
4789
+ }
4790
+ async write(buf) {
4791
+ if (this._err)
4792
+ return this._err;
4793
+ if (this.ws)
4794
+ this.ws.send(buf.data);
4795
+ else {
4796
+ if (this.reqSent)
4797
+ return -2;
4798
+ let str = pxsim.U.fromUTF8(pxsim.U.uint8ArrayToString(buf.data));
4799
+ if (str == "\r\n") {
4800
+ const dummy = this.handleFetch();
4801
+ return 0;
4802
+ }
4803
+ str = str.replace(/\r?\n$/, "");
4804
+ if (!this.reqInit.method) {
4805
+ const m = /^\s*(\S+)\s+\/(\S+)/.exec(str);
4806
+ if (m) {
4807
+ this.reqInit.method = m[1];
4808
+ this.reqUrl += m[2];
4809
+ }
4810
+ }
4811
+ else {
4812
+ const m = /^([^:]+):\s*(.*)/.exec(str);
4813
+ if (m) {
4814
+ this.reqInit.headers[m[1]] = m[2];
4815
+ }
4816
+ }
4817
+ }
4818
+ return 0;
4819
+ }
4820
+ close() {
4821
+ if (this.ws)
4822
+ this.ws.close();
4823
+ }
4824
+ }
4825
+ pxsim.WifiSocket = WifiSocket;
4826
+ class WifiSocketState {
4827
+ constructor() {
4828
+ this.sockets = [null];
4829
+ }
4830
+ }
4831
+ pxsim.WifiSocketState = WifiSocketState;
4832
+ })(pxsim || (pxsim = {}));
4833
+ (function (pxsim) {
4834
+ var _wifi;
4835
+ (function (_wifi) {
4836
+ const MAX_SOCKET = 16;
4837
+ const WIFI_ID = 1234;
4838
+ function _allowed() {
4839
+ var _a, _b, _c;
4840
+ const bid = (_c = (_b = (_a = pxsim.board()) === null || _a === void 0 ? void 0 : _a.runOptions) === null || _b === void 0 ? void 0 : _b.boardDefinition) === null || _c === void 0 ? void 0 : _c.id;
4841
+ return /esp32|-s2/.test(bid);
4842
+ }
4843
+ _wifi._allowed = _allowed;
4844
+ function getState() {
4845
+ const b = pxsim.board();
4846
+ if (!b.wifiSocketState) {
4847
+ if (!_allowed())
4848
+ throw new Error("_wifi not enabled");
4849
+ b.wifiSocketState = new pxsim.WifiSocketState();
4850
+ }
4851
+ return b.wifiSocketState;
4852
+ }
4853
+ function getSock(fd) {
4854
+ if (fd < 0 || fd >= MAX_SOCKET)
4855
+ return null;
4856
+ return getState().sockets[fd];
4857
+ }
4858
+ function socketAlloc() {
4859
+ const state = getState();
4860
+ for (let i = 1; i < state.sockets.length; ++i) {
4861
+ if (!state.sockets[i]) {
4862
+ state.sockets[i] = new pxsim.WifiSocket(i);
4863
+ return i;
4864
+ }
4865
+ }
4866
+ const idx = state.sockets.length;
4867
+ if (idx > MAX_SOCKET)
4868
+ return -1;
4869
+ state.sockets.push(new pxsim.WifiSocket(idx));
4870
+ return idx;
4871
+ }
4872
+ _wifi.socketAlloc = socketAlloc;
4873
+ function socketConnectTLS(fd, host, port) {
4874
+ const sock = getSock(fd);
4875
+ if (!sock)
4876
+ return Promise.resolve(-11);
4877
+ // TODO loosen this up in future
4878
+ if (port == 8883 && /\.azure-devices.net$/.test(host)) {
4879
+ return sock.openWS("wss://" + host + "/$iothub/websocket?iothub-no-client-cert=true", ["mqtt"]);
4880
+ }
4881
+ else if (port == 443 && host == "microsoft.github.io") {
4882
+ return sock.openReq(host, port);
4883
+ }
4884
+ else {
4885
+ console.log("invalid host: " + host);
4886
+ return Promise.resolve(-1);
4887
+ }
4888
+ }
4889
+ _wifi.socketConnectTLS = socketConnectTLS;
4890
+ async function socketWrite(fd, data) {
4891
+ const sock = getSock(fd);
4892
+ if (!sock)
4893
+ return -11;
4894
+ return sock.write(data);
4895
+ }
4896
+ _wifi.socketWrite = socketWrite;
4897
+ async function socketRead(fd, size) {
4898
+ const sock = getSock(fd);
4899
+ if (!sock)
4900
+ return -11;
4901
+ for (;;) {
4902
+ const buf = sock.read(size);
4903
+ if (buf)
4904
+ return buf;
4905
+ await sock.waitRead();
4906
+ }
4907
+ }
4908
+ _wifi.socketRead = socketRead;
4909
+ function socketBytesAvailable(fd) {
4910
+ const sock = getSock(fd);
4911
+ if (!sock)
4912
+ return -11;
4913
+ return sock.bytesAvail;
4914
+ }
4915
+ _wifi.socketBytesAvailable = socketBytesAvailable;
4916
+ function socketClose(fd) {
4917
+ const sock = getSock(fd);
4918
+ if (!sock)
4919
+ return -11;
4920
+ sock.close();
4921
+ return 0;
4922
+ }
4923
+ _wifi.socketClose = socketClose;
4924
+ function eventID() {
4925
+ return WIFI_ID;
4926
+ }
4927
+ _wifi.eventID = eventID;
4928
+ function scanStart() {
4929
+ _raiseEvent(1 /* ScanDone */);
4930
+ }
4931
+ _wifi.scanStart = scanStart;
4932
+ function scanResults() {
4933
+ const b = new Uint8Array(7);
4934
+ b[0] = -20; // rssi
4935
+ b[1] = 0; // authmode
4936
+ b.set(pxsim.U.stringToUint8Array("WiFi"), 2);
4937
+ return new pxsim.RefBuffer(b);
4938
+ }
4939
+ _wifi.scanResults = scanResults;
4940
+ function connect(ssid, pass) {
4941
+ _raiseEvent(2 /* GotIP */);
4942
+ return 0;
4943
+ }
4944
+ _wifi.connect = connect;
4945
+ function disconnect() {
4946
+ return 0;
4947
+ }
4948
+ _wifi.disconnect = disconnect;
4949
+ function isConnected() { return true; }
4950
+ _wifi.isConnected = isConnected;
4951
+ function _raiseEvent(id) {
4952
+ pxsim.control.raiseEvent(_wifi.eventID(), id, undefined);
4953
+ }
4954
+ _wifi._raiseEvent = _raiseEvent;
4955
+ })(_wifi = pxsim._wifi || (pxsim._wifi = {}));
4956
+ })(pxsim || (pxsim = {}));
4957
+ (function (pxsim) {
4958
+ var crypto;
4959
+ (function (crypto) {
4960
+ function _sha256(bufs) {
4961
+ var _a, _b;
4962
+ let len = 0;
4963
+ const buffers = bufs.toArray().filter(e => e instanceof pxsim.RefBuffer).map((b) => {
4964
+ len += b.data.length;
4965
+ return b.data;
4966
+ });
4967
+ const concat = new Uint8Array(len);
4968
+ len = 0;
4969
+ for (const b of buffers) {
4970
+ concat.set(b, len);
4971
+ len += b.length;
4972
+ }
4973
+ const r = (_b = (_a = window === null || window === void 0 ? void 0 : window.crypto) === null || _a === void 0 ? void 0 : _a.subtle) === null || _b === void 0 ? void 0 : _b.digest("SHA-256", concat);
4974
+ if (r)
4975
+ return r.then(buf => new pxsim.RefBuffer(new Uint8Array(buf)));
4976
+ else
4977
+ return Promise.resolve(undefined);
4978
+ }
4979
+ crypto._sha256 = _sha256;
4980
+ })(crypto = pxsim.crypto || (pxsim.crypto = {}));
4981
+ })(pxsim || (pxsim = {}));
@@ -8156,14 +8156,14 @@
8156
8156
  :100E9000704700BF43688B4210B400F10804184645
8157
8157
  :100EA000A8BF084632EA220128BF19461B1A9942F8
8158
8158
  :100EB0002044A8BF19465DF8044B00F085BE00BF72
8159
- :100EC000002BBCBF43689B1A002A70B50E4622DB7C
8160
- :100ED00044689918A1421EDC8A421CDCDBB136F062
8161
- :100EE000004118D059428E4213DDB34211DD083063
8162
- :100EF000002E00EB020516DB9C1B2246A919284692
8159
+ :100EC000002BBCBF43689B1A002A70B50E4620DB7E
8160
+ :100ED00044689918A1421CDC8A421ADCCBB136F076
8161
+ :100EE000004116D059428E4214DDB34212DD083063
8162
+ :100EF000002E00EB020515DB9C1B2246A919284693
8163
8163
  :100F000021F0BDFA324628190021BDE8704021F0D9
8164
- :100F1000D0BA002C00DA70BD224608300021BDE8AE
8165
- :100F2000704021F0C6BA74429A192946281921F056
8166
- :100F3000A6FA224628460021BDE8704021F0B9BA41
8164
+ :100F1000D0BA70BD002211464FF0FF33BDE87040DB
8165
+ :100F2000FFF7A0BF74429A192946281921F0A7FAA1
8166
+ :100F3000224628460021BDE8704021F0BABA00BF21
8167
8167
  :100F400003460830596800F03DBE00BF70B5044646
8168
8168
  :100F500000206168490000F011FE6668002E11DD76
8169
8169
  :100F6000094D04F1080100EB4606034611F8012B78
@@ -8390,8 +8390,8 @@
8390
8390
  :101D3000012F944203F1010304D1AB42F5D90020F5
8391
8391
  :101D400030BC704704DB012030BC70470020704776
8392
8392
  :101D50004FF0FF30F4E700BF80887047002A16DD9F
8393
- :101D600010B483880029BCBFC91821EAE1715C1A4C
8394
- :101D7000A24202DB002C0CDD22468B4286BF0630DD
8393
+ :101D600010B484880029BCBF631823EAE371631AA6
8394
+ :101D70009A4202DB002B0CDD1A468C4286BF0630ED
8395
8395
  :101D80004018002011465DF8044BFFF7F7BE0348EA
8396
8396
  :101D9000704702485DF8044B704700BF982F04005D
8397
8397
  :101DA00078B371B32DE9F047858822EAE272AA423E
@@ -8237,14 +8237,14 @@
8237
8237
  :1013A00008041846A8BF084632EA220128BF194699
8238
8238
  :1013B0001B1A99422044A8BF19465DF8044B00F05F
8239
8239
  :1013C00085BE00BF002BBCBF43689B1A002A70B5C6
8240
- :1013D0000E4622DB44689918A1421EDC8A421CDCBE
8241
- :1013E000DBB136F0004118D059428E4213DDB342D2
8242
- :1013F00011DD0830002E00EB020516DB9C1B224697
8240
+ :1013D0000E4620DB44689918A1421CDC8A421ADCC4
8241
+ :1013E000CBB136F0004116D059428E4214DDB342E3
8242
+ :1013F00012DD0830002E00EB020515DB9C1B224697
8243
8243
  :10140000A919284623F099F9324628190021BDE888
8244
- :10141000704023F0ACB9002C00DA70BD22460830D1
8245
- :101420000021BDE8704023F0A2B974429A19294600
8246
- :10143000281923F082F9224628460021BDE8704091
8247
- :1014400023F095B903460830596800F03DBE00BF4F
8244
+ :10141000704023F0ACB970BD002211464FF0FF338D
8245
+ :10142000BDE87040FFF7A0BF74429A1929462819F9
8246
+ :1014300023F083F9224628460021BDE8704023F0BE
8247
+ :1014400096B900BF03460830596800F03DBE00BFA2
8248
8248
  :1014500070B5044600206168490000F011FE66681E
8249
8249
  :10146000002E11DD094D04F1080100EB460603468C
8250
8250
  :1014700011F8012B141102F00F022C5DAA5C9C7173
@@ -8470,8 +8470,8 @@
8470
8470
  :10223000014F11F8012F944203F1010304D1AB4285
8471
8471
  :10224000F5D9002030BC704704DB012030BC70475A
8472
8472
  :10225000002070474FF0FF30F4E700BF80887047E0
8473
- :10226000002A16DD10B483880029BCBFC91821EAF2
8474
- :10227000E1715C1AA24202DB002C0CDD22468B428B
8473
+ :10226000002A16DD10B484880029BCBF631823EA55
8474
+ :10227000E371631A9A4202DB002B0CDD1A468C4292
8475
8475
  :1022800086BF06304018002011465DF8044BFFF76A
8476
8476
  :10229000F7BE0348704702485DF8044B704700BF23
8477
8477
  :1022A0000C53040078B371B32DE9F047858822EA16