@fuel-ts/account 0.0.0-pr-1699-20240214105147 → 0.0.0-pr-1699-20240214162234

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.

Potentially problematic release.


This version of @fuel-ts/account might be problematic. Click here for more details.

Files changed (34) hide show
  1. package/dist/account.d.ts +1 -0
  2. package/dist/account.d.ts.map +1 -1
  3. package/dist/connectors/fuel.d.ts +9 -4
  4. package/dist/connectors/fuel.d.ts.map +1 -1
  5. package/dist/connectors/index.d.ts +0 -4
  6. package/dist/connectors/index.d.ts.map +1 -1
  7. package/dist/connectors/types/index.d.ts +1 -1
  8. package/dist/connectors/types/index.d.ts.map +1 -1
  9. package/dist/connectors/types/local-storage.d.ts +11 -0
  10. package/dist/connectors/types/local-storage.d.ts.map +1 -0
  11. package/dist/index.global.js +72 -1270
  12. package/dist/index.global.js.map +1 -1
  13. package/dist/index.js +74 -302
  14. package/dist/index.js.map +1 -1
  15. package/dist/index.mjs +73 -298
  16. package/dist/index.mjs.map +1 -1
  17. package/dist/providers/provider.d.ts.map +1 -1
  18. package/dist/test-utils.global.js +43 -24
  19. package/dist/test-utils.global.js.map +1 -1
  20. package/dist/test-utils.js +43 -24
  21. package/dist/test-utils.js.map +1 -1
  22. package/dist/test-utils.mjs +43 -24
  23. package/dist/test-utils.mjs.map +1 -1
  24. package/package.json +16 -16
  25. package/dist/connectors/default-connector.d.ts +0 -7
  26. package/dist/connectors/default-connector.d.ts.map +0 -1
  27. package/dist/connectors/fuel-wallet-connector.d.ts +0 -54
  28. package/dist/connectors/fuel-wallet-connector.d.ts.map +0 -1
  29. package/dist/connectors/fuel-wallet-development-connector.d.ts +0 -7
  30. package/dist/connectors/fuel-wallet-development-connector.d.ts.map +0 -1
  31. package/dist/connectors/fuelet-wallet-connector.d.ts +0 -8
  32. package/dist/connectors/fuelet-wallet-connector.d.ts.map +0 -1
  33. package/dist/connectors/types/fuel-storage.d.ts +0 -11
  34. package/dist/connectors/types/fuel-storage.d.ts.map +0 -1
