new(core.gbapp): BASIC new keywords and saving to MSExcel.
This commit is contained in:
parent
63dfc03c15
commit
2d0f81c8c3
16 changed files with 399 additions and 30 deletions
133
package-lock.json
generated
133
package-lock.json
generated
|
@ -4263,6 +4263,13 @@
|
||||||
"safe-buffer": "~5.1.1",
|
"safe-buffer": "~5.1.1",
|
||||||
"string_decoder": "~1.1.1",
|
"string_decoder": "~1.1.1",
|
||||||
"util-deprecate": "~1.0.1"
|
"util-deprecate": "~1.0.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"string_decoder": {
|
"string_decoder": {
|
||||||
|
@ -4271,6 +4278,13 @@
|
||||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"safe-buffer": "~5.1.0"
|
"safe-buffer": "~5.1.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4308,6 +4322,13 @@
|
||||||
"safe-buffer": "~5.1.1",
|
"safe-buffer": "~5.1.1",
|
||||||
"string_decoder": "~1.1.1",
|
"string_decoder": "~1.1.1",
|
||||||
"util-deprecate": "~1.0.1"
|
"util-deprecate": "~1.0.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"string_decoder": {
|
"string_decoder": {
|
||||||
|
@ -4316,6 +4337,13 @@
|
||||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"safe-buffer": "~5.1.0"
|
"safe-buffer": "~5.1.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4375,6 +4403,13 @@
|
||||||
"integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
|
"integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"safe-buffer": "5.1.2"
|
"safe-buffer": "5.1.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"content-type": {
|
"content-type": {
|
||||||
|
@ -4575,6 +4610,14 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"safe-buffer": "~5.1.1"
|
"safe-buffer": "~5.1.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cookie": {
|
"cookie": {
|
||||||
|
@ -5890,6 +5933,11 @@
|
||||||
"version": "6.7.0",
|
"version": "6.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
|
||||||
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
|
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
|
||||||
|
},
|
||||||
|
"safe-buffer": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -8064,6 +8112,13 @@
|
||||||
"safe-buffer": "~5.1.1",
|
"safe-buffer": "~5.1.1",
|
||||||
"string_decoder": "~1.1.1",
|
"string_decoder": "~1.1.1",
|
||||||
"util-deprecate": "~1.0.1"
|
"util-deprecate": "~1.0.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"string_decoder": {
|
"string_decoder": {
|
||||||
|
@ -8072,6 +8127,13 @@
|
||||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"safe-buffer": "~5.1.0"
|
"safe-buffer": "~5.1.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16139,9 +16201,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"safe-buffer": {
|
"safe-buffer": {
|
||||||
"version": "5.1.2",
|
"version": "5.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
|
||||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
"integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg=="
|
||||||
},
|
},
|
||||||
"safe-regex": {
|
"safe-regex": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
|
@ -17204,6 +17266,13 @@
|
||||||
"safe-buffer": "~5.1.1",
|
"safe-buffer": "~5.1.1",
|
||||||
"string_decoder": "~1.1.1",
|
"string_decoder": "~1.1.1",
|
||||||
"util-deprecate": "~1.0.1"
|
"util-deprecate": "~1.0.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"string_decoder": {
|
"string_decoder": {
|
||||||
|
@ -17212,6 +17281,13 @@
|
||||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"safe-buffer": "~5.1.0"
|
"safe-buffer": "~5.1.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17590,6 +17666,14 @@
|
||||||
"safe-buffer": "~5.1.1",
|
"safe-buffer": "~5.1.1",
|
||||||
"string_decoder": "~1.1.1",
|
"string_decoder": "~1.1.1",
|
||||||
"util-deprecate": "~1.0.1"
|
"util-deprecate": "~1.0.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"string_decoder": {
|
"string_decoder": {
|
||||||
|
@ -17599,6 +17683,14 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"safe-buffer": "~5.1.0"
|
"safe-buffer": "~5.1.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18280,6 +18372,13 @@
|
||||||
"safe-buffer": "~5.1.1",
|
"safe-buffer": "~5.1.1",
|
||||||
"string_decoder": "~1.1.1",
|
"string_decoder": "~1.1.1",
|
||||||
"util-deprecate": "~1.0.1"
|
"util-deprecate": "~1.0.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"string_decoder": {
|
"string_decoder": {
|
||||||
|
@ -18288,6 +18387,13 @@
|
||||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"safe-buffer": "~5.1.0"
|
"safe-buffer": "~5.1.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18587,6 +18693,13 @@
|
||||||
"integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==",
|
"integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"safe-buffer": "~5.1.0"
|
"safe-buffer": "~5.1.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18617,6 +18730,13 @@
|
||||||
"safe-buffer": "~5.1.1",
|
"safe-buffer": "~5.1.1",
|
||||||
"string_decoder": "~1.1.1",
|
"string_decoder": "~1.1.1",
|
||||||
"util-deprecate": "~1.0.1"
|
"util-deprecate": "~1.0.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"string_decoder": {
|
"string_decoder": {
|
||||||
|
@ -18625,6 +18745,13 @@
|
||||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"safe-buffer": "~5.1.0"
|
"safe-buffer": "~5.1.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,15 +84,16 @@
|
||||||
"nexmo": "2.5.2",
|
"nexmo": "2.5.2",
|
||||||
"ngrok": "3.2.7",
|
"ngrok": "3.2.7",
|
||||||
"npm": "6.13.4",
|
"npm": "6.13.4",
|
||||||
"prism-media": "1.2.1",
|
|
||||||
"opn": "6.0.0",
|
"opn": "6.0.0",
|
||||||
"pragmatismo-io-framework": "1.0.20",
|
"pragmatismo-io-framework": "1.0.20",
|
||||||
|
"prism-media": "1.2.1",
|
||||||
"public-ip": "4.0.0",
|
"public-ip": "4.0.0",
|
||||||
"readline": "1.3.0",
|
"readline": "1.3.0",
|
||||||
"reflect-metadata": "0.1.13",
|
"reflect-metadata": "0.1.13",
|
||||||
"request-promise": "4.2.5",
|
"request-promise": "4.2.5",
|
||||||
"request-promise-native": "1.0.8",
|
"request-promise-native": "1.0.8",
|
||||||
"rimraf": "3.0.0",
|
"rimraf": "3.0.0",
|
||||||
|
"safe-buffer": "^5.2.0",
|
||||||
"scanf": "1.1.1",
|
"scanf": "1.1.1",
|
||||||
"sequelize": "5.21.5",
|
"sequelize": "5.21.5",
|
||||||
"sequelize-typescript": "1.1.0",
|
"sequelize-typescript": "1.1.0",
|
||||||
|
|
|
@ -2,5 +2,6 @@
|
||||||
"enabledAdmin": "true",
|
"enabledAdmin": "true",
|
||||||
"searchScore": ".15",
|
"searchScore": ".15",
|
||||||
"nlpScore": ".40",
|
"nlpScore": ".40",
|
||||||
"nlpVsSearch": ".4"
|
"nlpVsSearch": ".4",
|
||||||
|
"autoPackageSync": "gbdialog, gbot, gbtheme"
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,7 @@ import { SwitchBotDialog } from './dialogs/SwitchBot';
|
||||||
import { WelcomeDialog } from './dialogs/WelcomeDialog';
|
import { WelcomeDialog } from './dialogs/WelcomeDialog';
|
||||||
import { WhoAmIDialog } from './dialogs/WhoAmIDialog';
|
import { WhoAmIDialog } from './dialogs/WhoAmIDialog';
|
||||||
import { GuaribasChannel, GuaribasException, GuaribasInstance, GuaribasPackage } from './models/GBModel';
|
import { GuaribasChannel, GuaribasException, GuaribasInstance, GuaribasPackage } from './models/GBModel';
|
||||||
|
import { DialogClass } from './services/GBAPIService';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Package for core.gbapp.
|
* Package for core.gbapp.
|
||||||
|
@ -70,5 +71,6 @@ export class GBCorePackage implements IGBPackage {
|
||||||
WelcomeDialog.setup(min.bot, min);
|
WelcomeDialog.setup(min.bot, min);
|
||||||
WhoAmIDialog.setup(min.bot, min);
|
WhoAmIDialog.setup(min.bot, min);
|
||||||
SwitchBotDialog.setup(min.bot, min);
|
SwitchBotDialog.setup(min.bot, min);
|
||||||
|
DialogClass.setup(min.bot, min);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,15 +32,18 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { TurnContext } from 'botbuilder';
|
import { TurnContext, BotAdapter } from 'botbuilder';
|
||||||
import { WaterfallStepContext } from 'botbuilder-dialogs';
|
import { WaterfallStepContext, WaterfallDialog } from 'botbuilder-dialogs';
|
||||||
import { GBLog, GBMinInstance } from 'botlib';
|
import { GBLog, GBMinInstance } from 'botlib';
|
||||||
import * as crypto from 'crypto';
|
|
||||||
import * as request from 'request-promise-native';
|
import * as request from 'request-promise-native';
|
||||||
import urlJoin = require('url-join');
|
import urlJoin = require('url-join');
|
||||||
import { GBAdminService } from '../../admin.gbapp/services/GBAdminService';
|
import { GBAdminService } from '../../admin.gbapp/services/GBAdminService';
|
||||||
import { AzureDeployerService } from '../../azuredeployer.gbapp/services/AzureDeployerService';
|
import { AzureDeployerService } from '../../azuredeployer.gbapp/services/AzureDeployerService';
|
||||||
import { GBDeployer } from './GBDeployer';
|
import { GBDeployer } from './GBDeployer';
|
||||||
|
const MicrosoftGraph = require("@microsoft/microsoft-graph-client");
|
||||||
|
import { Messages } from "../strings";
|
||||||
|
import { sys } from 'typescript';
|
||||||
|
const request = require('request-promise-native');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @fileoverview General Bots server core.
|
* @fileoverview General Bots server core.
|
||||||
|
@ -58,12 +61,88 @@ class SysClass {
|
||||||
this.deployer = deployer;
|
this.deployer = deployer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async getFileContents(url) {
|
||||||
|
const options = {
|
||||||
|
url: url,
|
||||||
|
method: 'GET',
|
||||||
|
encoding: 'binary'
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await request(options);
|
||||||
|
return Promise.resolve(Buffer.from(res, 'binary').toString);
|
||||||
|
} catch (error) {
|
||||||
|
return Promise.reject(new Error(error));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getRandomId() {
|
||||||
|
return GBAdminService.getRndReadableIdentifier().substr(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getStock(symbol) {
|
||||||
|
var options = {
|
||||||
|
uri: `http://live-nse.herokuapp.com/?symbol=${symbol}`
|
||||||
|
};
|
||||||
|
|
||||||
|
let data = await request.get(options);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
public async wait(seconds: number) {
|
public async wait(seconds: number) {
|
||||||
// tslint:disable-next-line no-string-based-set-timeout
|
// tslint:disable-next-line no-string-based-set-timeout
|
||||||
const timeout = async (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
|
const timeout = async (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
|
||||||
await timeout(seconds * 1000);
|
await timeout(seconds * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async save(file: string, ...args): Promise<any> {
|
||||||
|
|
||||||
|
let token =
|
||||||
|
await this.min.adminService.acquireElevatedToken(this.min.instance.instanceId);
|
||||||
|
|
||||||
|
let siteId = process.env.SAAS_SHAREPOINT_SITE_ID;
|
||||||
|
let libraryId = process.env.SAAS_SHAREPOINT_LIBRARY_ID;
|
||||||
|
|
||||||
|
let client = MicrosoftGraph.Client.init({
|
||||||
|
authProvider: done => {
|
||||||
|
done(null, token);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const botId = this.min.instance.botId;
|
||||||
|
const path = `/${botId}/${botId}.gbdata`;
|
||||||
|
|
||||||
|
let res = await client.api(
|
||||||
|
`https://graph.microsoft.com/v1.0/sites/${siteId}/lists/${libraryId}/drive/root:${path}:/children`)
|
||||||
|
.get();
|
||||||
|
|
||||||
|
let document = res.value.filter(m => {
|
||||||
|
return m.name === file
|
||||||
|
});
|
||||||
|
|
||||||
|
await client.api(
|
||||||
|
`https://graph.microsoft.com/v1.0/sites/${siteId}/lists/${libraryId}/drive/items/${document[0].id}/workbook/worksheets('Sheet1')/range(address='A1:Z1')/insert`)
|
||||||
|
.post({});
|
||||||
|
|
||||||
|
if (document === undefined) {
|
||||||
|
throw `File '${file}' specified on save GBasic command SAVE not found. Check the .gbdata or the .gbdialog associated.`;
|
||||||
|
}
|
||||||
|
if (args.length > 27) {
|
||||||
|
throw `File '${file}' has a SAVE call with more than 27 arguments. Check the .gbdialog associated.`;
|
||||||
|
}
|
||||||
|
|
||||||
|
let body =
|
||||||
|
{ "values": [[]] };
|
||||||
|
|
||||||
|
for (let index = 0; index < 26; index++) {
|
||||||
|
body.values[0][index] = args[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
let res2 = await client.api(
|
||||||
|
`https://graph.microsoft.com/v1.0/sites/${siteId}/lists/${libraryId}/drive/items/${document[0].id}/workbook/worksheets('Sheet1')/range(address='A2:Z2')`)
|
||||||
|
.patch(body);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public generatePassword() {
|
public generatePassword() {
|
||||||
return GBAdminService.getRndPassword();
|
return GBAdminService.getRndPassword();
|
||||||
}
|
}
|
||||||
|
@ -108,7 +187,7 @@ class SysClass {
|
||||||
uri: urlJoin(url, qs)
|
uri: urlJoin(url, qs)
|
||||||
};
|
};
|
||||||
|
|
||||||
return request.get(options);
|
return await request.get(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -128,10 +207,72 @@ export class DialogClass {
|
||||||
this.internalSys = new SysClass(min, deployer);
|
this.internalSys = new SysClass(min, deployer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static setup(bot: BotAdapter, min: GBMinInstance) {
|
||||||
|
min.dialogs.add(new WaterfallDialog('/gbasic-email', [
|
||||||
|
|
||||||
|
async step => {
|
||||||
|
const locale = step.context.activity.locale;
|
||||||
|
if ((step.options as any).ask) {
|
||||||
|
await step.context.sendActivity(Messages[locale].whats_email);
|
||||||
|
}
|
||||||
|
return await step.prompt("textPrompt", {});
|
||||||
|
},
|
||||||
|
async step => {
|
||||||
|
const locale = step.context.activity.locale;
|
||||||
|
|
||||||
|
const extractEntity = (text) => {
|
||||||
|
return text.match(/([a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9_-]+)/gi);
|
||||||
|
}
|
||||||
|
|
||||||
|
const value = extractEntity(step.result);
|
||||||
|
|
||||||
|
if (value === null) {
|
||||||
|
await step.context.sendActivity(Messages[locale].validation_enter_valid_email);
|
||||||
|
return await step.replaceDialog('/gbasic-email', { ask: true });
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return await step.endDialog(value[0]);
|
||||||
|
}
|
||||||
|
}]));
|
||||||
|
}
|
||||||
|
|
||||||
public sys(): SysClass {
|
public sys(): SysClass {
|
||||||
return this.internalSys;
|
return this.internalSys;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async getToday(step) {
|
||||||
|
var d = new Date(),
|
||||||
|
month = '' + (d.getMonth() + 1),
|
||||||
|
day = '' + d.getDate(),
|
||||||
|
year = d.getFullYear();
|
||||||
|
|
||||||
|
if (month.length < 2)
|
||||||
|
month = '0' + month;
|
||||||
|
if (day.length < 2)
|
||||||
|
day = '0' + day;
|
||||||
|
|
||||||
|
const locale = step.context.activity.locale;
|
||||||
|
switch (locale) {
|
||||||
|
case 'pt-BR':
|
||||||
|
return [day, month, year].join('/');
|
||||||
|
|
||||||
|
case 'en-US':
|
||||||
|
return [month, day, year].join('/');
|
||||||
|
|
||||||
|
default:
|
||||||
|
return [year, month, day].join('/');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getFrom(step) {
|
||||||
|
return step.context.activity.from.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async askEmail(step) {
|
||||||
|
return await step.beginDialog('/gbasic-email');
|
||||||
|
}
|
||||||
|
|
||||||
public async hear(step, promise, previousResolve) {
|
public async hear(step, promise, previousResolve) {
|
||||||
function random(low, high) {
|
function random(low, high) {
|
||||||
return Math.random() * (high - low) + low
|
return Math.random() * (high - low) + low
|
||||||
|
@ -144,7 +285,7 @@ export class DialogClass {
|
||||||
if (previousResolve !== undefined) {
|
if (previousResolve !== undefined) {
|
||||||
previousResolve(opts);
|
previousResolve(opts);
|
||||||
}
|
}
|
||||||
else{
|
else {
|
||||||
await step.beginDialog('/hear', opts);
|
await step.beginDialog('/hear', opts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -211,7 +211,9 @@ export class GBMinService {
|
||||||
|
|
||||||
// Install default BASIC module.
|
// Install default BASIC module.
|
||||||
|
|
||||||
// this.deployer.deployPackage(min, 'packages/default.gbdialog');
|
|
||||||
|
this.deployer.deployPackage(min, 'packages/default.gbdialog');
|
||||||
|
|
||||||
|
|
||||||
// Call the loadBot context.activity for all packages.
|
// Call the loadBot context.activity for all packages.
|
||||||
await this.invokeLoadBot(GBServer.globals.appPackages, GBServer.globals.sysPackages, min);
|
await this.invokeLoadBot(GBServer.globals.appPackages, GBServer.globals.sysPackages, min);
|
||||||
|
|
|
@ -97,10 +97,19 @@ export class GBVMService extends GBService {
|
||||||
public convertGBASICToVBS(code: string) {
|
public convertGBASICToVBS(code: string) {
|
||||||
// Start and End of VB2TS tags of processing.
|
// Start and End of VB2TS tags of processing.
|
||||||
|
|
||||||
code = `<%\n${code}`;
|
code = `<%\n
|
||||||
|
|
||||||
|
from = this.getFrom(step)
|
||||||
|
today = this.getToday(step)
|
||||||
|
id = sys().getRandomId()
|
||||||
|
|
||||||
|
${code}
|
||||||
|
`;
|
||||||
|
|
||||||
// Keywords from General Bots BASIC.
|
// Keywords from General Bots BASIC.
|
||||||
|
|
||||||
|
code = code.replace(/(hear email)/g, `email = askEmail()`);
|
||||||
|
|
||||||
code = code.replace(/(hear)\s*(\w+)/g, ($0, $1, $2) => {
|
code = code.replace(/(hear)\s*(\w+)/g, ($0, $1, $2) => {
|
||||||
return `${$2} = hear()`;
|
return `${$2} = hear()`;
|
||||||
});
|
});
|
||||||
|
@ -109,8 +118,8 @@ export class GBVMService extends GBService {
|
||||||
return `sys().wait(${$2})`;
|
return `sys().wait(${$2})`;
|
||||||
});
|
});
|
||||||
|
|
||||||
code = code.replace(/(generate a password)/g, ($0, $1) => {
|
code = code.replace(/(get stock for )(.*)/g, ($0, $1, $2) => {
|
||||||
return 'let password = sys().generatePassword()';
|
return `let stock = sys().getStock(${$2})`;
|
||||||
});
|
});
|
||||||
|
|
||||||
code = code.replace(/(get)(\s)(.*)/g, ($0, $1, $2) => {
|
code = code.replace(/(get)(\s)(.*)/g, ($0, $1, $2) => {
|
||||||
|
@ -125,6 +134,10 @@ export class GBVMService extends GBService {
|
||||||
return `talk (step, ${$3})\n`;
|
return `talk (step, ${$3})\n`;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
code = code.replace(/(save)(\s)(.*)/g, ($0, $1, $2, $3) => {
|
||||||
|
return `sys().save(${$3})\n`;
|
||||||
|
});
|
||||||
|
|
||||||
code = `${code}\n%>`;
|
code = `${code}\n%>`;
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
|
@ -144,7 +157,7 @@ export class GBVMService extends GBService {
|
||||||
// Convert TS into JS.
|
// Convert TS into JS.
|
||||||
const tsfile: string = `${filename}.ts`;
|
const tsfile: string = `${filename}.ts`;
|
||||||
let tsCode: string = fs.readFileSync(tsfile, 'utf8');
|
let tsCode: string = fs.readFileSync(tsfile, 'utf8');
|
||||||
tsCode = tsCode.replace(/export.*\n/g, `export function ${mainName}(step) { let resolve = undefined;`);
|
tsCode = tsCode.replace(/export.*\n/g, `export function ${mainName}(step:any) { let resolve = undefined;`);
|
||||||
fs.writeFileSync(tsfile, tsCode);
|
fs.writeFileSync(tsfile, tsCode);
|
||||||
|
|
||||||
const tsc = new TSCompiler();
|
const tsc = new TSCompiler();
|
||||||
|
@ -222,11 +235,16 @@ export class GBVMService extends GBService {
|
||||||
parsedCode = beautify(parsedCode, { indent_size: 2, space_in_empty_paren: true })
|
parsedCode = beautify(parsedCode, { indent_size: 2, space_in_empty_paren: true })
|
||||||
fs.writeFileSync(jsfile, parsedCode);
|
fs.writeFileSync(jsfile, parsedCode);
|
||||||
|
|
||||||
const sandbox: DialogClass = new DialogClass(min, deployer);
|
try {
|
||||||
const context = vm.createContext(sandbox);
|
const sandbox: DialogClass = new DialogClass(min, deployer);
|
||||||
vm.runInContext(parsedCode, context);
|
const context = vm.createContext(sandbox);
|
||||||
min.sandBoxMap[mainName] = sandbox;
|
vm.runInContext(parsedCode, context);
|
||||||
GBLog.info(`[GBVMService] Finished loading of ${filename}`);
|
min.sandBoxMap[mainName] = sandbox;
|
||||||
|
GBLog.info(`[GBVMService] Finished loading of ${filename}`);
|
||||||
|
} catch (error) {
|
||||||
|
GBLog.error(`[GBVMService] ERROR loading ${error}`);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -244,6 +262,9 @@ export class GBVMService extends GBService {
|
||||||
code = code.replace(/("[^"]*"|'[^']*')|\bsendEmail\b/g, ($0, $1) => {
|
code = code.replace(/("[^"]*"|'[^']*')|\bsendEmail\b/g, ($0, $1) => {
|
||||||
return $1 === undefined ? 'this.sendEmail' : $1;
|
return $1 === undefined ? 'this.sendEmail' : $1;
|
||||||
});
|
});
|
||||||
|
code = code.replace(/("[^"]*"|'[^']*')|\baskEmail\b/g, ($0, $1) => {
|
||||||
|
return $1 === undefined ? 'this.askEmail' : $1;
|
||||||
|
});
|
||||||
|
|
||||||
// await insertion.
|
// await insertion.
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,9 @@ export const Messages = {
|
||||||
hi: (msg) => `Hello, ${msg}.`,
|
hi: (msg) => `Hello, ${msg}.`,
|
||||||
very_sorry_about_error: `I'm sorry to inform that there was an error which was recorded to be solved.`,
|
very_sorry_about_error: `I'm sorry to inform that there was an error which was recorded to be solved.`,
|
||||||
global_quit: /^(quit|Quit)/i,
|
global_quit: /^(quit|Quit)/i,
|
||||||
canceled: 'Canceled. If I can be useful, let me know how'
|
canceled: 'Canceled. If I can be useful, let me know how',
|
||||||
|
whats_email: "What's your E-mail address?",
|
||||||
|
validation_enter_valid_email: "Please enter a valid e-mail."
|
||||||
},
|
},
|
||||||
'pt-BR': {
|
'pt-BR': {
|
||||||
show_video: 'Vou te mostrar um vídeo. Por favor, aguarde...',
|
show_video: 'Vou te mostrar um vídeo. Por favor, aguarde...',
|
||||||
|
@ -18,6 +20,8 @@ export const Messages = {
|
||||||
hi: (msg) => `Oi, ${msg}.`,
|
hi: (msg) => `Oi, ${msg}.`,
|
||||||
very_sorry_about_error: `Lamento, ocorreu um erro que já foi registrado para ser tratado.`,
|
very_sorry_about_error: `Lamento, ocorreu um erro que já foi registrado para ser tratado.`,
|
||||||
global_quit: /^(sair|Sair)/i,
|
global_quit: /^(sair|Sair)/i,
|
||||||
canceled: 'Cancelado, avise como posso ser útil novamente.'
|
canceled: 'Cancelado, avise como posso ser útil novamente.',
|
||||||
|
whats_email: "Qual seu e-mail?",
|
||||||
|
validation_enter_valid_email: "Por favor digite um email válido."
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -73,5 +73,7 @@ else
|
||||||
talk "Total Value: **" + totalValue + "**"
|
talk "Total Value: **" + totalValue + "**"
|
||||||
talk "Final Value: **" + finalValue + "**"
|
talk "Final Value: **" + finalValue + "**"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
end if
|
end if
|
||||||
end if
|
end if
|
21
packages/default.gbdialog/delivery.vbs.gbignore
Normal file
21
packages/default.gbdialog/delivery.vbs.gbignore
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
' General Bots Copyright (c) Pragmatismo.io. All rights reserved. Licensed under the AGPL-3.0.
|
||||||
|
|
||||||
|
talk "Quer pagar quanto?"
|
||||||
|
hear ammount
|
||||||
|
|
||||||
|
talk "Para onde?"
|
||||||
|
hear address
|
||||||
|
|
||||||
|
if ammount < 5 then
|
||||||
|
talk "O mínimo que vendo este produto é 5."
|
||||||
|
else
|
||||||
|
|
||||||
|
if address is in "Rio" then
|
||||||
|
get payment ammount
|
||||||
|
delivery to address
|
||||||
|
else
|
||||||
|
talk "Vou ver se tenho um parceiro para entregar aí e te falo. Eu só entrego no Rio."
|
||||||
|
end if
|
||||||
|
end if
|
||||||
|
|
||||||
|
talk "Valeu!"
|
12
packages/default.gbdialog/get-payment.vbs.gbignore
Normal file
12
packages/default.gbdialog/get-payment.vbs.gbignore
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
' General Bots Copyright (c) Pragmatismo.io. All rights reserved. Licensed under the AGPL-3.0.
|
||||||
|
|
||||||
|
talk "Quer pagar quanto?"
|
||||||
|
hear ammount
|
||||||
|
|
||||||
|
if ammount < 5 then
|
||||||
|
talk "O mínimo que vendo este produto é 5."
|
||||||
|
else
|
||||||
|
get payment ammount
|
||||||
|
end if
|
||||||
|
|
||||||
|
talk "Valeu!"
|
2
packages/default.gbdialog/get-stock.vbs
Normal file
2
packages/default.gbdialog/get-stock.vbs
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
get stock for "MSFT"
|
||||||
|
talk "Você sabia, as ações da Microsoft estão em " + stock.value
|
26
packages/default.gbdialog/lab.vbs.gbignore
Normal file
26
packages/default.gbdialog/lab.vbs.gbignore
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
talk "Qual seu pedido?"
|
||||||
|
hear pedido
|
||||||
|
talk "Qual seu e-mail?"
|
||||||
|
hear email
|
||||||
|
talk "Obrigado, seu pedido será processado e retornamos."
|
||||||
|
ask payment
|
||||||
|
|
||||||
|
|
||||||
|
talk "Qual seu pedido?"
|
||||||
|
hear pedido
|
||||||
|
talk "Obrigado. Agora informe seu nome:"
|
||||||
|
Hear nome
|
||||||
|
Talk "Obrigado" + nome + "! Agora falta saber onde vamos entregar. Qual seu endereço?"
|
||||||
|
Hear endereço
|
||||||
|
Save "BistroBot.gbdata\pedidos.xlsx", nome, pedido, endereço, phone
|
||||||
|
Talk "Aguarde, enquanto eu calculo o valor total do seu pedido. Volto em alguns minutos, aguarde!"
|
||||||
|
Total = Ask "+5521999995555", "Qual o valor para o pedido da(o)" + nome +"?"
|
||||||
|
ask payment Total
|
||||||
|
|
||||||
|
Talk "Qual seunome? "
|
||||||
|
Hear nome
|
||||||
|
Talk "Qual o valor pedido?"
|
||||||
|
Hear pedido
|
||||||
|
Save "Contoso.gbdata\ Aprovações.xlsx", nome, pedido, phone
|
||||||
|
Ask "+5521999995555", "Aprove por favor o pedido tal "
|
||||||
|
Talk "Sua aprovação foi enviada, aguarde."
|
11
packages/default.gbdialog/save-on-excel.vbs
Normal file
11
packages/default.gbdialog/save-on-excel.vbs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
|
||||||
|
talk "O seu nome, por favor?"
|
||||||
|
hear nome
|
||||||
|
|
||||||
|
talk "Qual seu pedido?"
|
||||||
|
hear details
|
||||||
|
|
||||||
|
talk "Valeu " + nome + "! Agora falta saber onde vamos entregar. \nQual seu endereço?"
|
||||||
|
hear address
|
||||||
|
|
||||||
|
save "Pedidos.xlsx", id, nome, from, address, details, today
|
|
@ -1,4 +0,0 @@
|
||||||
talk "Qual seu pedido?"
|
|
||||||
hear pedido
|
|
||||||
talk "Obrigado, seu pedido será processado e retornamos."
|
|
||||||
ask payment
|
|
Loading…
Add table
Reference in a new issue