How happy is this emoticon? (2.0) OG post
Task
In this challenge, you will be given an string emoticon, and your task will be to output its happiness.
How?
An emoticon will always have eyes and mouth. It can also include eyebrows and nose. Each part will influence the overall happiness rating, which is the sum of happiness ratings of all parts.  Emoticons may be flipped, reversing the order of parts. Here is the different possible parts and their happiness rating:
Symbol    Flipped symbol    Happiness rating

Eyebrows:

&lt;None&gt;    &lt;None&gt;            0
&lt;         &gt;                -2
[         ]                -1
|         |                 0
]         [                 1
&gt;         &lt;                 2

Eyes:

:         :                 0
;         ;                 1

Noses:

^         ^                 0
-         -                 0

Mouth

&lt;         &gt;                -3
(         )                -2
[         ]                -1
|         |                 0
]         [                 1
)         (                 2
&gt;         &lt;                 3

Test cases:
In        Out

:)        2
&lt;:(      -4
|:-|      0
&gt;;^)      5
(;        3
&gt;-:&lt;     -1
(:|       2

Rules

You must be able to handle flipped emoticons. If the input can be interpreted both ways (for example &lt;:&lt;) you can output either of the possible results
Standard loopholes and I/O rules apply.
This is code-golf, so shortest code wins.
05AB1E, 60 59 bytes
„:;S¡D€gÆI„()SkàĀ-dUv&quot;&gt;)]|&quot;')NXQ×K©.ºDysÃk®g&lt;-X·&lt;*yĀ*}I';åO

Try it online or verify all test cases.
Explanation:

„:;S              # Push string &quot;:;&quot;, and convert it to a list of characters: [&quot;:&quot;,&quot;;&quot;]
    ¡             # Split the (implicit) input-string on these characters
     D            # Duplicate the pair
      €g          # Get the length of each part
        Æ         # Reduce by subtracting
I                 # Push the input again
 „()S             # Push string &quot;()&quot;, and convert it to a list of characters: [&quot;(&quot;,&quot;)&quot;]
     k            # Get the 0-based index of these characters in the string
                  # (or -1 if it isn't present)
      à           # Pop and push the maximum
       Ā          # Check that this is NOT 0 (0 if 0; 1 if -1, 1, 2, or 3)
-                 # Subtract the two from one another
 d                # Check that this is non-negative (&gt;=0)
  U               # And pop and store this result in variable `X`
                  # (X=1 for faces where the mouth is left; X=0 for faces where the
                  # mouth is right or where we couldn't determine mouth/eyebrows)
v                 # Loop over the parts `y` in the pair we duplicated after the split:
 &quot;&gt;)]|&quot;           #  Push string &quot;&gt;)]|&quot;
         N        #  Push the 0-based loop-index
          XQ      #  Check if it's equal to variable `X` (1 if N==X, 0 if N!=X)
       ')   ×    '#  Repeat &quot;)&quot; that many times (&quot;)&quot; if N==X, &quot;&quot; if N!=X)
             K    #  Remove that from string &quot;&gt;)]|&quot;
              ©   #  Store this string in variable `®` (without popping)
               .º #  Mirror it with overlap: &quot;&gt;)]|&quot;→&quot;&gt;)]|[(&lt;&quot; or &quot;&gt;]|&quot;→&quot;&gt;]|[&lt;&quot;
 D                #  Duplicate this mirrored string
  y               #  Push the current part
   s              #  Swap so the copy of the mirrored string is at the top
    Ã             #  Keep only those characters in the part (removes noses &quot;^&quot;/&quot;-&quot;)
     k            #  Get the 0-based index of the character in the mirrored string
      ®g          #  Push string `®`, and pop and push its length
        &lt;         #  Decrease it by 1
         -        #  And subtract this from the index
 X                #  Push variable `X`
  ·               #  Double it
   &lt;              #  Decrease it by 1
    *             #  And multiply the top two values
                  #  (negates the current value if X==0, or leaves it as is if X==1)
 y                #  Push the current part again
  Ā               #  Check that it's NOT empty (0 if empty; 1 otherwise)
   *              #  And multiply that as well, so empty parts become 0
}I                # After the loop, push the input again
  ';å            '# Check if it contains a &quot;;&quot; (1 if truthy; 0 if falsey)
O                 # And sum all values on the stack
                  # (after which the result is output implicitly)