package/dist/index.js CHANGED
@@ -73,13 +73,11 @@ __export(src_exports, {
73
73
  FuelConnectorEventType: () => FuelConnectorEventType,
74
74
  FuelConnectorEventTypes: () => FuelConnectorEventTypes,
75
75
  FuelConnectorMethods: () => FuelConnectorMethods,
76
- FuelWalletConnector: () => FuelWalletConnector,
77
- FuelWalletDevelopmentConnector: () => FuelWalletDevelopmentConnector,
78
76
  FuelWalletLocked: () => FuelWalletLocked,
79
77
  FuelWalletProvider: () => FuelWalletProvider,
80
- FueletWalletConnector: () => FueletWalletConnector,
81
78
  HDWallet: () => hdwallet_default,
82
79
  Language: () => Language,
80
+ LocalStorage: () => LocalStorage,
83
81
  MNEMONIC_SIZES: () => MNEMONIC_SIZES,
84
82
  MemoryStorage: () => MemoryStorage,
85
83
  MessageTypes: () => MessageTypes,
@@ -116,7 +114,6 @@ __export(src_exports, {
116
114
  calculatePriceWithFactor: () => calculatePriceWithFactor,
117
115
  calculateTransactionFee: () => calculateTransactionFee,
118
116
  coinQuantityfy: () => coinQuantityfy,
119
- defaultConnectors: () => defaultConnectors,
120
117
  deferPromise: () => deferPromise,
121
118
  dispatchFuelConnectorEvent: () => dispatchFuelConnectorEvent,
122
119
  english: () => english,
@@ -3904,23 +3901,6 @@ var _Provider = class {
3904
3901
  if (estimateTxDependencies) {
3905
3902
  await this.estimateTxDependencies(transactionRequest);
3906
3903
  }
3907
- const { gasUsed, minGasPrice } = await this.getTransactionCost(transactionRequest, [], {
3908
- estimateTxDependencies: false,
3909
- estimatePredicates: false
3910
- });
3911
- if ((0, import_math14.bn)(minGasPrice).gt((0, import_math14.bn)(transactionRequest.gasPrice))) {
3912
- throw new import_errors13.FuelError(
3913
- import_errors13.ErrorCode.GAS_PRICE_TOO_LOW,
3914
- `Gas price '${transactionRequest.gasPrice}' is lower than the required: '${minGasPrice}'.`
3915
- );
3916
- }
3917
- const isScriptTransaction = transactionRequest.type === import_transactions17.TransactionType.Script;
3918
- if (isScriptTransaction && (0, import_math14.bn)(gasUsed).gt((0, import_math14.bn)(transactionRequest.gasLimit))) {
3919
- throw new import_errors13.FuelError(
3920
- import_errors13.ErrorCode.GAS_LIMIT_TOO_LOW,
3921
- `Gas limit '${transactionRequest.gasLimit}' is lower than the required: '${gasUsed}'.`
3922
- );
3923
- }
3924
3904
  const encodedTransaction = (0, import_ethers18.hexlify)(transactionRequest.toTransactionBytes());
3925
3905
  if (awaitExecution) {
3926
3906
  const subscription = this.operations.submitAndAwait({ encodedTransaction });
@@ -4880,10 +4860,14 @@ var Account = class extends import_interfaces.AbstractAccount {
4880
4860
  const request = new ScriptTransactionRequest(params);
4881
4861
  request.addCoinOutput(import_address4.Address.fromAddressOrString(destination), amount, assetId);
4882
4862
  const { maxFee, requiredQuantities, gasUsed } = await this.provider.getTransactionCost(request);
4883
- const gasPriceToUse = (0, import_math17.bn)(txParams.gasPrice ?? minGasPrice);
4884
- const gasLimitToUse = (0, import_math17.bn)(txParams.gasLimit ?? gasUsed);
4885
- request.gasPrice = gasPriceToUse;
4886
- request.gasLimit = gasLimitToUse;
4863
+ request.gasPrice = (0, import_math17.bn)(txParams.gasPrice ?? minGasPrice);
4864
+ request.gasLimit = (0, import_math17.bn)(txParams.gasLimit ?? gasUsed);
4865
+ this.validateGas({
4866
+ gasUsed,
4867
+ gasPrice: request.gasPrice,
4868
+ gasLimit: request.gasLimit,
4869
+ minGasPrice
4870
+ });
4887
4871
  await this.fund(request, requiredQuantities, maxFee);
4888
4872
  return request;
4889
4873
  }
@@ -4928,7 +4912,13 @@ var Account = class extends import_interfaces.AbstractAccount {
4928
4912
  request,
4929
4913
  [{ amount: (0, import_math17.bn)(amount), assetId: String(assetId) }]
4930
4914
  );
4931
- request.gasLimit = (0, import_math17.bn)(params.gasLimit || gasUsed);
4915
+ request.gasLimit = (0, import_math17.bn)(params.gasLimit ?? gasUsed);
4916
+ this.validateGas({
4917
+ gasUsed,
4918
+ gasPrice: request.gasPrice,
4919
+ gasLimit: request.gasLimit,
4920
+ minGasPrice
4921
+ });
4932
4922
  await this.fund(request, requiredQuantities, maxFee);
4933
4923
  return this.sendTransaction(request);
4934
4924
  }
@@ -4941,6 +4931,7 @@ var Account = class extends import_interfaces.AbstractAccount {
4941
4931
  * @returns A promise that resolves to the transaction response.
4942
4932
  */
4943
4933
  async withdrawToBaseLayer(recipient, amount, txParams = {}) {
4934
+ const { minGasPrice } = this.provider.getGasConfig();
4944
4935
  const recipientAddress = import_address4.Address.fromAddressOrString(recipient);
4945
4936
  const recipientDataArray = (0, import_ethers21.getBytesCopy)(
4946
4937
  "0x".concat(recipientAddress.toHexString().substring(2).padStart(64, "0"))
@@ -4953,14 +4944,20 @@ var Account = class extends import_interfaces.AbstractAccount {
4953
4944
  ...recipientDataArray,
4954
4945
  ...amountDataArray
4955
4946
  ]);
4956
- const params = { script, ...txParams };
4947
+ const params = { script, gasPrice: minGasPrice, ...txParams };
4957
4948
  const request = new ScriptTransactionRequest(params);
4958
4949
  const forwardingQuantities = [{ amount: (0, import_math17.bn)(amount), assetId: import_configs10.BaseAssetId }];
4959
4950
  const { requiredQuantities, maxFee, gasUsed } = await this.provider.getTransactionCost(
4960
4951
  request,
4961
4952
  forwardingQuantities
4962
4953
  );
4963
- request.gasLimit = params.gasLimit ? (0, import_math17.bn)(params.gasLimit) : gasUsed;
4954
+ request.gasLimit = (0, import_math17.bn)(params.gasLimit ?? gasUsed);
4955
+ this.validateGas({
4956
+ gasUsed,
4957
+ gasPrice: request.gasPrice,
4958
+ gasLimit: request.gasLimit,
4959
+ minGasPrice
4960
+ });
4964
4961
  await this.fund(request, requiredQuantities, maxFee);
4965
4962
  return this.sendTransaction(request);
4966
4963
  }
@@ -4989,6 +4986,25 @@ var Account = class extends import_interfaces.AbstractAccount {
4989
4986
  await this.provider.estimateTxDependencies(transactionRequest);
4990
4987
  return this.provider.simulate(transactionRequest, { estimateTxDependencies: false });
4991
4988
  }
4989
+ validateGas({
4990
+ gasUsed,
4991
+ gasPrice,
4992
+ gasLimit,
4993
+ minGasPrice
4994
+ }) {
4995
+ if (minGasPrice.gt(gasPrice)) {
4996
+ throw new import_errors15.FuelError(
4997
+ import_errors15.ErrorCode.GAS_PRICE_TOO_LOW,
4998
+ `Gas price '${gasPrice}' is lower than the required: '${minGasPrice}'.`
4999
+ );
5000
+ }
5001
+ if (gasUsed.gt(gasLimit)) {
5002
+ throw new import_errors15.FuelError(
5003
+ import_errors15.ErrorCode.GAS_LIMIT_TOO_LOW,
5004
+ `Gas limit '${gasLimit}' is lower than the required: '${gasUsed}'.`
5005
+ );
5006
+ }
5007
+ }
4992
5008
  };
4993
5009
 
4994
5010
  // src/wallet/base-wallet-unlocked.ts
@@ -8640,10 +8656,6 @@ var Predicate = class extends Account {
8640
8656
  }
8641
8657
  };
8642
8658
 
8643
- // src/connectors/fuel-wallet-connector.ts
8644
- var import_json_rpc_2 = require("json-rpc-2.0");
8645
- var import_uuid2 = require("uuid");
8646
-
8647
8659
  // src/connectors/fuel-connector.ts
8648
8660
  var import_events2 = require("events");
8649
8661
 
@@ -8703,6 +8715,26 @@ var MessageTypes = /* @__PURE__ */ ((MessageTypes2) => {
8703
8715
  return MessageTypes2;
8704
8716
  })(MessageTypes || {});
8705
8717
 
8718
+ // src/connectors/types/local-storage.ts
8719
+ var LocalStorage = class {
8720
+ storage;
8721
+ constructor(localStorage) {
8722
+ this.storage = localStorage;
8723
+ }
8724
+ async setItem(key, value) {
8725
+ this.storage.setItem(key, value);
8726
+ }
8727
+ async getItem(key) {
8728
+ return this.storage.getItem(key);
8729
+ }
8730
+ async removeItem(key) {
8731
+ this.storage.removeItem(key);
8732
+ }
8733
+ async clear() {
8734
+ this.storage.clear();
8735
+ }
8736
+ };
8737
+
8706
8738
  // src/connectors/fuel-connector.ts
8707
8739
  var FuelConnector = class extends import_events2.EventEmitter {
8708
8740
  name = "";
@@ -8921,261 +8953,6 @@ var FuelConnector = class extends import_events2.EventEmitter {
8921
8953
  }
8922
8954
  };
8923
8955
 
8924
- // src/connectors/fuel-wallet-connector.ts
8925
- var FuelWalletConnector = class extends FuelConnector {
8926
- name = "";
8927
- connected = false;
8928
- installed = false;
8929
- events = FuelConnectorEventTypes;
8930
- metadata = {
8931
- image: "/connectors/fuel-wallet.svg",
8932
- install: {
8933
- action: "Install",
8934
- description: "To connect your Fuel Wallet, install the browser extension.",
8935
- link: "https://chrome.google.com/webstore/detail/fuel-wallet/dldjpboieedgcmpkchcjcbijingjcgok"
8936
- }
8937
- };
8938
- client;
8939
- constructor(name = "Fuel Wallet") {
8940
- super();
8941
- this.name = name;
8942
- this.setMaxListeners(100);
8943
- this.client = new import_json_rpc_2.JSONRPCClient(this.sendRequest.bind(this), this.createRequestId);
8944
- this.setupListener();
8945
- this.setupConnector();
8946
- }
8947
- /**
8948
- * ============================================================
8949
- * Application communication methods
8950
- * ============================================================
8951
- */
8952
- setupConnector() {
8953
- if (typeof window !== "undefined") {
8954
- this.ping().then(() => {
8955
- window.dispatchEvent(new CustomEvent("FuelConnector", { detail: this }));
8956
- }).catch(() => {
8957
- });
8958
- }
8959
- }
8960
- acceptMessage(message) {
8961
- const { data: event } = message;
8962
- return message.origin === window.origin && event.type !== "request" /* request */ && event.connectorName === this.name && event.target === CONNECTOR_SCRIPT;
8963
- }
8964
- setupListener() {
8965
- if (typeof window === "undefined") {
8966
- return;
8967
- }
8968
- window.addEventListener(EVENT_MESSAGE, this.onMessage.bind(this));
8969
- }
8970
- createRequestId() {
8971
- return (0, import_uuid2.v4)();
8972
- }
8973
- postMessage(message, origin) {
8974
- window.postMessage(message, origin || window.origin);
8975
- }
8976
- // eslint-disable-next-line @typescript-eslint/require-await
8977
- async sendRequest(request) {
8978
- if (!request) {
8979
- return;
8980
- }
8981
- this.postMessage({
8982
- type: "request" /* request */,
8983
- target: CONTENT_SCRIPT_NAME,
8984
- connectorName: this.name,
8985
- request
8986
- });
8987
- }
8988
- onResponse(message) {
8989
- this.client.receive(message.response);
8990
- }
8991
- onEvent(message) {
8992
- message.events.forEach((eventData) => {
8993
- if (eventData.event === "start") {
8994
- this.setupConnector();
8995
- } else {
8996
- this.emit(eventData.event, ...eventData.params);
8997
- }
8998
- });
8999
- }
9000
- onMessage = (message) => {
9001
- const messageFroze = Object.freeze(message);
9002
- if (!this.acceptMessage(messageFroze)) {
9003
- return;
9004
- }
9005
- const { data: event } = messageFroze;
9006
- this.onCommunicationMessage(event);
9007
- };
9008
- onCommunicationMessage = (message) => {
9009
- switch (message.type) {
9010
- case "response" /* response */:
9011
- this.onResponse(message);
9012
- break;
9013
- case "event" /* event */:
9014
- this.onEvent(message);
9015
- break;
9016
- default:
9017
- }
9018
- };
9019
- /**
9020
- * ============================================================
9021
- * Connector methods
9022
- * ============================================================
9023
- */
9024
- async ping() {
9025
- return this.client.timeout(800).request("ping", {});
9026
- }
9027
- async isConnected() {
9028
- try {
9029
- return await this.client.request("isConnected", {});
9030
- } catch {
9031
- return false;
9032
- }
9033
- }
9034
- async connect() {
9035
- return this.client.request("connect", {});
9036
- }
9037
- async disconnect() {
9038
- return this.client.request("disconnect", {});
9039
- }
9040
- async accounts() {
9041
- return this.client.request("accounts", {});
9042
- }
9043
- async currentAccount() {
9044
- return this.client.request("currentAccount", {});
9045
- }
9046
- async signMessage(address, message) {
9047
- if (!message.trim()) {
9048
- throw new Error("Message is required");
9049
- }
9050
- return this.client.request("signMessage", {
9051
- address,
9052
- message
9053
- });
9054
- }
9055
- async sendTransaction(address, transaction) {
9056
- if (!transaction) {
9057
- throw new Error("Transaction is required");
9058
- }
9059
- const txRequest = transactionRequestify(transaction);
9060
- const network = await this.currentNetwork();
9061
- const provider = {
9062
- url: network.url
9063
- };
9064
- return this.client.request("sendTransaction", {
9065
- address,
9066
- transaction: JSON.stringify(txRequest),
9067
- provider
9068
- });
9069
- }
9070
- async assets() {
9071
- return this.client.request("assets", {});
9072
- }
9073
- async addAsset(asset) {
9074
- return this.addAssets([asset]);
9075
- }
9076
- async addAssets(assets) {
9077
- const assetsData = assets.map((asset) => {
9078
- const fuelNetworkAsset = asset.networks.find((n) => n.type === "fuel");
9079
- if (!fuelNetworkAsset) {
9080
- throw new Error("Asset for Fuel Network not found!");
9081
- }
9082
- return {
9083
- ...asset,
9084
- imageUrl: asset.icon,
9085
- decimals: fuelNetworkAsset.decimals,
9086
- assetId: fuelNetworkAsset.assetId
9087
- };
9088
- });
9089
- return this.client.request("addAssets", {
9090
- assets: assetsData
9091
- });
9092
- }
9093
- async addABI(contractId, abi) {
9094
- return this.client.request("addAbi", {
9095
- abiMap: {
9096
- [contractId]: abi
9097
- }
9098
- });
9099
- }
9100
- async getABI(contractId) {
9101
- return this.client.request("getAbi", {
9102
- contractId
9103
- });
9104
- }
9105
- async hasABI(contractId) {
9106
- const abi = await this.getABI(contractId);
9107
- return !!abi;
9108
- }
9109
- async currentNetwork() {
9110
- return this.client.request("network", {});
9111
- }
9112
- // eslint-disable-next-line @typescript-eslint/require-await
9113
- async selectNetwork(_network) {
9114
- throw new Error("Method not implemented.");
9115
- }
9116
- async networks() {
9117
- return this.client.request("networks", {});
9118
- }
9119
- async addNetwork(networkUrl) {
9120
- const provider = await Provider.create(networkUrl);
9121
- return this.client.request("addNetwork", {
9122
- network: {
9123
- url: provider.url,
9124
- name: provider.getChain().name
9125
- }
9126
- });
9127
- }
9128
- async version() {
9129
- return this.client.request("version", {
9130
- app: "0.0.0",
9131
- network: "0.0.0"
9132
- });
9133
- }
9134
- };
9135
-
9136
- // src/connectors/fuel-wallet-development-connector.ts
9137
- var FuelWalletDevelopmentConnector = class extends FuelWalletConnector {
9138
- metadata = {
9139
- image: "/connectors/fuel-wallet-dev.svg",
9140
- install: {
9141
- action: "Install",
9142
- description: "To connect your Fuel Wallet, you need to install the browser extension first.",
9143
- link: "https://chrome.google.com/webstore/detail/fuel-wallet-development/hcgmehahnlbhpilepakbdinkhhaackmc"
9144
- }
9145
- };
9146
- constructor() {
9147
- super("Fuel Wallet Development");
9148
- }
9149
- };
9150
-
9151
- // src/connectors/fuelet-wallet-connector.ts
9152
- var FueletWalletConnector = class extends FuelWalletConnector {
9153
- name = "Fuelet Wallet";
9154
- metadata = {
9155
- image: {
9156
- light: "/connectors/fuelet-light.svg",
9157
- dark: "/connectors/fuelet-dark.svg"
9158
- },
9159
- install: {
9160
- action: "Install",
9161
- description: "Install Fuelet Wallet in order to connect it.",
9162
- link: "https://fuelet.app/download/"
9163
- }
9164
- };
9165
- constructor() {
9166
- super("Fuelet Wallet");
9167
- }
9168
- };
9169
-
9170
- // src/connectors/default-connector.ts
9171
- function defaultConnectors({ devMode } = {}) {
9172
- const connectors = [new FuelWalletConnector(), new FueletWalletConnector()];
9173
- if (devMode) {
9174
- connectors.push(new FuelWalletDevelopmentConnector());
9175
- }
9176
- return connectors;
9177
- }
9178
-
9179
8956
  // src/connectors/fuel-wallet-locked.ts
9180
8957
  var FuelWalletLocked = class extends WalletLocked {
9181
8958
  connector;
@@ -9288,9 +9065,7 @@ var _Fuel = class extends FuelConnector {
9288
9065
  constructor(config = _Fuel.defaultConfig) {
9289
9066
  super();
9290
9067
  this.setMaxListeners(1e3);
9291
- this._connectors = config.connectors ?? defaultConnectors({
9292
- devMode: config.devMode
9293
- });
9068
+ this._connectors = config.connectors ?? [];
9294
9069
  this._targetObject = this.getTargetObject(config.targetObject);
9295
9070
  this._storage = config.storage === void 0 ? this.getStorage() : config.storage;
9296
9071
  this.setupMethods();
@@ -9317,15 +9092,15 @@ var _Fuel = class extends FuelConnector {
9317
9092
  */
9318
9093
  getStorage() {
9319
9094
  if (typeof window !== "undefined") {
9320
- return window.localStorage;
9095
+ return new LocalStorage(window.localStorage);
9321
9096
  }
9322
9097
  return void 0;
9323
9098
  }
9324
9099
  /**
9325
9100
  * Setup the default connector from the storage.
9326
9101
  */
9327
- setDefaultConnector() {
9328
- const connectorName = this._storage?.getItem(_Fuel.STORAGE_KEY) || this._connectors[0]?.name;
9102
+ async setDefaultConnector() {
9103
+ const connectorName = await this._storage?.getItem(_Fuel.STORAGE_KEY) || this._connectors[0]?.name;
9329
9104
  if (connectorName) {
9330
9105
  return this.selectConnector(connectorName, {
9331
9106
  emitEvents: false
@@ -9513,7 +9288,7 @@ var _Fuel = class extends FuelConnector {
9513
9288
  this._currentConnector = connector;
9514
9289
  this.emit(this.events.currentConnector, connector);
9515
9290
  this.setupConnectorEvents(Object.values(FuelConnectorEventTypes));
9516
- this._storage?.setItem(_Fuel.STORAGE_KEY, connector.name);
9291
+ await this._storage?.setItem(_Fuel.STORAGE_KEY, connector.name);
9517
9292
  if (options.emitEvents) {
9518
9293
  this.triggerConnectorEvents();
9519
9294
  }
@@ -9595,15 +9370,15 @@ var _Fuel = class extends FuelConnector {
9595
9370
  /**
9596
9371
  * Clean all the data from the storage.
9597
9372
  */
9598
- clean() {
9599
- this._storage?.removeItem(_Fuel.STORAGE_KEY);
9373
+ async clean() {
9374
+ await this._storage?.removeItem(_Fuel.STORAGE_KEY);
9600
9375
  }
9601
9376
  /**
9602
9377
  * Removes all listeners and cleans the storage.
9603
9378
  */
9604
- destroy() {
9379
+ async destroy() {
9605
9380
  this.unsubscribe();
9606
- this.clean();
9381
+ await this.clean();
9607
9382
  }
9608
9383
  };
9609
9384
  var Fuel = _Fuel;
@@ -9627,13 +9402,11 @@ __publicField(Fuel, "defaultConfig", {});
9627
9402
  FuelConnectorEventType,
9628
9403
  FuelConnectorEventTypes,
9629
9404
  FuelConnectorMethods,
9630
- FuelWalletConnector,
9631
- FuelWalletDevelopmentConnector,
9632
9405
  FuelWalletLocked,
9633
9406
  FuelWalletProvider,
9634
- FueletWalletConnector,
9635
9407
  HDWallet,
9636
9408
  Language,
9409
+ LocalStorage,
9637
9410
  MNEMONIC_SIZES,
9638
9411
  MemoryStorage,
9639
9412
  MessageTypes,
@@ -9670,7 +9443,6 @@ __publicField(Fuel, "defaultConfig", {});
9670
9443
  calculatePriceWithFactor,
9671
9444
  calculateTransactionFee,
9672
9445
  coinQuantityfy,
9673
- defaultConnectors,
9674
9446
  deferPromise,
9675
9447
  dispatchFuelConnectorEvent,
9676
9448
  english,