The JavaScript-based parser has been moved to a github repository.

Background on parsing unencrypted ViewState is here followed by part two.

.NET ViewState Byte Sequences

Byte(s) Explanation
0x02 […] Unsigned integer, compose value from 7 bits of each following byte until leading 8th bit equals 0.
0x0201 == 00000010 00000001 == 1  
0x027f == 00000010 01111111 == 127  
0x028101 == 00000010 10000001 00000001 == 1 + (1 « 7) == 129  
0x02a1b22a == 00000010 10100001 10110010 00101010 == 33 + (98 « 7) + (42 « 14) == 44052769  
0x03 [length] […] Container of [length] Booleans
0x05 [length] […] String, a container of [length] bytes
0x09 RGBA component
0x0B […] 0x00 String, usually NULL-terminated, i.e. read bytes until 0x00.
0x0f Pair (tuple of two objects)
0x10 Triplet (tuple of three objects)
0x15 [length] Array of strings
0x16 [length] Container of objects
0x18 Control state
0x1b [12 bytes] Unit
0x1e [length] […] String (identical to 0x05)
0x1f [number] String reference
0x24 [36 bytes] UUID
0x64 empty node
0x65 empty string
0x66 Number 0
0x67 Boolean true
0x68 Boolean false
0xff01 ViewState preamble
Notes The number of elements in a container is defined by [length], which is one or more bytes interpreted as a number in the manner of 0x02.
A container may be empty, i.e. [length] is 0x00.