Operators

[Previous << Values and Types](https://qiita.com/flowcadence/items/c917af1e35cd46cf6a7f)
[Next >> Functions](https://qiita.com/flowcadence/items/6518644e68d32b032530)

https://qiita.com/flowcadence/items/3073d69c6e9895e68b5a#cadenceの言語仕様を学ぶ

演算子とは、1つまたは複数の値に対して演算を行う特別な記号です。単項演算子、2項演算子、3項演算子があります。
* 単項演算子は、単一の値に対して演算を実行します。単項演算子の記号は値の前に表示されます。
* 二項演算子は、2つの値に対して演算を実行します。二項演算子の記号は2つの値の間に表示されます（中置）。
* 三項演算子は、3つの値に対して演算を実行します。最初の演算子の記号は最初の値と2番目の値の間に、2番目の演算子の記号は2番目の値と3番目の値の間に表示されます（中置）。

<h1 id="Assignment Operator (=)">Assignment Operator (=)</h1>

2項代入演算子=は、変数に新しい値を代入するために使用できます。これはステートメントでのみ使用でき、式(expression)では使用できません。
```ruby
var a = 1
a = 2
/* `a` is `2` */


var b = 3
var c = 4

/* Invalid: The assignment operation cannot be used in an expression. */
a = b = c

/* Instead, the intended assignment must be written in multiple statements. */
b = c
a = b
```
定数への代入は出来ません。
```ruby
let a = 1
/* Invalid: Assignments are only for variables, not constants. */
a = 2
```
代入オペランドの左辺は識別子でなければなりません。配列やディクショナリの場合、この識別子は1つ以上のインデックスまたはアクセス式を伴うことができます。
```ruby
/* Declare an array of integers. */
let numbers = [1, 2]

/* Change the first element of the array. */
numbers[0] = 3

/* `numbers` is `[3, 2]` */
```
```ruby
/* Declare an array of arrays of integers. */
let arrays = [[1, 2], [3, 4]]

/* Change the first element in the second array */
arrays[1][0] = 5

/* `arrays` is `[[1, 2], [5, 4]]` */
```
```ruby
let dictionaries = {
  true: {1: 2},
  false: {3: 4}
}

dictionaries[false][3] = 0

/* `dictionaries` is `{
 *   true: {1: 2},
 *   false: {3: 0}
 *  }` 
 */
```

<h1 id="Force-assignment operator (<-!)">Force-assignment operator (<-!)</h1>

強制代入演算子 (`<-!`) は、リソース型値をオプショナル型変数に代入します（代入先の変数が nil の場合）。代入先の変数が nil でない場合、プログラムの実行は中断されます。

強制代入演算子は、[リソース型](https://qiita.com/flowcadence/items/f9b95df70c80a90d3a20)に対してのみ使用されます。

<h1 id="Swapping Operator (<->)">Swapping Operator (<->)</h1>

2項スワップ演算子`<->`は、2つの変数の値を交換するために使用できます。これはステートメント内でのみ使用でき、式内では使用できません。
```ruby
var a = 1
var b = 2
a <-> b
/* `a` is `2` 
   `b` is `1` */

var c = 3

/* Invalid: The swap operation cannot be used in an expression. */
a <-> b <-> c

/* Instead, the intended swap must be written in multiple statements. */
b <-> c
a <-> b
```
スワップ操作の両辺は変数でなければならず、定数への代入は無効です。
```ruby
var a = 1
let b = 2

/* Invalid: Swapping is only possible for variables, not constants. */
a <-> b
```
スワップ操作の両側は、識別子か、それに続く1つ以上のインデックスまたはアクセス式でなければなりません。

<h1 id="Arithmetic-Operators">Arithmetic Operators</h1>

単項の pefix 演算子`-`は整数を反転します。
```ruby
let a = 1
-a  /* is `-1` */
```
2進演算子は4つあります。
* 足し算：`+`
* 引き算：`-`
* 掛け算：`*`
* 割り算：`/`
* 余り：`%`
```ruby
let a = 1 + 2
/* `a` is `3` */
```
演算子の引数は同じ型でなければなりません。結果は常に引数と同じ型になります。

除算および余り演算子は、除数がゼロの場合にプログラムを中断します。

符号付き整数型`Int8`、`Int16`、`Int32`、`Int64`、`Int128`、`Int256`、および符号なし整数型`UInt8`、`UInt16`、`UInt32`、`UInt64`、`UInt128`、`UInt256`での算術演算では、値がオーバーフローまたはアンダーフローすることはありません。
```ruby
let a: UInt8 = 255

/* Run-time error: The result `256` does not fit in the range of `UInt8`,
 * thus a fatal overflow error is raised and the program aborts
 */
let b = a + 1
```
```ruby
let a: Int8 = 100
let b: Int8 = 100

/* Run-time error: The result `10000` does not fit in the range of `Int8`,
 * thus a fatal overflow error is raised and the program aborts
 */
let c = a * b
```
```ruby
let a: Int8 = -128

/* Run-time error: The result `128` does not fit in the range of `Int8`,
 * thus a fatal overflow error is raised and the program aborts
 */
let b = -a
```
符号なし整数型`Word8`、`Word16`、`Word32`、`Word64`の算術演算では、値がオーバーフローまたはアンダーフローする場合があります。

例えば、符号なし8ビット整数の最大値は255（2進数11111111）です。1を加算するとオーバーフローが発生し、8ビットに切り捨てられ、値は0になります。

```ruby
/*    11111111 = 255
 * +         1
 * = 100000000 = 0   */
```
```ruby
let a: Word8 = 255
a + 1 // is `0`
```
同様に、最小値0から1を引くと、結果は最大値255になります。
```ruby
/*    00000000
 * -         1
 * =  11111111 = 255  */
```
```ruby
let b: Word8 = 0
b - 1  // is `255`
```

<h1 id="Arithmetics-on-number-super-types">Arithmetics on number super-types</h1>

算術演算子は、数値のスーパータイプ（`Number`、`SignedNumber`、`FixedPoint`、`SignedFixedPoint`、`Integer`、`SignedInteger`）ではサポートされていません。実行時に成功する場合としない場合があるためです。
```ruby
let x: Integer = 3 as Int8
let y: Integer = 4 as Int8

let z: Integer = x + y    /* Static error */
```
これらの型の値は、算術演算を実行する前に希望する型にキャストする必要があります。
```ruby
let z: Integer = (x as! Int8) + (y as! Int8)
```

<h1 id="Logical-Operators">Logical Operators</h1>

論理演算子は、ブール値の`true`および`false`と一緒に使用します。
* 論理NOT：`!a`

この単項演算子は、ブール値を論理的に否定します。
```ruby
let a = true
!a  /* is `false` */
```
* 論理AND：`a && b`
```ruby
true && true  // is `true`

true && false  // is `false`

false && true  // is `false`

false && false  // is `false`
```
左辺が false の場合、右辺は評価されません。
* 論理 OR：`a || b`
```ruby
true || true  // is `true`

true || false  // is `true`

false || true  // is `true`

false || false // is `false`
```
左辺が真であれば、右辺は評価されない。

<h1 id="Comparison-Operators">Comparison Operators</h1>

比較演算子は、ブール値および整数値で動作します。
* 等価性：`==`は、ブーリアン、数値、アドレス、文字列、文字、列挙型、パス、`Type`、参照、`Void`値（`()`）でサポートされています。可変長配列、固定長配列、ディクショナリ、オプショナルも、それらの内部型がサポートしていれば、等価性テストをサポートします。等価演算子の両辺はオプショナルである場合もあり、異なるレベルのオプショナルである場合もあります。そのため、例えば、非オプショナルと二重オプショナル（`??`）で比較することも可能です。
```ruby
1 == 1
/* is `true` */

1 == 2
/* is `false` */
```
```ruby
true == true  // is `true`

true == false  // is `false`
```
```ruby
let x: Int? = 1
x == nil  /* is `false` */
```
```ruby
let x: Int = 1
x == nil  /* is `false` */
```
```ruby
/* Comparisons of different levels of optionals are possible. */
let x: Int? = 2
let y: Int?? = nil
x == y  /* is `false` */
```
```ruby
/* Comparisons of different levels of optionals are possible. */
let x: Int? = 2
let y: Int?? = 2
x == y  /* is `true` */
```
```ruby
/* Equality tests of arrays are possible if their inner types are equatable. */
let xs: [Int] = [1, 2, 3]
let ys: [Int] = [1, 2, 3]
xs == ys /* is `true` */

let xss: [[Int]] = [xs, xs, xs]
let yss: [[Int]] = [ys, ys, ys]
xss == yss /* is `true` */
```
```ruby
/* Equality also applies to fixed-size arrays. If their lengths differ, the result is a type error. */
let xs: [Int; 2] = [1, 2]
let ys: [Int; 2] = [0 + 1, 1 + 1]
xs == ys /* is `true` */
```
```ruby
/* Equality tests of dictionaries are possible if the key and value types are equatable. */
let d1 = {"abc": 1, "def": 2}
let d2 = {"abc": 1, "def": 2}
d1 == d2 /* is `true` */

let d3 = {"abc": {1: {"a": 1000}, 2: {"b": 2000}}, "def": {4: {"c": 1000}, 5: {"d": 2000}}}
let d4 = {"abc": {1: {"a": 1000}, 2: {"b": 2000}}, "def": {4: {"c": 1000}, 5: {"d": 2000}}}
d3 == d4 /* is `true` */
```
* 不等号: `!=`は、ブール値、数値、アドレス、文字列、文字、列挙enum、パス、`Type`、参照、`Void`値（`()`）でサポートされています。可変長配列、固定長配列、ディクショナリ、オプショナルも、それらの内部の型がサポートしていれば、不等号テストをサポートします。
不等号演算子の両辺は、オプショナルであることもあり、異なるレベルであることもあります。例えば、オプショナルでないものとダブルオプショナル（`??`）で比較することも可能です。
```ruby
1 != 1 
/* is `false` */

1 != 2 
/* is `true` */
```
```ruby
true != true  // is `false`

true != false  // is `true`
```
```ruby
let x: Int? = 1
x != nil  /* is `true` */
```
```ruby
let x: Int = 1
x != nil  /* is `true` */
```
```ruby
/* Comparisons of different levels of optionals are possible. */
let x: Int? = 2
let y: Int?? = nil
x != y  /* is `true` */
```
```ruby
/* Comparisons of different levels of optionals are possible. */
let x: Int? = 2
let y: Int?? = 2
x != y  /* is `false` */
```
```ruby
/* Inequality tests of arrays are possible if their inner types are equatable. */
let xs: [Int] = [1, 2, 3]
let ys: [Int] = [4, 5, 6]
xs != ys /* is `true` */
```
```ruby
/* Inequality also applies to fixed-size arrays. If their lengths differ, the result is a type error. */
let xs: [Int; 2] = [1, 2]
let ys: [Int; 2] = [1, 2]
xs != ys /* is `false` */
```
```ruby
/* Inequality tests of dictionaries are possible if the key and value types are equatable. */
let d1 = {"abc": 1, "def": 2}
let d2 = {"abc": 1, "def": 500}
d1 != d2 /* is `true` */

let d3 = {"abc": {1: {"a": 1000}, 2: {"b": 2000}}, "def": {4: {"c": 1000}, 5: {"d": 2000}}}
let d4 = {"abc": {1: {"a": 1000}, 2: {"b": 2000}}, "def": {4: {"c": 1000}, 5: {"d": 2000}}}
d3 != d4 /* is `false` */
```
* Less Than: `<` は 整数、ブール値、文字、文字列の場合のみ可能
```ruby
1 <= 1
// is `true`

1 <= 2
// is `true`

2 <= 1
// is `false`

false <= true
// is `true`

true <= true
// is `true`

true <= false
// is `false`

"c"  <= "a"
// is `false`

"z"  <= "z"
// is `true`

"a" <= "A"
// is `false`

"" <= ""
// is `true`

"" <= "a"
// is `true`

"az" <= "b"
// is `true`

"xAB" <= "Xab"
// is `false`
```
* Greater than: `>` は 整数、ブール値、文字、文字列型に対して
```ruby
1 > 1
// is `false`

1 > 2
// is `false`

2 > 1
// is `true`

false > true
// is `false`

true > true
// is `false`

true > false
// is `true`

"c"  > "a"
// is `true`

"g"  > "g"
// is `false`

"a" > "A"
// is `true`

"" > ""
// is `false`

"" > "a"
// is `false`

"az" > "b"
// is `false`

"xAB" > "Xab"
// is `true`
```
* Greater or equal than: `>=` は 整数、ブール値、文字、文字列型に対して
```ruby
1 >= 1
// is `true`

1 >= 2
// is `false`

2 >= 1
// is `true`

false >= true
// is `false`

true >= true
// is `true`

true >= false
// is `true`

"c"  >= "a"
// is `true`

"q"  >= "q"
// is `true`

"a" >= "A"
// is `true`

"" >= ""
// is `true`

"" >= "a"
// is `true`

"az" >= "b"
// is `true`

"xAB" >= "Xab"
// is `false`
```

<h1 id="Comparing-number-super-types">Comparing number super-types</h1>

算術演算子と同様に、比較演算子も数値のスーパータイプ（`Number`、`SignedNumberFixedPoint`、`SignedFixedPoint`、`Integer`、`SignedInteger`）ではサポートされていません。実行時に成功する場合もあれば、しない場合もあるためです。

```ruby
let x: Integer = 3 as Int8
let y: Integer = 4 as Int8

let z: Bool = x > y    /* Static error */
```
これらの型の値は、算術演算を実行する前に希望する型にキャストする必要があります。
```ruby
let z: Bool = (x as! Int8) > (y as! Int8)
```

<h1 id="Bitwise-Operators">Bitwise Operators</h1>

ビット演算子は、符号なしおよび符号付き整数の個々のビットの操作を可能にします。これらは、低レベルのプログラミングでよく使用されます。
* ビット演算子 AND: は `a & b`
入力の整数両方のビットが1の場合にのみ、ビットが1である新しい整数を返します。

```ruby
let firstFiveBits = 0b11111000
let lastFiveBits  = 0b00011111
let middleTwoBits = firstFiveBits & lastFiveBits  /* is 0b00011000 */
```
* ビット演算子 OR: `a | b`
入力整数どちらかのビットが1の場合のみ、ビットが1である新しい整数を返します。
```
let someBits = 0b10110010
let moreBits = 0b01011110
let combinedbits = someBits | moreBits  /* is 0b11111110 */
```
* ビット演算子 XOR: `a ^ b`
入力ビットが異なる場合はそのビットを1、同じ場合は0とする新しい整数を返します。
```ruby
let firstBits = 0b00010100
let otherBits = 0b00000101
let outputBits = firstBits ^ otherBits  /* is 0b00010001 */
```

<h1 id="Bitwise-Shifting-Operators">Bitwise Shifting Operators</h1>

* ビット演算子 LEFT SHIFT: `a << b`
すべてのビットを左に一定数シフトした新しい整数を返します。
```ruby
let someBits = 4
/* is 0b00000100 */
let shiftedBits = someBits << 2 
/* is 0b00010000 */
```
* ビット演算子 RIGHT SHIFT: `a >> b`
すべてのビットを右に一定数だけ移動させた新しい整数を返します。
```ruby
let someBits = 8
/* is 0b00001000 */
let shiftedBits = someBits >> 2
/* is 0b00000010 */
```
符号なし整数の場合は、ビットシフト演算子は[論理シフト](https://en.wikipedia.org/wiki/Logical_shift)を実行し、符号付き整数の場合は、[算術シフト](https://en.wikipedia.org/wiki/Arithmetic_shift)を実行します。また、`a << b`または`a >> b`の場合、`b`は64ビット整数に収まる必要があります。

<h1 id="Ternary-Conditional-Operator">Ternary Conditional Operator</h1>

三項条件演算子は1つしかなく、三項条件演算子（`a ? b : c`）です。

これは if 文のような動作をしますが、式です。最初の演算子の値が true の場合は、2番目の演算子の値が返されます。最初の演算子の値が false の場合は、3番目の値が返されます。

最初の値はブール値（`Bool` 型）でなければなりません。2番目の値と3番目の値は、任意の型とすることができます。結果の型は、2番目と3番目の値の最小共通スーパータイプとなります。
```ruby
let x = 1 > 2 ? 3 : 4
/* `x` is `4` and has type `Int` */

let y = 1 > 2 ? nil : 3
/* `y` is `3` and has type `Int?` */
```

<h1 id="Casting-Operators">Casting Operators</h1>
<h2 id="Static-Casting-Operator-(as)">Static Casting Operator (as)</h2>

静的型付けキャスト演算子`as`は、値を静的に型付けキャストするために使用することができます。

値の静的型が指定された型（target type）のサブタイプである場合、演算子は値を指定された型として返します。

静的型変換は、すなわちプログラムの型チェック時に実行されます。値の実行時型ではなく、値の静的型のみが考慮されます。

つまり、この演算子を使用してダウンキャストを行うことはできません。代わりに[conditional downcasting operator `as?`(条件付きダウンキャスト演算子)](#conditional-downcasting-operator-as)の使用を検討してください。

```ruby
/* Declare a constant named `integer` which has type `Int`. */
let integer: Int = 1

/* Statically cast the value of `integer` to the supertype `Number`.
 * The cast succeeds, because the type of the variable `integer`,
 * the type `Int`, is a subtype of type `Number`.
 * This is an upcast.
 */
let number = integer as Number
/* `number` is `1` and has type `Number` */

/* Declare a constant named `something` which has type `AnyStruct`,
 * with an initial value which has type `Int`.
 */
let something: AnyStruct = 1

/* Statically cast the value of `something` to `Int`.
 * This is invalid, the cast fails, because the static type of the value is type `AnyStruct`,
 * which is not a subtype of type `Int`.
 */
let result = something as Int
```
<h1 id="Conditional Downcasting Operator (as?)">Conditional Downcasting Operator (as?)</h1>

条件付きダウンキャスト演算子`as?`は、値を動的に型変換するために使用することができます。この演算子はオプショナルを返します。値の実行時型がtarget typeの下位型である場合、演算子は値をtarget typeとして返します。そうでない場合は、結果は`nil`となります。

キャストは実行時、すなわちプログラムが実行される時に実行され、静的(すなわちプログラムが確認される)時には実行されません。
```ruby
/* Declare a constant named `something` which has type `AnyStruct`,
 * with an initial value which has type `Int`.
 */
let something: AnyStruct = 1

/* Conditionally downcast the value of `something` to `Int`.
 * The cast succeeds, because the value has type `Int`.
 */
let number = something as? Int
/* `number` is `1` and has type `Int?` */

/* Conditionally downcast the value of `something` to `Bool`.
 * The cast fails, because the value has type `Int`,
 * and `Bool` is not a subtype of `Int`.
 */
let boolean = something as? Bool
/* `boolean` is `nil` and has type `Bool?` */
```
ダウンキャストは具体的な型に対して有効ですが、ネストされた型（配列など）、インターフェイス、オプショナルなどに対しても有効です。
```ruby
/* Declare a constant named `values` which has type `[AnyStruct]`,
 * i.e. an array of arbitrarily typed values.
 */
let values: [AnyStruct] = [1, true]

let first = values[0] as? Int
/* `first` is `1` and has type `Int?` */

let second = values[1] as? Bool
/* `second` is `true` and has type `Bool?` */
```

<h1 id="Force-downcasting Operator (as!)">Force-downcasting Operator (as!)</h1>

強制ダウンキャスト演算子`as!`は、[条件付きダウンキャスト演算子`as?`](#conditional-downcasting-operator-as)と同じ動作をします。ただし、キャストが成功した場合はオプショナルではなく指定された型の値を返し、キャストが失敗した場合は`nil`を返す代わりにプログラムを中止します。
```ruby
/* Declare a constant named `something` which has type `AnyStruct`,
 * with an initial value which has type `Int`.
 */
let something: AnyStruct = 1

/* Force-downcast the value of `something` to `Int`.
 * The cast succeeds, because the value has type `Int`.
 */
let number = something as! Int
/* `number` is `1` and has type `Int` */

/* Force-downcast the value of `something` to `Bool`.
 * The cast fails, because the value has type `Int`,
 * and `Bool` is not a subtype of `Int`.
 */
let boolean = something as! Bool
/* Run-time error */
```

<h1 id="Optional-Operators">Optional Operators</h1>
<h2 id="Nil-Coalescing Operator (??)">Nil-Coalescing Operator (??)</h2>

nil結合演算子`??`は、オプショナルが値を含む場合はその値を返し、オプショナルが値を持たない場合、すなわちオプショナル値が`nil`である場合は代替値を返します。

左辺がnilでない場合、右辺は評価されません。
```ruby
/* Declare a constant which has an optional integer type */
let a: Int? = nil

/* Declare a constant with a non-optional integer type,
 * which is initialized to `a` if it is non-nil, or 42 otherwise.
 */
let b: Int = a ?? 42
/* `b` is 42, as `a` is nil */
```
nil結合演算子は、オプショナル型を持つ値にのみ適用できます。
```ruby
/* Declare a constant with a non-optional integer type. */
let a = 1

/* Invalid: nil-coalescing operator is applied to a value which has a non-optional type
 * (a has the non-optional type `Int`).
 */
let b = a ?? 2
```
```ruby
/* Invalid: nil-coalescing operator is applied to a value which has a non-optional type
 * (the integer literal is of type `Int`).
 */
let c = 1 ?? 2
```
演算子の右辺の型（代替値）は、左辺の型のサブタイプでなければなりません。すなわち、演算子の右辺は、左辺の型に一致する非オプショナル型またはオプショナル型でなければなりません。
```ruby
/* Declare a constant with an optional integer type. */
let a: Int? = nil
let b: Int? = 1
let c = a ?? b
/* `c` is `1` and has type `Int?` */

/* Invalid: nil-coalescing operator is applied to a value of type `Int?`,
 * but the alternative has type `Bool`.
 */
let d = a ?? false
```

<h1 id="Force Unwrap Operator (!)">Force Unwrap Operator (!)</h1>

force-unwrap演算子（`!`）は、オプショナルに値が含まれている場合はその値を返し、オプショナルに値が含まれていない場合、すなわちオプショナルの値が`nil`である場合は、パニック(panic)が発生して実行が中止されます。
```ruby
/* Declare a constant which has an optional integer type */
let a: Int? = nil

/* Declare a constant with a non-optional integer type,
 * which is initialized to `a` if `a` is non-nil.
 * If `a` is nil, the program aborts.
 */
let b: Int = a!
/* The program aborts because `a` is nil. */

/* Declare another optional integer constant */
let c: Int? = 3

/* Declare a non-optional integer
 * which is initialized to `c` if `c` is non-nil.
 * If `c` is nil, the program aborts. */
let d: Int = c!
/* `d` is initialized to 3 because c isn't nil. */
```
force-unwrap演算子は、オプショナルの型を持つ値にのみ適用されます。
```ruby
/* Declare a constant with a non-optional integer type. */
let a = 1

/* Invalid: force-unwrap operator is applied to a value which has a
 * non-optional type (`a` has the non-optional type `Int`).
 */
let b = a!
```
```ruby
/* Invalid: The force-unwrap operator is applied
 * to a value which has a non-optional type
 * (the integer literal is of type `Int`).
 */
let c = 1!
```

<h1 id="Precedence-and-Associativity">Precedence and Associativity</h1>

演算子の優先順位は、高い順から低い順に以下のとおりです。
* 単項演算子の優先順位：`-`、`!`、`<-`
* キャストの優先順位：`as`、`as?`、`as!`
* 乗算の優先順位：`*`、`/`、`%`
* 加算の優先順位：`+`、`-`
* ビットシフトの優先順位：`<<`、`>>`
* ビット論理積の優先順位：`&`
* ビット論理和の優先順位：`^`
* ビット論理和の優先順位：`|`
* nil結合の優先順位：`??`
* 関係演算子の優先順位：`<`、`<=`、`>`、`>=`
* 等価演算子の優先順位：`==`、`!=`
* 論理積演算子の優先順位：`&&`
* 論理和演算子の優先順位：`||`
* 三項演算子の優先順位：`? :`

ただし、以下の演算子は右結合です。
* 三項演算子
* nil結合演算子

優先順位の規則を無効にするために、すなわち、別の順序を示す場合や、混乱を避けるためにデフォルトの順序を強調する場合などには、式を括弧で囲むことができます。例えば、`(2 + 3) * 4`と記述すると、加算が乗算より前に実行されるよう強制され、`5 + (6 * 7)`と記述すると、デフォルトの順序が強調されます。

翻訳元

https://cadence-lang.org/docs/language/operators

***
<b>[Previous << Values and Types](https://qiita.com/flowcadence/items/c917af1e35cd46cf6a7f)
</b>

[Flow blockchain / Cadence version1.0ドキュメント](https://qiita.com/flowcadence/items/3073d69c6e9895e68b5a) (Operators)

<b>[Next >> Functions](https://qiita.com/flowcadence/items/6518644e68d32b032530)</b>