package jx

import (
	

	
)

// htmlSafeSet holds the value true if the ASCII character with the given
// array position can be safely represented inside a JSON string, embedded
// inside of HTML <script> tags, without any additional escaping.
//
// All values are true except for the ASCII control characters (0-31), the
// double quote ("), the backslash character ("\"), HTML opening and closing
// tags ("<" and ">"), and the ampersand ("&").
var htmlSafeSet = [utf8.RuneSelf]bool{
	' ':      true,
	'!':      true,
	'"':      false,
	'#':      true,
	'$':      true,
	'%':      true,
	'&':      false,
	'\'':     true,
	'(':      true,
	')':      true,
	'*':      true,
	'+':      true,
	',':      true,
	'-':      true,
	'.':      true,
	'/':      true,
	'0':      true,
	'1':      true,
	'2':      true,
	'3':      true,
	'4':      true,
	'5':      true,
	'6':      true,
	'7':      true,
	'8':      true,
	'9':      true,
	':':      true,
	';':      true,
	'<':      false,
	'=':      true,
	'>':      false,
	'?':      true,
	'@':      true,
	'A':      true,
	'B':      true,
	'C':      true,
	'D':      true,
	'E':      true,
	'F':      true,
	'G':      true,
	'H':      true,
	'I':      true,
	'J':      true,
	'K':      true,
	'L':      true,
	'M':      true,
	'N':      true,
	'O':      true,
	'P':      true,
	'Q':      true,
	'R':      true,
	'S':      true,
	'T':      true,
	'U':      true,
	'V':      true,
	'W':      true,
	'X':      true,
	'Y':      true,
	'Z':      true,
	'[':      true,
	'\\':     false,
	']':      true,
	'^':      true,
	'_':      true,
	'`':      true,
	'a':      true,
	'b':      true,
	'c':      true,
	'd':      true,
	'e':      true,
	'f':      true,
	'g':      true,
	'h':      true,
	'i':      true,
	'j':      true,
	'k':      true,
	'l':      true,
	'm':      true,
	'n':      true,
	'o':      true,
	'p':      true,
	'q':      true,
	'r':      true,
	's':      true,
	't':      true,
	'u':      true,
	'v':      true,
	'w':      true,
	'x':      true,
	'y':      true,
	'z':      true,
	'{':      true,
	'|':      true,
	'}':      true,
	'~':      true,
	'\u007f': true,
}

// StrEscape encodes string with html special characters escaping.
func ( *Writer) ( string) bool {
	return strEscape(, )
}

// ByteStrEscape encodes string with html special characters escaping.
func ( *Writer) ( []byte) bool {
	return strEscape(, )
}

func [ byteseq.Byteseq]( *Writer,  ) ( bool) {
	 = .byte('"')

	// Fast path, probably does not require escaping.
	var (
		      = 0
		 = len()
	)
	for ;  <  && !; ++ {
		 := []
		if  >= utf8.RuneSelf || !(htmlSafeSet[]) {
			break
		}
	}
	 =  || writeStreamByteseq(, [:])
	if  ==  {
		return  || .byte('"')
	}
	return  || strEscapeSlow[](, , , )
}

func [ byteseq.Byteseq]( *Writer,  int,  ,  int) ( bool) {
	 := 
	// for the remaining parts, we process them char by char
	for  <  && ! {
		if  := [];  < utf8.RuneSelf {
			if htmlSafeSet[] {
				++
				continue
			}
			if  <  {
				 =  || writeStreamByteseq(, [:])
			}

			switch  {
			case '\\', '"':
				 =  || .twoBytes('\\', )
			case '\n':
				 =  || .twoBytes('\\', 'n')
			case '\r':
				 =  || .twoBytes('\\', 'r')
			case '\t':
				 =  || .twoBytes('\\', 't')
			default:
				// This encodes bytes < 0x20 except for \t, \n and \r.
				// If escapeHTML is set, it also escapes <, >, and &
				// because they can lead to security holes when
				// user-controlled strings are rendered into JSON
				// and served to some browsers.
				 =  || .rawStr(`\u00`) || .twoBytes(hexChars[>>4], hexChars[&0xF])
			}
			++
			 = 
			continue
		}
		,  := byteseq.DecodeRuneInByteseq([:])
		if  == utf8.RuneError &&  == 1 {
			if  <  {
				 =  || writeStreamByteseq(, [:])
			}
			 =  || .rawStr(`\ufffd`)
			++
			 = 
			continue
		}
		// U+2028 is LINE SEPARATOR.
		// U+2029 is PARAGRAPH SEPARATOR.
		// They are both technically valid characters in JSON strings,
		// but don't work in JSONP, which has to be evaluated as JavaScript,
		// and can lead to security holes there. It is valid JSON to
		// escape them, so we do so unconditionally.
		// See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion.
		if  == '\u2028' ||  == '\u2029' {
			if  <  {
				 =  || writeStreamByteseq(, [:])
			}
			 =  || .rawStr(`\u202`) || .byte(hexChars[&0xF])
			 += 
			 = 
			continue
		}
		 += 
	}
	if  < len() {
		 =  || writeStreamByteseq(, [:])
	}
	return  || .byte('"')
}