text:
/*
 *  Date built-ins
 *
 *  Unlike most built-ins, Date has some platform dependencies for getting
 *  UTC time, converting between UTC and local time, and parsing and
 *  formatting time values.  These are all abstracted behind DUK_USE_xxx
 *  config options.  There are built-in platform specific providers for
 *  POSIX and Windows, but external providers can also be used.
 *
 *  See doc/datetime.rst.
 *
 */

#include "duk_internal.h"

/*
 *  Forward declarations
 */

DUK_LOCAL_DECL duk_double_t duk__push_this_get_timeval_tzoffset(duk_context *ctx, duk_small_uint_t flags, duk_int_t *out_tzoffset);
DUK_LOCAL_DECL duk_double_t duk__push_this_get_timeval(duk_context *ctx, duk_small_uint_t flags);
DUK_LOCAL_DECL void duk__twodigit_year_fixup(duk_context *ctx, duk_idx_t idx_val);
DUK_LOCAL_DECL duk_ret_t duk__set_this_timeval_from_dparts(duk_context *ctx, duk_double_t *dparts, duk_small_uint_t flags);

/*
 *  Other file level defines
 */

/* Debug macro to print all parts and dparts (used manually because of debug level). */
#define  DUK__DPRINT_PARTS_AND_DPARTS(parts,dparts)  do { \
		DUK_D(DUK_DPRINT("parts: %ld %ld %ld %ld %ld %ld %ld %ld, dparts: %lf %lf %lf %lf %lf %lf %lf %lf", \
		                 (long) (parts)[0], (long) (parts)[1], \
		                 (long) (parts)[2], (long) (parts)[3], \
		                 (long) (parts)[4], (long) (parts)[5], \
		                 (long) (parts)[6], (long) (parts)[7], \
		                 (double) (dparts)[0], (double) (dparts)[1], \
		                 (double) (dparts)[2], (double) (dparts)[3], \
		                 (double) (dparts)[4], (double) (dparts)[5], \
		                 (double) (dparts)[6], (double) (dparts)[7])); \
	} while (0)
#define  DUK__DPRINT_PARTS(parts)  do { \
		DUK_D(DUK_DPRINT("parts: %ld %ld %ld %ld %ld %ld %ld %ld", \
		                 (long) (parts)[0], (long) (parts)[1], \
		                 (long) (parts)[2], (long) (parts)[3], \
		                 (long) (parts)[4], (long) (parts)[5], \
		                 (long) (parts)[6], (long) (parts)[7])); \
	} while (0)
#define  DUK__DPRINT_DPARTS(dparts)  do { \
		DUK_D(DUK_DPRINT("dparts: %lf %lf %lf %lf %lf %lf %lf %lf", \
		                 (double) (dparts)[0], (double) (dparts)[1], \
		                 (double) (dparts)[2], (double) (dparts)[3], \
		                 (double) (dparts)[4], (double) (dparts)[5], \
		                 (double) (dparts)[6], (double) (dparts)[7])); \
	} while (0)

/* Equivalent year for DST calculations outside [1970,2038[ range, see
 * E5 Section 15.9.1.8.  Equivalent year has the same leap-year-ness and
 * starts with the same weekday on Jan 1.
 * https://bugzilla.mozilla.org/show_bug.cgi?id=351066
 */
#define DUK__YEAR(x) ((duk_uint8_t) ((x) - 1970))
DUK_LOCAL duk_uint8_t duk__date_equivyear[14] = {
#if 1
	/* This is based on V8 EquivalentYear() algorithm (see src/genequivyear.py):
	 * http://code.google.com/p/v8/source/browse/trunk/src/date.h#146
	 */

	/* non-leap year: sunday, monday, ... */
	DUK__YEAR(2023), DUK__YEAR(2035), DUK__YEAR(2019), DUK__YEAR(2031),
	DUK__YEAR(2015), DUK__YEAR(2027), DUK__YEAR(2011),

	/* leap year: sunday, monday, ... */
	DUK__YEAR(2012), DUK__YEAR(2024), DUK__YEAR(2008), DUK__YEAR(2020),
	DUK__YEAR(2032), DUK__YEAR(2016), DUK__YEAR(2028)
#endif

#if 0
	/* This is based on Rhino EquivalentYear() algorithm:
	 * https://github.com/mozilla/rhino/blob/f99cc11d616f0cdda2c42bde72b3484df6182947/src/org/mozilla/javascript/NativeDate.java
	 */

	/* non-leap year: sunday, monday, ... */
	DUK__YEAR(1978), DUK__YEAR(1973), DUK__YEAR(1985), DUK__YEAR(1986),
	DUK__YEAR(1981), DUK__YEAR(1971), DUK__YEAR(1977),

	/* leap year: sunday, monday, ... */
	DUK__YEAR(1984), DUK__YEAR(1996), DUK__YEAR(1980), DUK__YEAR(1992),
	DUK__YEAR(1976), DUK__YEAR(1988), DUK__YEAR(1972)
#endif
};
#undef DUK__YEAR

/*
 *  ISO 8601 subset parser.
 */

/* Parser part count. */
#define DUK__NUM_ISO8601_PARSER_PARTS  9

/* Parser part indices. */
#define DUK__PI_YEAR         0
#define DUK__PI_MONTH        1
#define DUK__PI_DAY          2
#define DUK__PI_HOUR         3
#define DUK__PI_MINUTE       4
#define DUK__PI_SECOND       5
#define DUK__PI_MILLISECOND  6
#define DUK__PI_TZHOUR       7
#define DUK__PI_TZMINUTE     8

/* Parser part masks. */
#define DUK__PM_YEAR         (1 << DUK__PI_YEAR)
#define DUK__PM_MONTH        (1 << DUK__PI_MONTH)
#define DUK__PM_DAY          (1 << DUK__PI_DAY)
#define DUK__PM_HOUR         (1 << DUK__PI_HOUR)
#define DUK__PM_MINUTE       (1 << DUK__PI_MINUTE)
#define DUK__PM_SECOND       (1 << DUK__PI_SECOND)
#define DUK__PM_MILLISECOND  (1 << DUK__PI_MILLISECOND)
#define DUK__PM_TZHOUR       (1 << DUK__PI_TZHOUR)
#define DUK__PM_TZMINUTE     (1 << DUK__PI_TZMINUTE)

/* Parser separator indices. */
#define DUK__SI_PLUS         0
#define DUK__SI_MINUS        1
#define DUK__SI_T            2
#define DUK__SI_SPACE        3
#define DUK__SI_COLON        4
#define DUK__SI_PERIOD       5
#define DUK__SI_Z            6
#define DUK__SI_NUL          7

/* Parser separator masks. */
#define DUK__SM_PLUS         (1 << DUK__SI_PLUS)
#define DUK__SM_MINUS        (1 << DUK__SI_MINUS)
#define DUK__SM_T            (1 << DUK__SI_T)
#define DUK__SM_SPACE        (1 << DUK__SI_SPACE)
#define DUK__SM_COLON        (1 << DUK__SI_COLON)
#define DUK__SM_PERIOD       (1 << DUK__SI_PERIOD)
#define DUK__SM_Z            (1 << DUK__SI_Z)
#define DUK__SM_NUL          (1 << DUK__SI_NUL)

/* Rule control flags. */
#define DUK__CF_NEG          (1 << 0)  /* continue matching, set neg_tzoffset flag */
#define DUK__CF_ACCEPT       (1 << 1)  /* accept string */
#define DUK__CF_ACCEPT_NUL   (1 << 2)  /* accept string if next char is NUL (otherwise reject) */

#define DUK__PACK_RULE(partmask,sepmask,nextpart,flags)  \
	((duk_uint32_t) (partmask) + \
	 (((duk_uint32_t) (sepmask)) << 9) + \
	 (((duk_uint32_t) (nextpart)) << 17) + \
	 (((duk_uint32_t) (flags)) << 21))

#define DUK__UNPACK_RULE(rule,var_nextidx,var_flags)  do { \
		(var_nextidx) = (duk_small_uint_t) (((rule) >> 17) & 0x0f); \
		(var_flags) = (duk_small_uint_t) ((rule) >> 21); \
	} while (0)

#define DUK__RULE_MASK_PART_SEP  0x1ffffUL

/* Matching separator index is used in the control table */
DUK_LOCAL const duk_uint8_t duk__parse_iso8601_seps[] = {
	DUK_ASC_PLUS /*0*/, DUK_ASC_MINUS /*1*/, DUK_ASC_UC_T /*2*/, DUK_ASC_SPACE /*3*/,
	DUK_ASC_COLON /*4*/, DUK_ASC_PERIOD /*5*/, DUK_ASC_UC_Z /*6*/, DUK_ASC_NUL /*7*/
};

/* Rule table: first matching rule is used to determine what to do next. */
DUK_LOCAL const duk_uint32_t duk__parse_iso8601_control[] = {
	DUK__PACK_RULE(DUK__PM_YEAR, DUK__SM_MINUS, DUK__PI_MONTH, 0),
	DUK__PACK_RULE(DUK__PM_MONTH, DUK__SM_MINUS, DUK__PI_DAY, 0),
	DUK__PACK_RULE(DUK__PM_YEAR | DUK__PM_MONTH | DUK__PM_DAY, DUK__SM_T | DUK__SM_SPACE, DUK__PI_HOUR, 0),
	DUK__PACK_RULE(DUK__PM_HOUR, DUK__SM_COLON, DUK__PI_MINUTE, 0),
	DUK__PACK_RULE(DUK__PM_MINUTE, DUK__SM_COLON, DUK__PI_SECOND, 0),
	DUK__PACK_RULE(DUK__PM_SECOND, DUK__SM_PERIOD, DUK__PI_MILLISECOND, 0),
	DUK__PACK_RULE(DUK__PM_TZHOUR, DUK__SM_COLON, DUK__PI_TZMINUTE, 0),
	DUK__PACK_RULE(DUK__PM_YEAR | DUK__PM_MONTH | DUK__PM_DAY | DUK__PM_HOUR /*Note1*/ | DUK__PM_MINUTE | DUK__PM_SECOND | DUK__PM_MILLISECOND, DUK__SM_PLUS, DUK__PI_TZHOUR, 0),
	DUK__PACK_RULE(DUK__PM_YEAR | DUK__PM_MONTH | DUK__PM_DAY | DUK__PM_HOUR /*Note1*/ | DUK__PM_MINUTE | DUK__PM_SECOND | DUK__PM_MILLISECOND, DUK__SM_MINUS, DUK__PI_TZHOUR, DUK__CF_NEG),
	DUK__PACK_RULE(DUK__PM_YEAR | DUK__PM_MONTH | DUK__PM_DAY | DUK__PM_HOUR /*Note1*/ | DUK__PM_MINUTE | DUK__PM_SECOND | DUK__PM_MILLISECOND, DUK__SM_Z, 0, DUK__CF_ACCEPT_NUL),
	DUK__PACK_RULE(DUK__PM_YEAR | DUK__PM_MONTH | DUK__PM_DAY | DUK__PM_HOUR /*Note1*/ | DUK__PM_MINUTE | DUK__PM_SECOND | DUK__PM_MILLISECOND | DUK__PM_TZHOUR /*Note2*/ | DUK__PM_TZMINUTE, DUK__SM_NUL, 0, DUK__CF_ACCEPT)

	/* Note1: the specification doesn't require matching a time form with
	 *        just hours ("HH"), but we accept it here, e.g. "2012-01-02T12Z".
	 *
	 * Note2: the specification doesn't require matching a timezone offset
	 *        with just hours ("HH"), but accept it here, e.g. "2012-01-02T03:04:05+02"
	 */
};

DUK_LOCAL duk_bool_t duk__parse_string_iso8601_subset(duk_context *ctx, const char *str) {
	duk_int_t parts[DUK__NUM_ISO8601_PARSER_PARTS];
	duk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];
	duk_double_t d;
	const duk_uint8_t *p;
	duk_small_uint_t part_idx = 0;
	duk_int_t accum = 0;
	duk_small_uint_t ndigits = 0;
	duk_bool_t neg_year = 0;
	duk_bool_t neg_tzoffset = 0;
	duk_uint_fast8_t ch;
	duk_small_uint_t i;

	/* During parsing, month and day are one-based; set defaults here. */
	DUK_MEMZERO(parts, sizeof(parts));
	DUK_ASSERT(parts[DUK_DATE_IDX_YEAR] == 0);  /* don't care value, year is mandatory */
	parts[DUK_DATE_IDX_MONTH] = 1;
	parts[DUK_DATE_IDX_DAY] = 1;

	/* Special handling for year sign. */
	p = (const duk_uint8_t *) str;
	ch = p[0];
	if (ch == DUK_ASC_PLUS) {
		p++;
	} else if (ch == DUK_ASC_MINUS) {
		neg_year = 1;
		p++;
	}

	for (;;) {
		ch = *p++;
		DUK_DDD(DUK_DDDPRINT("parsing, part_idx=%ld, char=%ld ('%c')",
		                     (long) part_idx, (long) ch,
		                     (int) ((ch >= 0x20 && ch <= 0x7e) ? ch : DUK_ASC_QUESTION)));

		if (ch >= DUK_ASC_0 && ch <= DUK_ASC_9) {
			if (ndigits >= 9) {
				DUK_DDD(DUK_DDDPRINT("too many digits -> reject"));
				goto reject;
			}
			if (part_idx == DUK__PI_MILLISECOND /*msec*/ && ndigits >= 3) {
				/* ignore millisecond fractions after 3 */
			} else {
				accum = accum * 10 + ((duk_int_t) ch) - ((duk_int_t) DUK_ASC_0) + 0x00;
				ndigits++;
			}
		} else {
			duk_uint_fast32_t match_val;
			duk_small_int_t sep_idx;

			if (ndigits <= 0) {
				goto reject;
			}
			if (part_idx == DUK__PI_MILLISECOND) {
				/* complete the millisecond field */
				while (ndigits < 3) {
					accum *= 10;
					ndigits++;
				}
			}
			parts[part_idx] = accum;
			DUK_DDD(DUK_DDDPRINT("wrote part %ld -> value %ld", (long) part_idx, (long) accum));

			accum = 0;
			ndigits = 0;

			for (i = 0; i < (duk_small_uint_t) (sizeof(duk__parse_iso8601_seps) / sizeof(duk_uint8_t)); i++) {
				if (duk__parse_iso8601_seps[i] == ch) {
					break;
				}
			}
			if (i == (duk_small_uint_t) (sizeof(duk__parse_iso8601_seps) / sizeof(duk_uint8_t))) {
				DUK_DDD(DUK_DDDPRINT("separator character doesn't match -> reject"));
				goto reject;
			}

			sep_idx = i;
			match_val = (1UL << part_idx) + (1UL << (sep_idx + 9));  /* match against rule part/sep bits */

			for (i = 0; i < (duk_small_uint_t) (sizeof(duk__parse_iso8601_control) / sizeof(duk_uint32_t)); i++) {
				duk_uint_fast32_t rule = duk__parse_iso8601_control[i];
				duk_small_uint_t nextpart;
				duk_small_uint_t cflags;

				DUK_DDD(DUK_DDDPRINT("part_idx=%ld, sep_idx=%ld, match_val=0x%08lx, considering rule=0x%08lx",
				                     (long) part_idx, (long) sep_idx,
				                     (unsigned long) match_val, (unsigned long) rule));

				if ((rule & match_val) != match_val) {
					continue;
				}

				DUK__UNPACK_RULE(rule, nextpart, cflags);

				DUK_DDD(DUK_DDDPRINT("rule match -> part_idx=%ld, sep_idx=%ld, match_val=0x%08lx, "
				                     "rule=0x%08lx -> nextpart=%ld, cflags=0x%02lx",
				                     (long) part_idx, (long) sep_idx,
				                     (unsigned long) match_val, (unsigned long) rule,
				                     (long) nextpart, (unsigned long) cflags));

				if (cflags & DUK__CF_NEG) {
					neg_tzoffset = 1;
				}

				if (cflags & DUK__CF_ACCEPT) {
					goto accept;
				}

				if (cflags & DUK__CF_ACCEPT_NUL) {
					DUK_ASSERT(*(p - 1) != (char) 0);
					if (*p == DUK_ASC_NUL) {
						goto accept;
					}
					goto reject;
				}

				part_idx = nextpart;
				break;
			}  /* rule match */

			if (i == (duk_small_uint_t) (sizeof(duk__parse_iso8601_control) / sizeof(duk_uint32_t))) {
				DUK_DDD(DUK_DDDPRINT("no rule matches -> reject"));
				goto reject;
			}

			if (ch == 0) {
				/* This shouldn't be necessary, but check just in case
				 * to avoid any chance of overruns.
				 */
				DUK_DDD(DUK_DDDPRINT("NUL after rule matching (should not happen) -> reject"));
				goto reject;
			}
		}  /* if-digit-else-ctrl */
	}  /* char loop */

	/* We should never exit the loop above, but if we do, reject
	 * by falling through.
	 */
	DUK_DDD(DUK_DDDPRINT("fell out of char loop without explicit accept/reject -> reject"));

 reject:
	DUK_DDD(DUK_DDDPRINT("reject"));
	return 0;

 accept:
	DUK_DDD(DUK_DDDPRINT("accept"));

	/* Apply timezone offset to get the main parts in UTC */
	if (neg_year) {
		parts[DUK__PI_YEAR] = -parts[DUK__PI_YEAR];
	}
	if (neg_tzoffset) {
		parts[DUK__PI_HOUR] += parts[DUK__PI_TZHOUR];
		parts[DUK__PI_MINUTE] += parts[DUK__PI_TZMINUTE];
	} else {
		parts[DUK__PI_HOUR] -= parts[DUK__PI_TZHOUR];
		parts[DUK__PI_MINUTE] -= parts[DUK__PI_TZMINUTE];
	}
	parts[DUK__PI_MONTH] -= 1;  /* zero-based month */
	parts[DUK__PI_DAY] -= 1;  /* zero-based day */

	/* Use double parts, they tolerate unnormalized time.
	 *
	 * Note: DUK_DATE_IDX_WEEKDAY is initialized with a bogus value (DUK__PI_TZHOUR)
	 * on purpose.  It won't be actually used by duk_bi_date_get_timeval_from_dparts(),
	 * but will make the value initialized just in case, and avoid any
	 * potential for Valgrind issues.
	 */
	for (i = 0; i < DUK_DATE_IDX_NUM_PARTS; i++) {
		DUK_DDD(DUK_DDDPRINT("part[%ld] = %ld", (long) i, (long) parts[i]));
		dparts[i] = parts[i];
	}

	d = duk_bi_date_get_timeval_from_dparts(dparts, 0 /*flags*/);
	duk_push_number(ctx, d);
	return 1;
}

/*
 *  Date/time parsing helper.
 *
 *  Parse a datetime string into a time value.  We must first try to parse
 *  the input according to the standard format in E5.1 Section 15.9.1.15.
 *  If that fails, we can try to parse using custom parsing, which can
 *  either be platform neutral (custom code) or platform specific (using
 *  existing platform API calls).
 *
 *  Note in particular that we must parse whatever toString(), toUTCString(),
 *  and toISOString() can produce; see E5.1 Section 15.9.4.2.
 *
 *  Returns 1 to allow tailcalling.
 *
 *  There is much room for improvement here with respect to supporting
 *  alternative datetime formats.  For instance, V8 parses '2012-01-01' as
 *  UTC and '2012/01/01' as local time.
 */

DUK_LOCAL duk_ret_t duk__parse_string(duk_context *ctx, const char *str) {
	/* XXX: there is a small risk here: because the ISO 8601 parser is
	 * very loose, it may end up parsing some datetime values which
	 * would be better parsed with a platform specific parser.
	 */

	DUK_ASSERT(str != NULL);
	DUK_DDD(DUK_DDDPRINT("parse datetime from string '%s'", (const char *) str));

	if (duk__parse_string_iso8601_subset(ctx, str) != 0) {
		return 1;
	}

#if defined(DUK_USE_DATE_PARSE_STRING)
	/* Contract, either:
	 * - Push value on stack and return 1
	 * - Don't push anything on stack and return 0
	 */

	if (DUK_USE_DATE_PARSE_STRING(ctx, str) != 0) {
		return 1;
	}
#else
	/* No platform-specific parsing, this is not an error. */
#endif

	duk_push_nan(ctx);
	return 1;
}

/*
 *  Calendar helpers
 *
 *  Some helpers are used for getters and can operate on normalized values
 *  which can be represented with 32-bit signed integers.  Other helpers are
 *  needed by setters and operate on un-normalized double values, must watch
 *  out for non-finite numbers etc.
 */

DUK_LOCAL duk_uint8_t duk__days_in_month[12] = {
	(duk_uint8_t) 31, (duk_uint8_t) 28, (duk_uint8_t) 31, (duk_uint8_t) 30,
	(duk_uint8_t) 31, (duk_uint8_t) 30, (duk_uint8_t) 31, (duk_uint8_t) 31,
	(duk_uint8_t) 30, (duk_uint8_t) 31, (duk_uint8_t) 30, (duk_uint8_t) 31
};

/* Maximum iteration count for computing UTC-to-local time offset when
 * creating an Ecmascript time value from local parts.
 */
#define DUK__LOCAL_TZOFFSET_MAXITER   4

/* Because 'day since epoch' can be negative and is used to compute weekday
 * using a modulo operation, add this multiple of 7 to avoid negative values
 * when year is below 1970 epoch.  Ecmascript time values are restricted to
 * +/- 100 million days from epoch, so this adder fits nicely into 32 bits.
 * Round to a multiple of 7 (= floor(100000000 / 7) * 7) and add margin.
 */
#define DUK__WEEKDAY_MOD_ADDER  (20000000 * 7)  /* 0x08583b00 */

DUK_INTERNAL duk_bool_t duk_bi_date_is_leap_year(duk_int_t year) {
	if ((year % 4) != 0) {
		return 0;
	}
	if ((year % 100) != 0) {
		return 1;
	}
	if ((year % 400) != 0) {
		return 0;
	}
	return 1;
}

DUK_INTERNAL duk_bool_t duk_bi_date_timeval_in_valid_range(duk_double_t x) {
	return (x >= -DUK_DATE_MSEC_100M_DAYS && x <= DUK_DATE_MSEC_100M_DAYS);
}

DUK_INTERNAL duk_bool_t duk_bi_date_timeval_in_leeway_range(duk_double_t x) {
	return (x >= -DUK_DATE_MSEC_100M_DAYS_LEEWAY && x <= DUK_DATE_MSEC_100M_DAYS_LEEWAY);
}

DUK_INTERNAL duk_bool_t duk_bi_date_year_in_valid_range(duk_double_t x) {
	return (x >= DUK_DATE_MIN_ECMA_YEAR && x <= DUK_DATE_MAX_ECMA_YEAR);
}

DUK_LOCAL duk_double_t duk__timeclip(duk_double_t x) {
	if (!DUK_ISFINITE(x)) {
		return DUK_DOUBLE_NAN;
	}

	if (!duk_bi_date_timeval_in_valid_range(x)) {
		return DUK_DOUBLE_NAN;
	}

	x = duk_js_tointeger_number(x);

	/* Here we'd have the option to normalize -0 to +0. */
	return x;
}

/* Integer division which floors also negative values correctly. */
DUK_LOCAL duk_int_t duk__div_floor(duk_int_t a, duk_int_t b) {
	DUK_ASSERT(b > 0);
	if (a >= 0) {
		return a / b;
	} else {
		/* e.g. a = -4, b = 5  -->  -4 - 5 + 1 / 5  -->  -8 / 5  -->  -1
		 *      a = -5, b = 5  -->  -5 - 5 + 1 / 5  -->  -9 / 5  -->  -1
		 *      a = -6, b = 5  -->  -6 - 5 + 1 / 5  -->  -10 / 5  -->  -2
		 */
		return (a - b + 1) / b;
	}
}

/* Compute day number of the first day of a given year. */
DUK_LOCAL duk_int_t duk__day_from_year(duk_int_t year) {
	/* Note: in integer arithmetic, (x / 4) is same as floor(x / 4) for non-negative
	 * values, but is incorrect for negative ones.
	 */
	return 365 * (year - 1970)
	       + duk__div_floor(year - 1969, 4)
	       - duk__div_floor(year - 1901, 100)
	       + duk__div_floor(year - 1601, 400);
}

/* Given a day number, determine year and day-within-year. */
DUK_LOCAL duk_int_t duk__year_from_day(duk_int_t day, duk_small_int_t *out_day_within_year) {
	duk_int_t year;
	duk_int_t diff_days;

	/* estimate year upwards (towards positive infinity), then back down;
	 * two iterations should be enough
	 */

	if (day >= 0) {
		year = 1970 + day / 365;
	} else {
		year = 1970 + day / 366;
	}

	for (;;) {
		diff_days = duk__day_from_year(year) - day;
		DUK_DDD(DUK_DDDPRINT("year=%ld day=%ld, diff_days=%ld", (long) year, (long) day, (long) diff_days));
		if (diff_days <= 0) {
			DUK_ASSERT(-diff_days < 366);  /* fits into duk_small_int_t */
			*out_day_within_year = -diff_days;
			DUK_DDD(DUK_DDDPRINT("--> year=%ld, day-within-year=%ld",
			                     (long) year, (long) *out_day_within_year));
			DUK_ASSERT(*out_day_within_year >= 0);
			DUK_ASSERT(*out_day_within_year < (duk_bi_date_is_leap_year(year) ? 366 : 365));
			return year;
		}

		/* Note: this is very tricky; we must never 'overshoot' the
		 * correction downwards.
		 */
		year -= 1 + (diff_days - 1) / 366;  /* conservative */
	}
}

/* Given a (year, month, day-within-month) triple, compute day number.
 * The input triple is un-normalized and may contain non-finite values.
 */
DUK_LOCAL duk_double_t duk__make_day(duk_double_t year, duk_double_t month, duk_double_t day) {
	duk_int_t day_num;
	duk_bool_t is_leap;
	duk_small_int_t i, n;

	/* Assume that year, month, day are all coerced to whole numbers.
	 * They may also be NaN or infinity, in which case this function
	 * must return NaN or infinity to ensure time value becomes NaN.
	 * If 'day' is NaN, the final return will end up returning a NaN,
	 * so it doesn't need to be checked here.
	 */

	if (!DUK_ISFINITE(year) || !DUK_ISFINITE(month)) {
		return DUK_DOUBLE_NAN;
	}

	year += DUK_FLOOR(month / 12.0);

	month = DUK_FMOD(month, 12.0);
	if (month < 0.0) {
		/* handle negative values */
		month += 12.0;
	}

	/* The algorithm in E5.1 Section 15.9.1.12 normalizes month, but
	 * does not normalize the day-of-month (nor check whether or not
	 * it is finite) because it's not necessary for finding the day
	 * number which matches the (year,month) pair.
	 *
	 * We assume that duk__day_from_year() is exact here.
	 *
	 * Without an explicit infinity / NaN check in the beginning,
	 * day_num would be a bogus integer here.
	 *
	 * It's possible for 'year' to be out of integer range here.
	 * If so, we need to return NaN without integer overflow.
	 * This fixes test-bug-setyear-overflow.js.
	 */

	if (!duk_bi_date_year_in_valid_range(year)) {
		DUK_DD(DUK_DDPRINT("year not in ecmascript valid range, avoid integer overflow: %lf", (double) year));
		return DUK_DOUBLE_NAN;
	}
	day_num = duk__day_from_year((duk_int_t) year);
	is_leap = duk_bi_date_is_leap_year((duk_int_t) year);

	n = (duk_small_int_t) month;
	for (i = 0; i < n; i++) {
		day_num += duk__days_in_month[i];
		if (i == 1 && is_leap) {
			day_num++;
		}
	}

	/* If 'day' is NaN, returns NaN. */
	return (duk_double_t) day_num + day;
}

/* Split time value into parts.  The time value is assumed to be an internal
 * one, i.e. finite, no fractions.  Possible local time adjustment has already
 * been applied when reading the time value.
 */
DUK_INTERNAL void duk_bi_date_timeval_to_parts(duk_double_t d, duk_int_t *parts, duk_double_t *dparts, duk_small_uint_t flags) {
	duk_double_t d1, d2;
	duk_int_t t1, t2;
	duk_int_t day_since_epoch;
	duk_int_t year;  /* does not fit into 16 bits */
	duk_small_int_t day_in_year;
	duk_small_int_t month;
	duk_small_int_t day;
	duk_small_int_t dim;
	duk_int_t jan1_since_epoch;
	duk_small_int_t jan1_weekday;
	duk_int_t equiv_year;
	duk_small_uint_t i;
	duk_bool_t is_leap;
	duk_small_int_t arridx;

	DUK_ASSERT(DUK_ISFINITE(d));    /* caller checks */
	DUK_ASSERT(DUK_FLOOR(d) == d);  /* no fractions in internal time */

	/* The timevalue must be in valid Ecmascript range, but since a local
	 * time offset can be applied, we need to allow a +/- 24h leeway to
	 * the value.  In other words, although the UTC time is within the
	 * Ecmascript range, the local part values can be just outside of it.
	 */
	DUK_UNREF(duk_bi_date_timeval_in_leeway_range);
	DUK_ASSERT(duk_bi_date_timeval_in_leeway_range(d));

	/* these computations are guaranteed to be exact for the valid
	 * E5 time value range, assuming milliseconds without fractions.
	 */
	d1 = (duk_double_t) DUK_FMOD(d, (double) DUK_DATE_MSEC_DAY);
	if (d1 < 0.0) {
		/* deal with negative values */
		d1 += (duk_double_t) DUK_DATE_MSEC_DAY;
	}
	d2 = DUK_FLOOR((double) (d / (duk_double_t) DUK_DATE_MSEC_DAY));
	DUK_ASSERT(d2 * ((duk_double_t) DUK_DATE_MSEC_DAY) + d1 == d);
	/* now expected to fit into a 32-bit integer */
	t1 = (duk_int_t) d1;
	t2 = (duk_int_t) d2;
	day_since_epoch = t2;
	DUK_ASSERT((duk_double_t) t1 == d1);
	DUK_ASSERT((duk_double_t) t2 == d2);

	/* t1 = milliseconds within day (fits 32 bit)
	 * t2 = day number from epoch (fits 32 bit, may be negative)
	 */

	parts[DUK_DATE_IDX_MILLISECOND] = t1 % 1000; t1 /= 1000;
	parts[DUK_DATE_IDX_SECOND] = t1 % 60; t1 /= 60;
	parts[DUK_DATE_IDX_MINUTE] = t1 % 60; t1 /= 60;
	parts[DUK_DATE_IDX_HOUR] = t1;
	DUK_ASSERT(parts[DUK_DATE_IDX_MILLISECOND] >= 0 && parts[DUK_DATE_IDX_MILLISECOND] <= 999);
	DUK_ASSERT(parts[DUK_DATE_IDX_SECOND] >= 0 && parts[DUK_DATE_IDX_SECOND] <= 59);
	DUK_ASSERT(parts[DUK_DATE_IDX_MINUTE] >= 0 && parts[DUK_DATE_IDX_MINUTE] <= 59);
	DUK_ASSERT(parts[DUK_DATE_IDX_HOUR] >= 0 && parts[DUK_DATE_IDX_HOUR] <= 23);

	DUK_DDD(DUK_DDDPRINT("d=%lf, d1=%lf, d2=%lf, t1=%ld, t2=%ld, parts: hour=%ld min=%ld sec=%ld msec=%ld",
	                     (double) d, (double) d1, (double) d2, (long) t1, (long) t2,
	                     (long) parts[DUK_DATE_IDX_HOUR],
	                     (long) parts[DUK_DATE_IDX_MINUTE],
	                     (long) parts[DUK_DATE_IDX_SECOND],
	                     (long) parts[DUK_DATE_IDX_MILLISECOND]));

	/* This assert depends on the input parts representing time inside
	 * the Ecmascript range.
	 */
	DUK_ASSERT(t2 + DUK__WEEKDAY_MOD_ADDER >= 0);
	parts[DUK_DATE_IDX_WEEKDAY] = (t2 + 4 + DUK__WEEKDAY_MOD_ADDER) % 7;  /* E5.1 Section 15.9.1.6 */
	DUK_ASSERT(parts[DUK_DATE_IDX_WEEKDAY] >= 0 && parts[DUK_DATE_IDX_WEEKDAY] <= 6);

	year = duk__year_from_day(t2, &day_in_year);
	day = day_in_year;
	is_leap = duk_bi_date_is_leap_year(year);
	for (month = 0; month < 12; month++) {
		dim = duk__days_in_month[month];
		if (month == 1 && is_leap) {
			dim++;
		}
		DUK_DDD(DUK_DDDPRINT("month=%ld, dim=%ld, day=%ld",
		                     (long) month, (long) dim, (long) day));
		if (day < dim) {
			break;
		}
		day -= dim;
	}
	DUK_DDD(DUK_DDDPRINT("final month=%ld", (long) month));
	DUK_ASSERT(month >= 0 && month <= 11);
	DUK_ASSERT(day >= 0 && day <= 31);

	/* Equivalent year mapping, used to avoid DST trouble when platform
	 * may fail to provide reasonable DST answers for dates outside the
	 * ordinary range (e.g. 1970-2038).  An equivalent year has the same
	 * leap-year-ness as the original year and begins on the same weekday
	 * (Jan 1).
	 *
	 * The year 2038 is avoided because there seem to be problems with it
	 * on some platforms.  The year 1970 is also avoided as there were
	 * practical problems with it; an equivalent year is used for it too,
	 * which breaks some DST computations for 1970 right now, see e.g.
	 * test-bi-date-tzoffset-brute-fi.js.
	 */
	if ((flags & DUK_DATE_FLAG_EQUIVYEAR) && (year < 1971 || year > 2037)) {
		DUK_ASSERT(is_leap == 0 || is_leap == 1);

		jan1_since_epoch = day_since_epoch - day_in_year;  /* day number for Jan 1 since epoch */
		DUK_ASSERT(jan1_since_epoch + DUK__WEEKDAY_MOD_ADDER >= 0);
		jan1_weekday = (jan1_since_epoch + 4 + DUK__WEEKDAY_MOD_ADDER) % 7;  /* E5.1 Section 15.9.1.6 */
		DUK_ASSERT(jan1_weekday >= 0 && jan1_weekday <= 6);
		arridx = jan1_weekday;
		if (is_leap) {
			arridx += 7;
		}
		DUK_ASSERT(arridx >= 0 && arridx < (duk_small_int_t) (sizeof(duk__date_equivyear) / sizeof(duk_uint8_t)));

		equiv_year = (duk_int_t) duk__date_equivyear[arridx] + 1970;
		year = equiv_year;
		DUK_DDD(DUK_DDDPRINT("equiv year mapping, year=%ld, day_in_year=%ld, day_since_epoch=%ld, "
		                     "jan1_since_epoch=%ld, jan1_weekday=%ld -> equiv year %ld",
		                     (long) year, (long) day_in_year, (long) day_since_epoch,
		                     (long) jan1_since_epoch, (long) jan1_weekday, (long) equiv_year));
	}

	parts[DUK_DATE_IDX_YEAR] = year;
	parts[DUK_DATE_IDX_MONTH] = month;
	parts[DUK_DATE_IDX_DAY] = day;

	if (flags & DUK_DATE_FLAG_ONEBASED) {
		parts[DUK_DATE_IDX_MONTH]++;  /* zero-based -> one-based */
		parts[DUK_DATE_IDX_DAY]++;    /* -""- */
	}

	if (dparts != NULL) {
		for (i = 0; i < DUK_DATE_IDX_NUM_PARTS; i++) {
			dparts[i] = (duk_double_t) parts[i];
		}
	}
}

/* Compute time value from (double) parts.  The parts can be either UTC
 * or local time; if local, they need to be (conceptually) converted into
 * UTC time.  The parts may represent valid or invalid time, and may be
 * wildly out of range (but may cancel each other and still come out in
 * the valid Date range).
 */
DUK_INTERNAL duk_double_t duk_bi_date_get_timeval_from_dparts(duk_double_t *dparts, duk_small_uint_t flags) {
#if defined(DUK_USE_PARANOID_DATE_COMPUTATION)
	/* See comments below on MakeTime why these are volatile. */
	volatile duk_double_t tmp_time;
	volatile duk_double_t tmp_day;
	volatile duk_double_t d;
#else
	duk_double_t tmp_time;
	duk_double_t tmp_day;
	duk_double_t d;
#endif
	duk_small_uint_t i;
	duk_int_t tzoff, tzoffprev1, tzoffprev2;

	/* Expects 'this' at top of stack on entry. */

	/* Coerce all finite parts with ToInteger().  ToInteger() must not
	 * be called for NaN/Infinity because it will convert e.g. NaN to
	 * zero.  If ToInteger() has already been called, this has no side
	 * effects and is idempotent.
	 *
	 * Don't read dparts[DUK_DATE_IDX_WEEKDAY]; it will cause Valgrind
	 * issues if the value is uninitialized.
	 */
	for (i = 0; i <= DUK_DATE_IDX_MILLISECOND; i++) {
		/* SCANBUILD: scan-build complains here about assigned value
		 * being garbage or undefined.  This is correct but operating
		 * on undefined values has no ill effect and is ignored by the
		 * caller in the case where this happens.
		 */
		d = dparts[i];
		if (DUK_ISFINITE(d)) {
			dparts[i] = duk_js_tointeger_number(d);
		}
	}

	/* Use explicit steps in computation to try to ensure that
	 * computation happens with intermediate results coerced to
	 * double values (instead of using something more accurate).
	 * E.g. E5.1 Section 15.9.1.11 requires use of IEEE 754
	 * rules (= Ecmascript '+' and '*' operators).
	 *
	 * Without 'volatile' even this approach fails on some platform
	 * and compiler combinations.  For instance, gcc 4.8.1 on Ubuntu
	 * 64-bit, with -m32 and without -std=c99, test-bi-date-canceling.js
	 * would fail because of some optimizations when computing tmp_time
	 * (MakeTime below).  Adding 'volatile' to tmp_time solved this
	 * particular problem (annoyingly, also adding debug prints or
	 * running the executable under valgrind hides it).
	 */

	/* MakeTime */
	tmp_time = 0.0;
	tmp_time += dparts[DUK_DATE_IDX_HOUR] * ((duk_double_t) DUK_DATE_MSEC_HOUR);
	tmp_time += dparts[DUK_DATE_IDX_MINUTE] * ((duk_double_t) DUK_DATE_MSEC_MINUTE);
	tmp_time += dparts[DUK_DATE_IDX_SECOND] * ((duk_double_t) DUK_DATE_MSEC_SECOND);
	tmp_time += dparts[DUK_DATE_IDX_MILLISECOND];

	/* MakeDay */
	tmp_day = duk__make_day(dparts[DUK_DATE_IDX_YEAR], dparts[DUK_DATE_IDX_MONTH], dparts[DUK_DATE_IDX_DAY]);

	/* MakeDate */
	d = tmp_day * ((duk_double_t) DUK_DATE_MSEC_DAY) + tmp_time;

	DUK_DDD(DUK_DDDPRINT("time=%lf day=%lf --> timeval=%lf",
	                     (double) tmp_time, (double) tmp_day, (double) d));

	/* Optional UTC conversion. */
	if (flags & DUK_DATE_FLAG_LOCALTIME) {
		/* DUK_USE_DATE_GET_LOCAL_TZOFFSET() needs to be called with a
		 * time value computed from UTC parts.  At this point we only
		 * have 'd' which is a time value computed from local parts, so
		 * it is off by the UTC-to-local time offset which we don't know
		 * yet.  The current solution for computing the UTC-to-local
		 * time offset is to iterate a few times and detect a fixed
		 * point or a two-cycle loop (or a sanity iteration limit),
		 * see test-bi-date-local-parts.js and test-bi-date-tzoffset-basic-fi.js.
		 *
		 * E5.1 Section 15.9.1.9:
		 * UTC(t) = t - LocalTZA - DaylightSavingTA(t - LocalTZA)
		 *
		 * For NaN/inf, DUK_USE_DATE_GET_LOCAL_TZOFFSET() returns 0.
		 */

#if 0
		/* Old solution: don't iterate, incorrect */
		tzoff = DUK_USE_DATE_GET_LOCAL_TZOFFSET(d);
		DUK_DDD(DUK_DDDPRINT("tzoffset w/o iteration, tzoff=%ld", (long) tzoff));
		d -= tzoff * 1000L;
		DUK_UNREF(tzoffprev1);
		DUK_UNREF(tzoffprev2);
#endif

		/* Iteration solution */
		tzoff = 0;
		tzoffprev1 = 999999999L;  /* invalid value which never matches */
		for (i = 0; i < DUK__LOCAL_TZOFFSET_MAXITER; i++) {
			tzoffprev2 = tzoffprev1;
			tzoffprev1 = tzoff;
			tzoff = DUK_USE_DATE_GET_LOCAL_TZOFFSET(d - tzoff * 1000L);
			DUK_DDD(DUK_DDDPRINT("tzoffset iteration, i=%d, tzoff=%ld, tzoffprev1=%ld tzoffprev2=%ld",
			                     (int) i, (long) tzoff, (long) tzoffprev1, (long) tzoffprev2));
			if (tzoff == tzoffprev1) {
				DUK_DDD(DUK_DDDPRINT("tzoffset iteration finished, i=%d, tzoff=%ld, tzoffprev1=%ld, tzoffprev2=%ld",
				                     (int) i, (long) tzoff, (long) tzoffprev1, (long) tzoffprev2));
				break;
			} else if (tzoff == tzoffprev2) {
				/* Two value cycle, see e.g. test-bi-date-tzoffset-basic-fi.js.
				 * In these cases, favor a higher tzoffset to get a consistent
				 * result which is independent of iteration count.  Not sure if
				 * this is a generically correct solution.
				 */
				DUK_DDD(DUK_DDDPRINT("tzoffset iteration two-value cycle, i=%d, tzoff=%ld, tzoffprev1=%ld, tzoffprev2=%ld",
				                     (int) i, (long) tzoff, (long) tzoffprev1, (long) tzoffprev2));
				if (tzoffprev1 > tzoff) {
					tzoff = tzoffprev1;
				}
				break;
			}
		}
		DUK_DDD(DUK_DDDPRINT("tzoffset iteration, tzoff=%ld", (long) tzoff));
		d -= tzoff * 1000L;
	}

	/* TimeClip(), which also handles Infinity -> NaN conversion */
	d = duk__timeclip(d);

	return d;
}

/*
 *  API oriented helpers
 */

/* Push 'this' binding, check that it is a Date object; then push the
 * internal time value.  At the end, stack is: [ ... this timeval ].
 * Returns the time value.  Local time adjustment is done if requested.
 */
DUK_LOCAL duk_double_t duk__push_this_get_timeval_tzoffset(duk_context *ctx, duk_small_uint_t flags, duk_int_t *out_tzoffset) {
	duk_hthread *thr = (duk_hthread *) ctx;
	duk_hobject *h;
	duk_double_t d;
	duk_int_t tzoffset = 0;

	duk_push_this(ctx);
	h = duk_get_hobject(ctx, -1);  /* XXX: getter with class check, useful in built-ins */
	if (h == NULL || DUK_HOBJECT_GET_CLASS_NUMBER(h) != DUK_HOBJECT_CLASS_DATE) {
		DUK_ERROR(thr, DUK_ERR_TYPE_ERROR, "expected Date");
	}

	duk_get_prop_stridx(ctx, -1, DUK_STRIDX_INT_VALUE);
	d = duk_to_number(ctx, -1);
	duk_pop(ctx);

	if (DUK_ISNAN(d)) {
		if (flags & DUK_DATE_FLAG_NAN_TO_ZERO) {
			d = 0.0;
		}
		if (flags & DUK_DATE_FLAG_NAN_TO_RANGE_ERROR) {
			DUK_ERROR(thr, DUK_ERR_RANGE_ERROR, "Invalid Date");
		}
	}
	/* if no NaN handling flag, may still be NaN here, but not Inf */
	DUK_ASSERT(!DUK_ISINF(d));

	if (flags & DUK_DATE_FLAG_LOCALTIME) {
		/* Note: DST adjustment is determined using UTC time.
		 * If 'd' is NaN, tzoffset will be 0.
		 */
		tzoffset = DUK_USE_DATE_GET_LOCAL_TZOFFSET(d);  /* seconds */
		d += tzoffset * 1000L;
	}
	if (out_tzoffset) {
		*out_tzoffset = tzoffset;
	}

	/* [ ... this ] */
	return d;
}

DUK_LOCAL duk_double_t duk__push_this_get_timeval(duk_context *ctx, duk_small_uint_t flags) {
	return duk__push_this_get_timeval_tzoffset(ctx, flags, NULL);
}

/* Set timeval to 'this' from dparts, push the new time value onto the
 * value stack and return 1 (caller can then tailcall us).  Expects
 * the value stack to contain 'this' on the stack top.
 */
DUK_LOCAL duk_ret_t duk__set_this_timeval_from_dparts(duk_context *ctx, duk_double_t *dparts, duk_small_uint_t flags) {
	duk_double_t d;

	/* [ ... this ] */

	d = duk_bi_date_get_timeval_from_dparts(dparts, flags);
	duk_push_number(ctx, d);  /* -> [ ... this timeval_new ] */
	duk_dup_top(ctx);         /* -> [ ... this timeval_new timeval_new ] */
	duk_put_prop_stridx(ctx, -3, DUK_STRIDX_INT_VALUE);

	/* stack top: new time value, return 1 to allow tailcalls */
	return 1;
}

/* 'out_buf' must be at least DUK_BI_DATE_ISO8601_BUFSIZE long. */
DUK_LOCAL void duk__format_parts_iso8601(duk_int_t *parts, duk_int_t tzoffset, duk_small_uint_t flags, duk_uint8_t *out_buf) {
	char yearstr[8];   /* "-123456\0" */
	char tzstr[8];     /* "+11:22\0" */
	char sep = (flags & DUK_DATE_FLAG_SEP_T) ? DUK_ASC_UC_T : DUK_ASC_SPACE;

	DUK_ASSERT(parts[DUK_DATE_IDX_MONTH] >= 1 && parts[DUK_DATE_IDX_MONTH] <= 12);
	DUK_ASSERT(parts[DUK_DATE_IDX_DAY] >= 1 && parts[DUK_DATE_IDX_DAY] <= 31);
	DUK_ASSERT(parts[DUK_DATE_IDX_YEAR] >= -999999 && parts[DUK_DATE_IDX_YEAR] <= 999999);

	/* Note: %06d for positive value, %07d for negative value to include
	 * sign and 6 digits.
	 */
	DUK_SNPRINTF(yearstr,
	             sizeof(yearstr),
	             (parts[DUK_DATE_IDX_YEAR] >= 0 && parts[DUK_DATE_IDX_YEAR] <= 9999) ? "%04ld" :
	                    ((parts[DUK_DATE_IDX_YEAR] >= 0) ? "+%06ld" : "%07ld"),
	             (long) parts[DUK_DATE_IDX_YEAR]);
	yearstr[sizeof(yearstr) - 1] = (char) 0;

	if (flags & DUK_DATE_FLAG_LOCALTIME) {
		/* tzoffset seconds are dropped; 16 bits suffice for
		 * time offset in minutes
		 */
		if (tzoffset >= 0) {
			duk_small_int_t tmp = tzoffset / 60;
			DUK_SNPRINTF(tzstr, sizeof(tzstr), "+%02d:%02d", (int) (tmp / 60), (int) (tmp % 60));
		} else {
			duk_small_int_t tmp = -tzoffset / 60;
			DUK_SNPRINTF(tzstr, sizeof(tzstr), "-%02d:%02d", (int) (tmp / 60), (int) (tmp % 60));
		}
		tzstr[sizeof(tzstr) - 1] = (char) 0;
	} else {
		tzstr[0] = DUK_ASC_UC_Z;
		tzstr[1] = (char) 0;
	}

	/* Unlike year, the other parts fit into 16 bits so %d format
	 * is portable.
	 */
	if ((flags & DUK_DATE_FLAG_TOSTRING_DATE) && (flags & DUK_DATE_FLAG_TOSTRING_TIME)) {
		DUK_SPRINTF((char *) out_buf, "%s-%02d-%02d%c%02d:%02d:%02d.%03d%s",
		            (const char *) yearstr, (int) parts[DUK_DATE_IDX_MONTH], (int) parts[DUK_DATE_IDX_DAY], (int) sep,
		            (int) parts[DUK_DATE_IDX_HOUR], (int) parts[DUK_DATE_IDX_MINUTE],
		            (int) parts[DUK_DATE_IDX_SECOND], (int) parts[DUK_DATE_IDX_MILLISECOND], (const char *) tzstr);
	} else if (flags & DUK_DATE_FLAG_TOSTRING_DATE) {
		DUK_SPRINTF((char *) out_buf, "%s-%02d-%02d",
		            (const char *) yearstr, (int) parts[DUK_DATE_IDX_MONTH], (int) parts[DUK_DATE_IDX_DAY]);
	} else {
		DUK_ASSERT(flags & DUK_DATE_FLAG_TOSTRING_TIME);
		DUK_SPRINTF((char *) out_buf, "%02d:%02d:%02d.%03d%s",
		            (int) parts[DUK_DATE_IDX_HOUR], (int) parts[DUK_DATE_IDX_MINUTE],
		            (int) parts[DUK_DATE_IDX_SECOND], (int) parts[DUK_DATE_IDX_MILLISECOND],
		            (const char *) tzstr);
	}
}

/* Helper for string conversion calls: check 'this' binding, get the
 * internal time value, and format date and/or time in a few formats.
 * Return value allows tail calls.
 */
DUK_LOCAL duk_ret_t duk__to_string_helper(duk_context *ctx, duk_small_uint_t flags) {
	duk_double_t d;
	duk_int_t parts[DUK_DATE_IDX_NUM_PARTS];
	duk_int_t tzoffset;  /* seconds, doesn't fit into 16 bits */
	duk_bool_t rc;
	duk_uint8_t buf[DUK_BI_DATE_ISO8601_BUFSIZE];

	DUK_UNREF(rc);  /* unreferenced with some options */

	d = duk__push_this_get_timeval_tzoffset(ctx, flags, &tzoffset);
	if (DUK_ISNAN(d)) {
		duk_push_hstring_stridx(ctx, DUK_STRIDX_INVALID_DATE);
		return 1;
	}
	DUK_ASSERT(DUK_ISFINITE(d));

	/* formatters always get one-based month/day-of-month */
	duk_bi_date_timeval_to_parts(d, parts, NULL, DUK_DATE_FLAG_ONEBASED);
	DUK_ASSERT(parts[DUK_DATE_IDX_MONTH] >= 1 && parts[DUK_DATE_IDX_MONTH] <= 12);
	DUK_ASSERT(parts[DUK_DATE_IDX_DAY] >= 1 && parts[DUK_DATE_IDX_DAY] <= 31);

	if (flags & DUK_DATE_FLAG_TOSTRING_LOCALE) {
		/* try locale specific formatter; if it refuses to format the
		 * string, fall back to an ISO 8601 formatted value in local
		 * time.
		 */
#if defined(DUK_USE_DATE_FORMAT_STRING)
		/* Contract, either:
		 * - Push string to value stack and return 1
		 * - Don't push anything and return 0
		 */

		rc = DUK_USE_DATE_FORMAT_STRING(ctx, parts, tzoffset, flags);
		if (rc != 0) {
			return 1;
		}
#else
		/* No locale specific formatter; this is OK, we fall back
		 * to ISO 8601.
		 */
#endif
	}

	/* Different calling convention than above used because the helper
	 * is shared.
	 */
	duk__format_parts_iso8601(parts, tzoffset, flags, buf);
	duk_push_string(ctx, (const char *) buf);
	return 1;
}

/* Helper for component getter calls: check 'this' binding, get the
 * internal time value, split it into parts (either as UTC time or
 * local time), push a specified component as a return value to the
 * value stack and return 1 (caller can then tailcall us).
 */
DUK_LOCAL duk_ret_t duk__get_part_helper(duk_context *ctx, duk_small_uint_t flags_and_idx) {
	duk_double_t d;
	duk_int_t parts[DUK_DATE_IDX_NUM_PARTS];
	duk_small_uint_t idx_part = (duk_small_uint_t) (flags_and_idx >> DUK_DATE_FLAG_VALUE_SHIFT);  /* unpack args */

	DUK_ASSERT_DISABLE(idx_part >= 0);  /* unsigned */
	DUK_ASSERT(idx_part < DUK_DATE_IDX_NUM_PARTS);

	d = duk__push_this_get_timeval(ctx, flags_and_idx);
	if (DUK_ISNAN(d)) {
		duk_push_nan(ctx);
		return 1;
	}
	DUK_ASSERT(DUK_ISFINITE(d));

	duk_bi_date_timeval_to_parts(d, parts, NULL, flags_and_idx);  /* no need to mask idx portion */

	/* Setter APIs detect special year numbers (0...99) and apply a +1900
	 * only in certain cases.  The legacy getYear() getter applies -1900
	 * unconditionally.
	 */
	duk_push_int(ctx, (flags_and_idx & DUK_DATE_FLAG_SUB1900) ? parts[idx_part] - 1900 : parts[idx_part]);
	return 1;
}

/* Helper for component setter calls: check 'this' binding, get the
 * internal time value, split it into parts (either as UTC time or
 * local time), modify one or more components as specified, recompute
 * the time value, set it as the internal value.  Finally, push the
 * new time value as a return value to the value stack and return 1
 * (caller can then tailcall us).
 */
DUK_LOCAL duk_ret_t duk__set_part_helper(duk_context *ctx, duk_small_uint_t flags_and_maxnargs) {
	duk_double_t d;
	duk_int_t parts[DUK_DATE_IDX_NUM_PARTS];
	duk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];
	duk_idx_t nargs;
	duk_small_uint_t maxnargs = (duk_small_uint_t) (flags_and_maxnargs >> DUK_DATE_FLAG_VALUE_SHIFT);  /* unpack args */
	duk_small_uint_t idx_first, idx;
	duk_small_uint_t i;

	nargs = duk_get_top(ctx);
	d = duk__push_this_get_timeval(ctx, flags_and_maxnargs);
	DUK_ASSERT(DUK_ISFINITE(d) || DUK_ISNAN(d));

	if (DUK_ISFINITE(d)) {
		duk_bi_date_timeval_to_parts(d, parts, dparts, flags_and_maxnargs);
	} else {
		/* NaN timevalue: we need to coerce the arguments, but
		 * the resulting internal timestamp needs to remain NaN.
		 * This works but is not pretty: parts and dparts will
		 * be partially uninitialized, but we only write to them.
		 */
	}

	/*
	 *  Determining which datetime components to overwrite based on
	 *  stack arguments is a bit complicated, but important to factor
	 *  out from setters themselves for compactness.
	 *
	 *  If DUK_DATE_FLAG_TIMESETTER, maxnargs indicates setter type:
	 *
	 *   1 -> millisecond
	 *   2 -> second, [millisecond]
	 *   3 -> minute, [second], [millisecond]
	 *   4 -> hour, [minute], [second], [millisecond]
	 *
	 *  Else:
	 *
	 *   1 -> date
	 *   2 -> month, [date]
	 *   3 -> year, [month], [date]
	 *
	 *  By comparing nargs and maxnargs (and flags) we know which
	 *  components to override.  We rely on part index ordering.
	 */

	if (flags_and_maxnargs & DUK_DATE_FLAG_TIMESETTER) {
		DUK_ASSERT(maxnargs >= 1 && maxnargs <= 4);
		idx_first = DUK_DATE_IDX_MILLISECOND - (maxnargs - 1);
	} else {
		DUK_ASSERT(maxnargs >= 1 && maxnargs <= 3);
		idx_first = DUK_DATE_IDX_DAY - (maxnargs - 1);
	}
	DUK_ASSERT_DISABLE(idx_first >= 0);  /* unsigned */
	DUK_ASSERT(idx_first < DUK_DATE_IDX_NUM_PARTS);

	for (i = 0; i < maxnargs; i++) {
		if ((duk_idx_t) i >= nargs) {
			/* no argument given -> leave components untouched */
			break;
		}
		idx = idx_first + i;
		DUK_ASSERT_DISABLE(idx >= 0);  /* unsigned */
		DUK_ASSERT(idx < DUK_DATE_IDX_NUM_PARTS);

		if (idx == DUK_DATE_IDX_YEAR && (flags_and_maxnargs & DUK_DATE_FLAG_YEAR_FIXUP)) {
			duk__twodigit_year_fixup(ctx, (duk_idx_t) i);
		}

		dparts[idx] = duk_to_number(ctx, i);

		if (idx == DUK_DATE_IDX_DAY) {
			/* Day-of-month is one-based in the API, but zero-based
			 * internally, so fix here.  Note that month is zero-based
			 * both in the API and internally.
			 */
			/* SCANBUILD: complains about use of uninitialized values.
			 * The complaint is correct, but operating in undefined
			 * values here is intentional in some cases and the caller
			 * ignores the results.
			 */
			dparts[idx] -= 1.0;
		}
	}

	/* Leaves new timevalue on stack top and returns 1, which is correct
	 * for part setters.
	 */
	if (DUK_ISFINITE(d)) {
		return duk__set_this_timeval_from_dparts(ctx, dparts, flags_and_maxnargs);
	} else {
		/* Internal timevalue is already NaN, so don't touch it. */
		duk_push_nan(ctx);
		return 1;
	}
}

/* Apply ToNumber() to specified index; if ToInteger(val) in [0,99], add
 * 1900 and replace value at idx_val.
 */
DUK_LOCAL void duk__twodigit_year_fixup(duk_context *ctx, duk_idx_t idx_val) {
	duk_double_t d;

	/* XXX: idx_val would fit into 16 bits, but using duk_small_uint_t
	 * might not generate better code due to casting.
	 */

	/* E5 Sections 15.9.3.1, B.2.4, B.2.5 */
	duk_to_number(ctx, idx_val);
	if (duk_is_nan(ctx, idx_val)) {
		return;
	}
	duk_dup(ctx, idx_val);
	duk_to_int(ctx, -1);
	d = duk_get_number(ctx, -1);  /* get as double to handle huge numbers correctly */
	if (d >= 0.0 && d <= 99.0) {
		d += 1900.0;
		duk_push_number(ctx, d);
		duk_replace(ctx, idx_val);
	}
	duk_pop(ctx);
}

/* Set datetime parts from stack arguments, defaulting any missing values.
 * Day-of-week is not set; it is not required when setting the time value.
 */
DUK_LOCAL void duk__set_parts_from_args(duk_context *ctx, duk_double_t *dparts, duk_idx_t nargs) {
	duk_double_t d;
	duk_small_uint_t i;
	duk_small_uint_t idx;

	/* Causes a ToNumber() coercion, but doesn't break coercion order since
	 * year is coerced first anyway.
	 */
	duk__twodigit_year_fixup(ctx, 0);

	/* There are at most 7 args, but we use 8 here so that also
	 * DUK_DATE_IDX_WEEKDAY gets initialized (to zero) to avoid the potential
	 * for any Valgrind gripes later.
	 */
	for (i = 0; i < 8; i++) {
		/* Note: rely on index ordering */
		idx = DUK_DATE_IDX_YEAR + i;
		if ((duk_idx_t) i < nargs) {
			d = duk_to_number(ctx, (duk_idx_t) i);
			if (idx == DUK_DATE_IDX_DAY) {
				/* Convert day from one-based to zero-based (internal).  This may
				 * cause the day part to be negative, which is OK.
				 */
				d -= 1.0;
			}
		} else {
			/* All components default to 0 except day-of-month which defaults
			 * to 1.  However, because our internal day-of-month is zero-based,
			 * it also defaults to zero here.
			 */
			d = 0.0;
		}
		dparts[idx] = d;
	}

	DUK_DDD(DUK_DDDPRINT("parts from args -> %lf %lf %lf %lf %lf %lf %lf %lf",
	                     (double) dparts[0], (double) dparts[1],
	                     (double) dparts[2], (double) dparts[3],
	                     (double) dparts[4], (double) dparts[5],
	                     (double) dparts[6], (double) dparts[7]));
}

/*
 *  Helper to format a time value into caller buffer, used by logging.
 *  'out_buf' must be at least DUK_BI_DATE_ISO8601_BUFSIZE long.
 */

DUK_INTERNAL void duk_bi_date_format_timeval(duk_double_t timeval, duk_uint8_t *out_buf) {
	duk_int_t parts[DUK_DATE_IDX_NUM_PARTS];

	duk_bi_date_timeval_to_parts(timeval,
	                             parts,
	                             NULL,
	                             DUK_DATE_FLAG_ONEBASED);

	duk__format_parts_iso8601(parts,
	                          0 /*tzoffset*/,
	                          DUK_DATE_FLAG_TOSTRING_DATE |
	                          DUK_DATE_FLAG_TOSTRING_TIME |
	                          DUK_DATE_FLAG_SEP_T /*flags*/,
	                          out_buf);
}

/*
 *  Indirect magic value lookup for Date methods.
 *
 *  Date methods don't put their control flags into the function magic value
 *  because they wouldn't fit into a LIGHTFUNC's magic field.  Instead, the
 *  magic value is set to an index pointing to the array of control flags
 *  below.
 *
 *  This must be kept in strict sync with genbuiltins.py!
 */

static duk_uint16_t duk__date_magics[] = {
	/* 0: toString */
	DUK_DATE_FLAG_TOSTRING_DATE + DUK_DATE_FLAG_TOSTRING_TIME + DUK_DATE_FLAG_LOCALTIME,

	/* 1: toDateString */
	DUK_DATE_FLAG_TOSTRING_DATE + DUK_DATE_FLAG_LOCALTIME,

	/* 2: toTimeString */
	DUK_DATE_FLAG_TOSTRING_TIME + DUK_DATE_FLAG_LOCALTIME,

	/* 3: toLocaleString */
	DUK_DATE_FLAG_TOSTRING_DATE + DUK_DATE_FLAG_TOSTRING_TIME + DUK_DATE_FLAG_TOSTRING_LOCALE + DUK_DATE_FLAG_LOCALTIME,

	/* 4: toLocaleDateString */
	DUK_DATE_FLAG_TOSTRING_DATE + DUK_DATE_FLAG_TOSTRING_LOCALE + DUK_DATE_FLAG_LOCALTIME,

	/* 5: toLocaleTimeString */
	DUK_DATE_FLAG_TOSTRING_TIME + DUK_DATE_FLAG_TOSTRING_LOCALE + DUK_DATE_FLAG_LOCALTIME,

	/* 6: toUTCString */
	DUK_DATE_FLAG_TOSTRING_DATE + DUK_DATE_FLAG_TOSTRING_TIME,

	/* 7: toISOString */
	DUK_DATE_FLAG_TOSTRING_DATE + DUK_DATE_FLAG_TOSTRING_TIME + DUK_DATE_FLAG_NAN_TO_RANGE_ERROR + DUK_DATE_FLAG_SEP_T,

	/* 8: getFullYear */
	DUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_YEAR << DUK_DATE_FLAG_VALUE_SHIFT),

	/* 9: getUTCFullYear */
	0 + (DUK_DATE_IDX_YEAR << DUK_DATE_FLAG_VALUE_SHIFT),

	/* 10: getMonth */
	DUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_MONTH << DUK_DATE_FLAG_VALUE_SHIFT),

	/* 11: getUTCMonth */
	0 + (DUK_DATE_IDX_MONTH << DUK_DATE_FLAG_VALUE_SHIFT),

	/* 12: getDate */
	DUK_DATE_FLAG_ONEBASED + DUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_DAY << DUK_DATE_FLAG_VALUE_SHIFT),

	/* 13: getUTCDate */
	DUK_DATE_FLAG_ONEBASED + (DUK_DATE_IDX_DAY << DUK_DATE_FLAG_VALUE_SHIFT),

	/* 14: getDay */
	DUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_WEEKDAY << DUK_DATE_FLAG_VALUE_SHIFT),

	/* 15: getUTCDay */
	0 + (DUK_DATE_IDX_WEEKDAY << DUK_DATE_FLAG_VALUE_SHIFT),

	/* 16: getHours */
	DUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_HOUR << DUK_DATE_FLAG_VALUE_SHIFT),

	/* 17: getUTCHours */
	0 + (DUK_DATE_IDX_HOUR << DUK_DATE_FLAG_VALUE_SHIFT),

	/* 18: getMinutes */
	DUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_MINUTE << DUK_DATE_FLAG_VALUE_SHIFT),

	/* 19: getUTCMinutes */
	0 + (DUK_DATE_IDX_MINUTE << DUK_DATE_FLAG_VALUE_SHIFT),

	/* 20: getSeconds */
	DUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_SECOND << DUK_DATE_FLAG_VALUE_SHIFT),

	/* 21: getUTCSeconds */
	0 + (DUK_DATE_IDX_SECOND << DUK_DATE_FLAG_VALUE_SHIFT),

	/* 22: getMilliseconds */
	DUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_MILLISECOND << DUK_DATE_FLAG_VALUE_SHIFT),

	/* 23: getUTCMilliseconds */
	0 + (DUK_DATE_IDX_MILLISECOND << DUK_DATE_FLAG_VALUE_SHIFT),

	/* 24: setMilliseconds */
	DUK_DATE_FLAG_TIMESETTER + DUK_DATE_FLAG_LOCALTIME + (1 << DUK_DATE_FLAG_VALUE_SHIFT),

	/* 25: setUTCMilliseconds */
	DUK_DATE_FLAG_TIMESETTER + (1 << DUK_DATE_FLAG_VALUE_SHIFT),

	/* 26: setSeconds */
	DUK_DATE_FLAG_TIMESETTER + DUK_DATE_FLAG_LOCALTIME + (2 << DUK_DATE_FLAG_VALUE_SHIFT),

	/* 27: setUTCSeconds */
	DUK_DATE_FLAG_TIMESETTER + (2 << DUK_DATE_FLAG_VALUE_SHIFT),

	/* 28: setMinutes */
	DUK_DATE_FLAG_TIMESETTER + DUK_DATE_FLAG_LOCALTIME + (3 << DUK_DATE_FLAG_VALUE_SHIFT),

	/* 29: setUTCMinutes */
	DUK_DATE_FLAG_TIMESETTER + (3 << DUK_DATE_FLAG_VALUE_SHIFT),

	/* 30: setHours */
	DUK_DATE_FLAG_TIMESETTER + DUK_DATE_FLAG_LOCALTIME + (4 << DUK_DATE_FLAG_VALUE_SHIFT),

	/* 31: setUTCHours */
	DUK_DATE_FLAG_TIMESETTER + (4 << DUK_DATE_FLAG_VALUE_SHIFT),

	/* 32: setDate */
	DUK_DATE_FLAG_LOCALTIME + (1 << DUK_DATE_FLAG_VALUE_SHIFT),

	/* 33: setUTCDate */
	0 + (1 << DUK_DATE_FLAG_VALUE_SHIFT),

	/* 34: setMonth */
	DUK_DATE_FLAG_LOCALTIME + (2 << DUK_DATE_FLAG_VALUE_SHIFT),

	/* 35: setUTCMonth */
	0 + (2 << DUK_DATE_FLAG_VALUE_SHIFT),

	/* 36: setFullYear */
	DUK_DATE_FLAG_NAN_TO_ZERO + DUK_DATE_FLAG_LOCALTIME + (3 << DUK_DATE_FLAG_VALUE_SHIFT),

	/* 37: setUTCFullYear */
	DUK_DATE_FLAG_NAN_TO_ZERO + (3 << DUK_DATE_FLAG_VALUE_SHIFT),

	/* 38: getYear */
	DUK_DATE_FLAG_LOCALTIME + DUK_DATE_FLAG_SUB1900 + (DUK_DATE_IDX_YEAR << DUK_DATE_FLAG_VALUE_SHIFT),

	/* 39: setYear */
	DUK_DATE_FLAG_NAN_TO_ZERO + DUK_DATE_FLAG_YEAR_FIXUP + (3 << DUK_DATE_FLAG_VALUE_SHIFT),
};

DUK_LOCAL duk_small_uint_t duk__date_get_indirect_magic(duk_context *ctx) {
	duk_small_int_t magicidx = (duk_small_uint_t) duk_get_current_magic(ctx);
	DUK_ASSERT(magicidx >= 0 && magicidx < (duk_small_int_t) (sizeof(duk__date_magics) / sizeof(duk_uint16_t)));
	return (duk_small_uint_t) duk__date_magics[magicidx];
}

/*
 *  Constructor calls
 */

DUK_INTERNAL duk_ret_t duk_bi_date_constructor(duk_context *ctx) {
	duk_idx_t nargs = duk_get_top(ctx);
	duk_bool_t is_cons = duk_is_constructor_call(ctx);
	duk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];
	duk_double_t d;

	DUK_DDD(DUK_DDDPRINT("Date constructor, nargs=%ld, is_cons=%ld", (long) nargs, (long) is_cons));

	duk_push_object_helper(ctx,
	                       DUK_HOBJECT_FLAG_EXTENSIBLE |
	                       DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DATE),
	                       DUK_BIDX_DATE_PROTOTYPE);

	/* Unlike most built-ins, the internal [[PrimitiveValue]] of a Date
	 * is mutable.
	 */

	if (nargs == 0 || !is_cons) {
		d = duk__timeclip(DUK_USE_DATE_GET_NOW(ctx));
		duk_push_number(ctx, d);
		duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_W);
		if (!is_cons) {
			/* called as a normal function: return new Date().toString() */
			duk_to_string(ctx, -1);
		}
		return 1;
	} else if (nargs == 1) {
		duk_to_primitive(ctx, 0, DUK_HINT_NONE);
		if (duk_is_string(ctx, 0)) {
			duk__parse_string(ctx, duk_to_string(ctx, 0));
			duk_replace(ctx, 0);  /* may be NaN */
		}
		d = duk__timeclip(duk_to_number(ctx, 0));
		duk_push_number(ctx, d);
		duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_W);
		return 1;
	}

	duk__set_parts_from_args(ctx, dparts, nargs);

	/* Parts are in local time, convert when setting. */

	(void) duk__set_this_timeval_from_dparts(ctx, dparts, DUK_DATE_FLAG_LOCALTIME /*flags*/);  /* -> [ ... this timeval ] */
	duk_pop(ctx);  /* -> [ ... this ] */
	return 1;
}

DUK_INTERNAL duk_ret_t duk_bi_date_constructor_parse(duk_context *ctx) {
	return duk__parse_string(ctx, duk_to_string(ctx, 0));
}

DUK_INTERNAL duk_ret_t duk_bi_date_constructor_utc(duk_context *ctx) {
	duk_idx_t nargs = duk_get_top(ctx);
	duk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];
	duk_double_t d;

	/* Behavior for nargs < 2 is implementation dependent: currently we'll
	 * set a NaN time value (matching V8 behavior) in this case.
	 */

	if (nargs < 2) {
		duk_push_nan(ctx);
	} else {
		duk__set_parts_from_args(ctx, dparts, nargs);
		d = duk_bi_date_get_timeval_from_dparts(dparts, 0 /*flags*/);
		duk_push_number(ctx, d);
	}
	return 1;
}

DUK_INTERNAL duk_ret_t duk_bi_date_constructor_now(duk_context *ctx) {
	duk_double_t d;

	d = DUK_USE_DATE_GET_NOW(ctx);
	DUK_ASSERT(duk__timeclip(d) == d);  /* TimeClip() should never be necessary */
	duk_push_number(ctx, d);
	return 1;
}

/*
 *  String/JSON conversions
 *
 *  Human readable conversions are now basically ISO 8601 with a space
 *  (instead of 'T') as the date/time separator.  This is a good baseline
 *  and is platform independent.
 *
 *  A shared native helper to provide many conversions.  Magic value contains
 *  a set of flags.  The helper provides:
 *
 *    toString()
 *    toDateString()
 *    toTimeString()
 *    toLocaleString()
 *    toLocaleDateString()
 *    toLocaleTimeString()
 *    toUTCString()
 *    toISOString()
 *
 *  Notes:
 *
 *    - Date.prototype.toGMTString() and Date.prototype.toUTCString() are
 *      required to be the same Ecmascript function object (!), so it is
 *      omitted from here.
 *
 *    - Date.prototype.toUTCString(): E5.1 specification does not require a
 *      specific format, but result should be human readable.  The
 *      specification suggests using ISO 8601 format with a space (instead
 *      of 'T') separator if a more human readable format is not available.
 *
 *    - Date.prototype.toISOString(): unlike other conversion functions,
 *      toISOString() requires a RangeError for invalid date values.
 */

DUK_INTERNAL duk_ret_t duk_bi_date_prototype_tostring_shared(duk_context *ctx) {
	duk_small_uint_t flags = duk__date_get_indirect_magic(ctx);
	return duk__to_string_helper(ctx, flags);
}

DUK_INTERNAL duk_ret_t duk_bi_date_prototype_value_of(duk_context *ctx) {
	/* This native function is also used for Date.prototype.getTime()
	 * as their behavior is identical.
	 */

	duk_double_t d = duk__push_this_get_timeval(ctx, 0 /*flags*/);  /* -> [ this ] */
	DUK_ASSERT(DUK_ISFINITE(d) || DUK_ISNAN(d));
	duk_push_number(ctx, d);
	return 1;
}

DUK_INTERNAL duk_ret_t duk_bi_date_prototype_to_json(duk_context *ctx) {
	/* Note: toJSON() is a generic function which works even if 'this'
	 * is not a Date.  The sole argument is ignored.
	 */

	duk_push_this(ctx);
	duk_to_object(ctx, -1);

	duk_dup_top(ctx);
	duk_to_primitive(ctx, -1, DUK_HINT_NUMBER);
	if (duk_is_number(ctx, -1)) {
		duk_double_t d = duk_get_number(ctx, -1);
		if (!DUK_ISFINITE(d)) {
			duk_push_null(ctx);
			return 1;
		}
	}
	duk_pop(ctx);

	duk_get_prop_stridx(ctx, -1, DUK_STRIDX_TO_ISO_STRING);
	duk_dup(ctx, -2);  /* -> [ O toIsoString O ] */
	duk_call_method(ctx, 0);
	return 1;
}

/*
 *  Getters.
 *
 *  Implementing getters is quite easy.  The internal time value is either
 *  NaN, or represents milliseconds (without fractions) from Jan 1, 1970.
 *  The internal time value can be converted to integer parts, and each
 *  part will be normalized and will fit into a 32-bit signed integer.
 *
 *  A shared native helper to provide all getters.  Magic value contains
 *  a set of flags and also packs the date component index argument.  The
 *  helper provides:
 *
 *    getFullYear()
 *    getUTCFullYear()
 *    getMonth()
 *    getUTCMonth()
 *    getDate()
 *    getUTCDate()
 *    getDay()
 *    getUTCDay()
 *    getHours()
 *    getUTCHours()
 *    getMinutes()
 *    getUTCMinutes()
 *    getSeconds()
 *    getUTCSeconds()
 *    getMilliseconds()
 *    getUTCMilliseconds()
 *    getYear()
 *
 *  Notes:
 *
 *    - Date.prototype.getDate(): 'date' means day-of-month, and is
 *      zero-based in internal calculations but public API expects it to
 *      be one-based.
 *
 *    - Date.prototype.getTime() and Date.prototype.valueOf() have identical
 *      behavior.  They have separate function objects, but share the same C
 *      function (duk_bi_date_prototype_value_of).
 */

DUK_INTERNAL duk_ret_t duk_bi_date_prototype_get_shared(duk_context *ctx) {
	duk_small_uint_t flags_and_idx = duk__date_get_indirect_magic(ctx);
	return duk__get_part_helper(ctx, flags_and_idx);
}

DUK_INTERNAL duk_ret_t duk_bi_date_prototype_get_timezone_offset(duk_context *ctx) {
	/*
	 *  Return (t - LocalTime(t)) in minutes:
	 *
	 *    t - LocalTime(t) = t - (t + LocalTZA + DaylightSavingTA(t))
	 *                     = -(LocalTZA + DaylightSavingTA(t))
	 *
	 *  where DaylightSavingTA() is checked for time 't'.
	 *
	 *  Note that the sign of the result is opposite to common usage,
	 *  e.g. for EE(S)T which normally is +2h or +3h from UTC, this
	 *  function returns -120 or -180.
	 *
	 */

	duk_double_t d;
	duk_int_t tzoffset;

	/* Note: DST adjustment is determined using UTC time. */
	d = duk__push_this_get_timeval(ctx, 0 /*flags*/);
	DUK_ASSERT(DUK_ISFINITE(d) || DUK_ISNAN(d));
	if (DUK_ISNAN(d)) {
		duk_push_nan(ctx);
	} else {
		DUK_ASSERT(DUK_ISFINITE(d));
		tzoffset = DUK_USE_DATE_GET_LOCAL_TZOFFSET(d);
		duk_push_int(ctx, -tzoffset / 60);
	}
	return 1;
}

/*
 *  Setters.
 *
 *  Setters are a bit more complicated than getters.  Component setters
 *  break down the current time value into its (normalized) component
 *  parts, replace one or more components with -unnormalized- new values,
 *  and the components are then converted back into a time value.  As an
 *  example of using unnormalized values:
 *
 *    var d = new Date(1234567890);
 *
 *  is equivalent to:
 *
 *    var d = new Date(0);
 *    d.setUTCMilliseconds(1234567890);
 *
 *  A shared native helper to provide almost all setters.  Magic value
 *  contains a set of flags and also packs the "maxnargs" argument.  The
 *  helper provides:
 *
 *    setMilliseconds()
 *    setUTCMilliseconds()
 *    setSeconds()
 *    setUTCSeconds()
 *    setMinutes()
 *    setUTCMinutes()
 *    setHours()
 *    setUTCHours()
 *    setDate()
 *    setUTCDate()
 *    setMonth()
 *    setUTCMonth()
 *    setFullYear()
 *    setUTCFullYear()
 *    setYear()
 *
 *  Notes:
 *
 *    - Date.prototype.setYear() (Section B addition): special year check
 *      is omitted.  NaN / Infinity will just flow through and ultimately
 *      result in a NaN internal time value.
 *
 *    - Date.prototype.setYear() does not have optional arguments for
 *      setting month and day-in-month (like setFullYear()), but we indicate
 *      'maxnargs' to be 3 to get the year written to the correct component
 *      index in duk__set_part_helper().  The function has nargs == 1, so only
 *      the year will be set regardless of actual argument count.
 */

DUK_INTERNAL duk_ret_t duk_bi_date_prototype_set_shared(duk_context *ctx) {
	duk_small_uint_t flags_and_maxnargs = duk__date_get_indirect_magic(ctx);
	return duk__set_part_helper(ctx, flags_and_maxnargs);
}

DUK_INTERNAL duk_ret_t duk_bi_date_prototype_set_time(duk_context *ctx) {
	duk_double_t d;

	(void) duk__push_this_get_timeval(ctx, 0 /*flags*/); /* -> [ timeval this ] */
	d = duk__timeclip(duk_to_number(ctx, 0));
	duk_push_number(ctx, d);
	duk_dup_top(ctx);
	duk_put_prop_stridx(ctx, -3, DUK_STRIDX_INT_VALUE); /* -> [ timeval this timeval ] */

	return 1;
}


text:
<?php
//ini_set('display_errors', 'on');
//ini_set('error_reporting', E_ALL);
include_once("../include/inc-fuction.php");

$conn = connectDB_BigHead();
	//ตรวจสอบว่า มีค่า ตัวแปร $_GET['show_province'] เข้ามาหรือไม่  	//แสดงรายชื่อจังหวัด
	if(isset($_GET['levelEmp'])){
		$json_result[] = ['id'=>'6','name'=>'สาย',];
		$json_result[] = ['id'=>'5','name'=>'ซุป',];
		$json_result[] = ['id'=>'4','name'=>'ทีม',];
		$json_result[] = ['id'=>'3','name'=>'หน่วย',];
		$json_result[] = ['id'=>'2','name'=>'พนักงาน',];

			//ใช้ Function json_encode แปลงข้อมูลในตัวแปร $json_result ให้เป็นรูปแบบ Json
			echo json_encode($json_result);
	}
	if ($_COOKIE['tsr_emp_id'] == "000000") {
		$_COOKIE['tsr_emp_id'] = "A00000";
	}
	$EmpID = $_COOKIE['tsr_emp_id'];
	if (!empty($_REQUEST['EmpID'])) {
		$EmpID = $_REQUEST['EmpID'];
	}

	//ตรวจสอบว่า มีค่า ตัวแปร $_GET['province_id'] เข้ามาหรือไม่  //แสดงรายชืออำเภอ
	if(isset($_GET['LvEmp'])){

		$json_result[] = ['id'=>'0','name'=>'ทั้งหมด',];

		switch ($_GET['LvEmp']) {
    case 6:
			$sql_case = "SELECT EmployeeCode,PositionName +' '+ LEFT(SubDepartmentCode,1)+' '+ EmployeeName AS Pos FROM Bighead_Mobile.dbo.EmployeeDetail WHERE PositionCode = 'LineManager' AND ProcessType = 'FA' ORDER BY Pos";

			//echo $sql_case;
			$stmt = sqlsrv_query($conn,$sql_case);
			while ($row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC)) {
				$json_result[] = ['id'=>$row['EmployeeCode'],'name'=>$row['Pos'],];
			}
        break;
    case 5:
		if ($_COOKIE['tsr_emp_permit'] == 1 || $_COOKIE['tsr_emp_permit'] == 2 || ($_COOKIE['tsr_emp_permit'] == 13)) {
			$sql_case = "SELECT EmployeeCode,SupervisorName+' '+ EmployeeName AS Pos
			FROM Bighead_Mobile.dbo.EmployeeDetail WHERE PositionCode = 'Supervisor' AND ProcessType = 'FA' ORDER BY Pos";
		}else {
			$sql_case = "SELECT EmployeeCode,SupervisorName+' '+ EmployeeName AS Pos
			FROM Bighead_Mobile.dbo.EmployeeDetail WHERE PositionCode = 'Supervisor' AND ProcessType = 'FA'
			AND EmployeeCode IN ( SELECT DISTINCT EmployeeCodeLV5 FROM [TSRData_Source].[dbo].[EmployeeDataParent_ALL] WHERE StatusType = 'FA' AND (EmployeeCodeLV2 = '".$EmpID."' OR EmployeeCodeLV3 = '".$EmpID."' OR EmployeeCodeLV4 = '".$EmpID."' OR EmployeeCodeLV5 = '".$EmpID."' OR EmployeeCodeLV6 = '".$EmpID."' OR ParentEmployeeCode = '".$EmpID."') )	ORDER BY Pos";
		}

			//echo $sql_case;
			$stmt = sqlsrv_query($conn,$sql_case);
			while ($row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC)) {
				$json_result[] = ['id'=>$row['EmployeeCode'],'name'=>$row['Pos'],];
			}
        break;
    case 4:
		if ($_COOKIE['tsr_emp_permit'] == 1 || $_COOKIE['tsr_emp_permit'] == 2 || ($_COOKIE['tsr_emp_permit'] == 13)) {
			$sql_case = "SELECT EmployeeCode,TeamName+' '+ EmployeeName AS Pos FROM Bighead_Mobile.dbo.EmployeeDetail WHERE PositionCode = 'SaleLeader' AND ProcessType = 'FA' ORDER BY Pos";
		}else {
			$sql_case = "SELECT EmployeeCode,TeamName+' '+ EmployeeName AS Pos FROM Bighead_Mobile.dbo.EmployeeDetail WHERE PositionCode = 'SaleLeader' AND ProcessType = 'FA'
			AND EmployeeCode IN ( SELECT DISTINCT EmployeeCodeLV4 FROM [TSRData_Source].[dbo].[EmployeeDataParent_ALL] WHERE StatusType = 'FA' AND (EmployeeCodeLV2 = '".$EmpID."' OR EmployeeCodeLV3 = '".$EmpID."' OR EmployeeCodeLV4 = '".$EmpID."' OR EmployeeCodeLV5 = '".$EmpID."' OR EmployeeCodeLV6 = '".$EmpID."' OR ParentEmployeeCode = '".$EmpID."'))
				ORDER BY Pos";
		}

			//echo $sql_case;
			$stmt = sqlsrv_query($conn,$sql_case);
			while ($row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC)) {
				$json_result[] = ['id'=>$row['EmployeeCode'],'name'=>$row['Pos'],];
			}
        break;
		case 3:
		if ($_COOKIE['tsr_emp_permit'] == 1 || $_COOKIE['tsr_emp_permit'] == 2 || ($_COOKIE['tsr_emp_permit'] == 13)) {
			$sql_case = "SELECT EmployeeCode,SubTeamName+' '+ EmployeeName AS Pos FROM Bighead_Mobile.dbo.EmployeeDetail WHERE PositionCode = 'SubTeamLeader' AND ProcessType = 'FA' ORDER BY Pos";
		}else {
			$sql_case = "SELECT EmployeeCode,SubTeamName+' '+ EmployeeName AS Pos FROM Bighead_Mobile.dbo.EmployeeDetail WHERE PositionCode = 'SubTeamLeader' AND ProcessType = 'FA'
			AND EmployeeCode IN ( SELECT DISTINCT EmployeeCodeLV3 FROM [TSRData_Source].[dbo].[EmployeeDataParent_ALL] WHERE StatusType = 'FA' AND (EmployeeCodeLV2 = '".$EmpID."' OR EmployeeCodeLV3 = '".$EmpID."' OR EmployeeCodeLV4 = '".$EmpID."' OR EmployeeCodeLV5 = '".$EmpID."' OR EmployeeCodeLV6 = '".$EmpID."' OR ParentEmployeeCode = '".$EmpID."')) ORDER BY Pos";
		}

			//echo $sql_case;
			$stmt = sqlsrv_query($conn,$sql_case);
			while ($row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC)) {
				$json_result[] = ['id'=>$row['EmployeeCode'],'name'=>$row['Pos'],];
			}
				break;
		default:
		if ($_COOKIE['tsr_emp_permit'] == 1 || $_COOKIE['tsr_emp_permit'] == 2 || ($_COOKIE['tsr_emp_permit'] == 13)) {
			$sql_case = "SELECT EmployeeCode,SaleCode+' '+ EmployeeName AS Pos FROM Bighead_Mobile.dbo.EmployeeDetail WHERE PositionCode = 'SALE' AND ProcessType = 'FA' ORDER BY Pos";
		}else {
			$sql_case = "SELECT EmployeeCode,SaleCode+' '+ EmployeeName AS Pos FROM Bighead_Mobile.dbo.EmployeeDetail WHERE PositionCode = 'SALE' AND ProcessType = 'FA'
			AND EmployeeCode IN ( SELECT DISTINCT EmployeeCodeLV2 FROM [TSRData_Source].[dbo].[EmployeeDataParent_ALL] WHERE StatusType = 'FA' AND (EmployeeCodeLV2 = '".$EmpID."' OR EmployeeCodeLV3 = '".$EmpID."' OR EmployeeCodeLV4 = '".$EmpID."' OR EmployeeCodeLV5 = '".$EmpID."' OR EmployeeCodeLV6 = '".$EmpID."' OR ParentEmployeeCode = '".$EmpID."')) ORDER BY Pos";
		}

			//echo $sql_case;
			$stmt = sqlsrv_query($conn,$sql_case);
			while ($row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC)) {
				$json_result[] = ['id'=>$row['EmployeeCode'],'name'=>$row['Pos'],];
			}
				break;
		}

		echo json_encode($json_result);
	}

sqlsrv_close($conn);

?>

redpajama_set_name: RedPajamaGithub


text:
"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
var events_1 = require("events");
var PluginManager = /** @class */ (function (_super) {
    __extends(PluginManager, _super);
    function PluginManager() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.plugins = [];
        return _this;
    }
    Object.defineProperty(PluginManager.prototype, "Plugins", {
        get: function () {
            return this.plugins;
        },
        enumerable: true,
        configurable: true
    });
    PluginManager.prototype.addPlugin = function (plugin) {
        this.emit('add_plugin');
        this.initialisePlugin(plugin);
    };
    PluginManager.prototype.addPlugins = function (plugins) {
        var _this = this;
        this.emit('add_plugin');
        plugins.forEach(function (plugin) {
            _this.initialisePlugin(plugin);
        });
    };
    PluginManager.prototype.initialisePlugin = function (PluginType) {
        this.plugins.push(new PluginType());
    };
    return PluginManager;
}(events_1.EventEmitter));
exports.PluginManager = PluginManager;
//# sourceMappingURL=PluginManager.js.map


text:
import utils = require('../lib/utils')
import { Request, Response, NextFunction } from 'express'

const security = require('../lib/insecurity')
const challenges = require('../data/datacache').challenges

module.exports = function performRedirect () {
  return ({ query }: Request, res: Response, next: NextFunction) => {
    const toUrl = query.to
    if (security.isRedirectAllowed(toUrl)) {
      utils.solveIf(challenges.redirectCryptoCurrencyChallenge, () => { return toUrl === 'https://explorer.dash.org/address/Xr556RzuwX6hg5EGpkybbv5RanJoZN17kW' || toUrl === 'https://blockchain.info/address/1AbKfgvw9psQ41NbLi8kufDQTezwG8DRZm' || toUrl === 'https://etherscan.io/address/0x0f933ab9fcaaa782d0279c300d73750e1311eae6' })
      utils.solveIf(challenges.redirectChallenge, () => { return isUnintendedRedirect(toUrl as string) })
      res.redirect(toUrl as string)
    } else {
      res.status(406)
      next(new Error('Unrecognized target URL for redirect: ' + toUrl))
    }
  }
}

function isUnintendedRedirect (toUrl: string) {
  let unintended = true
  for (const allowedUrl of security.redirectAllowlist) {
    unintended = unintended && !utils.startsWith(toUrl, allowedUrl)
  }
  return unintended
}


text:
local Blocking_Aliases = {}

local aliases = {}

local function setup(args)
  tempAliases = {}

  tempAliases.block =
    tempAlias("\/[Bb][Ll][Oo][Cc][Kk]"
              ,[[
                local arguments = {}

                Events.raiseEvent("blockEvent", arguments)
              ]])

  tempAliases.unblock =
    tempAlias("\/[Uu][Nn][Bb][Ll][Oo][Cc][Kk]"
              ,[[
                local arguments = {}

                Events.raiseEvent("unblockEvent", arguments)
              ]])
  aliases = tempAliases
end

local function unsetup(args)
  for i,v in pairs(aliases) do
    killAlias(v)
  end
end

local function resetup(args)
  unsetup(args)
  setup(args)
end

Blocking_Aliases =
{
  setup = setup
  ,unsetup = unsetup
  ,resetup = resetup
}

return Blocking_Aliases


text:
<?php
namespace TwbBundle\Form\View\Helper;

use Zend\Form\ElementInterface;
use Zend\View\Helper\AbstractHelper;

class TwbBundleFormStatic extends AbstractHelper
{
    /**
     * @var string
     */
    protected static $staticFormat = '
%s
';

    /**
     * Invoke helper as functor
     *
     * Proxies to {@link render()}.
     *
     * @param  ElementInterface|null $element
     * @return string|TwbBundleFormStatic
     */
    public function __invoke(ElementInterface $element = null)
    {
        if (!$element) {
            return $this;
        }

        return $this->render($element);
    }

    /**
     * @see \Zend\Form\View\Helper\AbstractHelper::render()
     * @param ElementInterface $oElement
     * @return string
     */
    public function render(ElementInterface $oElement)
    {
        return sprintf(static::$staticFormat, $oElement->getValue());
    }
}


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<title>edu.wpi.first.wpilibj.command</title>
<meta name="date" content="2014-07-26">
<link rel="stylesheet" type="text/css" href="../../../../../stylesheet.css" title="Style">

edu.wpi.first.wpilibj.command

Interfaces

AutoSpreadsheetCommand

Classes

AutoSpreadsheet

AutoSpreadsheetCommandGroup

CommandGroupUpdateable


text:
#include "coding/varint_vector.hpp"

/*
#include "coding/writer.hpp"
#include "coding/reader.hpp"

#include "base/assert.hpp"

namespace varint
{

namespace
{
  void VarintEncode(vector<uint8_t> & dst, uint64_t n)
  {
    if (n == 0)
    {
      dst.push_back(0);
    }
    else
    {
      while (n != 0)
      {
        uint8_t b = n & 0x7F;
        n >>= 7;
        b |= (n == 0) ? 0 : 0x80;
        dst.push_back(b);
      }
    }
  }

  uint64_t VarintDecode(Reader * reader, uint64_t & offset)
  {
    uint64_t n = 0;
    int shift = 0;
    while (1)
    {
      uint8_t b = 0;
      reader->Read(offset, &b, 1);
      n |= uint64_t(b & 0x7F) << shift;
      ++offset;
      if ((b & 0x80) == 0)
        break;
      shift += 7;
    }
    return n;
  }
}

VectorBuilder::VectorBuilder(uint64_t numElemPerTableEntry)
  : m_numElemPerTableEntry(numElemPerTableEntry), m_numsCount(0), m_sum(0)
{
}

void VectorBuilder::AddNum(uint64_t num)
{
  if (m_numsCount % m_numElemPerTableEntry == 0)
  {
    TableEntry tableEntry;
    tableEntry.pos = m_serialNums.size();
    tableEntry.sum = m_sum;
    m_selectTable.push_back(tableEntry);
  }
  VarintEncode(m_serialNums, num);
  ++m_numsCount;
  m_sum += num;
}

void VectorBuilder::Finalize(Writer * writer)
{
  vector<uint8_t> header;
  VarintEncode(header, m_numsCount);
  VarintEncode(header, m_numElemPerTableEntry);
  VarintEncode(header, m_selectTable.size());
  VarintEncode(header, m_serialNums.size());

  writer->Write(header.data(), header.size());
  writer->Write(m_selectTable.data(), m_selectTable.size() * sizeof(m_selectTable.front()));
  writer->Write(m_serialNums.data(), m_serialNums.size());
}

void VectorBuilderDelayedLast::AddLast()
{
  if (m_hasLast)
  {
    BaseT::AddNum(m_last);
    m_hasLast = false;
  }
}

void VectorBuilderDelayedLast::AddNum(uint64_t num)
{
  AddLast();

  m_last = num;
  m_hasLast = true;
}

void VectorBuilderDelayedLast::ReplaceLast(uint64_t num)
{
  ASSERT(m_hasLast, ());
  m_last = num;
}

void VectorBuilderDelayedLast::Finalize(Writer * writer)
{
  AddLast();

  BaseT::Finalize(writer);
}

Vector::Vector(Reader * reader)
  : m_reader(reader), m_numsCount(0), m_numElemPerTableEntry(0), m_numTableEntries(0),
    m_serialNumsSize(0), m_selectTableOffset(0), m_serialNumsOffset(0)
{
  uint64_t parseOffset = 0;
  m_numsCount = VarintDecode(m_reader, parseOffset);
  m_numElemPerTableEntry = VarintDecode(m_reader, parseOffset);
  m_numTableEntries = VarintDecode(m_reader, parseOffset);
  m_serialNumsSize = VarintDecode(m_reader, parseOffset);
  m_selectTableOffset = parseOffset;
  m_serialNumsOffset = m_selectTableOffset + sizeof(TableEntry) * m_numTableEntries;
}

void Vector::FindByIndex(uint64_t index, uint32_t & serialPos, uint64_t & sumBefore)
{
  ASSERT_LESS(index, m_numsCount, ());
  uint64_t tableEntryIndex = index / m_numElemPerTableEntry;

  ASSERT_LESS(tableEntryIndex, m_numTableEntries, ());

  uint64_t tableEntryOffset = m_selectTableOffset + tableEntryIndex * sizeof(TableEntry);
  uint64_t indexWithinRange = index % m_numElemPerTableEntry;

  TableEntry tableEntry;
  m_reader->Read(tableEntryOffset, &tableEntry, sizeof(TableEntry));

  uint64_t sum = tableEntry.sum;
  uint64_t numOffset = m_serialNumsOffset + tableEntry.pos;
  for (uint64_t i = 0; i < indexWithinRange; ++i)
  {
    uint64_t num = VarintDecode(m_reader, numOffset);
    sum += num;
  }
  serialPos = numOffset - m_serialNumsOffset;
  sumBefore = sum;
}

void Vector::FindBySum(uint64_t sum, uint32_t & serialPos, uint64_t & sumBefore, uint64_t & countBefore)
{
  // First do binary search over select table to find the biggest
  // sum that is less or equal to our.
  uint64_t l = 0, r = m_numTableEntries;
  uint64_t countBinarySearchCycles = 0;
  while (r - l > 1)
  {
    ++countBinarySearchCycles;

    uint64_t m = (l + r) / 2;
    uint64_t tableEntryOffset = m_selectTableOffset + m * sizeof(TableEntry);

    TableEntry tableEntry;
    m_reader->Read(tableEntryOffset, &tableEntry, sizeof(TableEntry));
    if (sum >= tableEntry.sum)
      l = m;
    else
      r = m;
  }

  uint64_t tableEntryIndex = l;
  countBefore = tableEntryIndex * m_numElemPerTableEntry;

  uint64_t tableEntryOffset = m_selectTableOffset + tableEntryIndex * sizeof(TableEntry);
  TableEntry tableEntry;
  m_reader->Read(tableEntryOffset, &tableEntry, sizeof(TableEntry));

  uint64_t numsSum = tableEntry.sum;
  // At this point nums_sum <= sum.
  uint64_t numOffset = m_serialNumsOffset + tableEntry.pos;
  while (numsSum <= sum && countBefore < m_numsCount)
  {
    uint64_t nextOffset = numOffset;
    uint64_t num = VarintDecode(m_reader, nextOffset);

    if (numsSum + num > sum)
      break;

    numOffset = nextOffset;
    numsSum += num;
    ++countBefore;
  }

  serialPos = numOffset - m_serialNumsOffset;
  sumBefore = numsSum;
}

void Vector::Read(uint32_t & serialPos, uint64_t & num)
{
  ASSERT_LESS(serialPos, m_serialNumsSize, ());

  uint64_t numOffset = m_serialNumsOffset + serialPos;
  num = VarintDecode(m_reader, numOffset);
  serialPos = numOffset - m_serialNumsOffset;
}

}
*/


text:
package hydrograph.ui.engine.ui.converter.impl;

import hydrograph.engine.jaxb.commontypes.TypeBaseComponent;
import hydrograph.engine.jaxb.commontypes.TypeExternalSchema;
import hydrograph.engine.jaxb.commontypes.TypeInputOutSocket;
import hydrograph.engine.jaxb.commontypes.TypeProperties;
import hydrograph.engine.jaxb.commontypes.TypeProperties.Property;
import hydrograph.engine.jaxb.inputtypes.ParquetFile;
import hydrograph.ui.common.util.Constants;
import hydrograph.ui.datastructure.property.GridRow;
import hydrograph.ui.datastructure.property.Schema;
import hydrograph.ui.engine.constants.PropertyNameConstants;
import hydrograph.ui.engine.ui.constants.UIComponentsConstants;
import hydrograph.ui.engine.ui.converter.InputUiConverter;
import hydrograph.ui.engine.ui.helper.ConverterUiHelper;
import hydrograph.ui.graph.model.Container;
import hydrograph.ui.graph.model.components.IFParquet;
import hydrograph.ui.logging.factory.LogFactory;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.slf4j.Logger;

public class InputParquetUiConverter extends InputUiConverter {

	private static final Logger LOGGER = LogFactory.INSTANCE.getLogger(InputParquetUiConverter.class);
	private ParquetFile parquetFile;

	public InputParquetUiConverter(TypeBaseComponent typeBaseComponent, Container container) {
		this.container = container;
		this.typeBaseComponent = typeBaseComponent;
		this.uiComponent = new IFParquet();
		this.propertyMap = new LinkedHashMap<>();
	}

	@Override
	public void prepareUIXML() {
		super.prepareUIXML();
		LOGGER.debug("Fetching Input-Parquet-Properties for {}", componentName);
		parquetFile = (ParquetFile) typeBaseComponent;
		if (parquetFile.getPath() != null)
			propertyMap.put(PropertyNameConstants.PATH.value(), parquetFile.getPath().getUri());

		uiComponent.setType(UIComponentsConstants.FILE_PARQUET.value());
		uiComponent.setCategory(UIComponentsConstants.INPUT_CATEGORY.value());
		container.getComponentNextNameSuffixes().put(name_suffix, 0);

		uiComponent.setProperties(propertyMap);
	}

	@Override
	protected Map<String, String> getRuntimeProperties() {
		LOGGER.debug("Generating Runtime Properties for -{}", componentName);
		TreeMap<String, String> runtimeMap = null;
		TypeProperties typeProperties = ((ParquetFile) typeBaseComponent).getRuntimeProperties();
		if (typeProperties != null) {
			runtimeMap = new TreeMap<>();
			for (Property runtimeProperty : typeProperties.getProperty()) {
				runtimeMap.put(runtimeProperty.getName(), runtimeProperty.getValue());
			}
		}
		return runtimeMap;
	}

	@Override
	protected Object getSchema(TypeInputOutSocket outSocket) {
		LOGGER.debug("Generating UI-Schema data for {}", componentName);
		Schema schema = null;
		List<GridRow> gridRowList = new ArrayList<>();
		ConverterUiHelper converterUiHelper = new ConverterUiHelper(uiComponent);
		if (outSocket.getSchema() != null
				&& outSocket.getSchema().getFieldOrRecordOrIncludeExternalSchema().size() != 0) {
			schema = new Schema();
			for (Object record : outSocket.getSchema().getFieldOrRecordOrIncludeExternalSchema()) {
				if ((TypeExternalSchema.class).isAssignableFrom(record.getClass())) {
					schema.setIsExternal(true);
					if (((TypeExternalSchema) record).getUri() != null){
						schema.setExternalSchemaPath(((TypeExternalSchema) record).getUri());
					}
					gridRowList.addAll(converterUiHelper.loadSchemaFromExternalFile(schema.getExternalSchemaPath(),
							Constants.GENERIC_GRID_ROW));
					schema.setGridRow(gridRowList);
				} else {
					gridRowList.add(converterUiHelper.getSchema(record));
					schema.setGridRow(gridRowList);
					schema.setIsExternal(false);
				}
				saveComponentOutputSchema(outSocket.getId(),gridRowList);
			}
		}
		return schema;

	}
}


text:
package android.support.v4.media.session;

import android.content.Intent;
import android.os.Bundle;
import android.os.ResultReceiver;

// Referenced classes of package android.support.v4.media.session:
//            MediaSessionCompatApi14

public static interface
{

    public abstract void onCommand(String s, Bundle bundle, ResultReceiver resultreceiver);

    public abstract void onFastForward();

    public abstract boolean onMediaButtonEvent(Intent intent);

    public abstract void onPause();

    public abstract void onPlay();

    public abstract void onRewind();

    public abstract void onSeekTo(long l);

    public abstract void onSetRating(Object obj);

    public abstract void onSkipToNext();

    public abstract void onSkipToPrevious();

    public abstract void onStop();
}


text:
package com.example.picasso;

import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.widget.RemoteViews;
import com.squareup.picasso.Picasso;
import java.util.Random;

public class SampleWidgetProvider extends AppWidgetProvider {

  @Override
  public void onUpdate(final Context context, AppWidgetManager appWidgetManager,
      int[] appWidgetIds) {
    RemoteViews updateViews = new RemoteViews(context.getPackageName(), R.layout.sample_widget);
    // Load image for all appWidgetIds.
    Picasso picasso = Picasso.with();
    picasso.load(Data.URLS[new Random().nextInt(Data.URLS.length)]) //
        .placeholder(R.drawable.placeholder) //
        .error(R.drawable.error) //
        .transform(new GrayscaleTransformation(picasso)) //
        .into(updateViews, R.id.image, appWidgetIds);
  }
}


text:
// Copyright (c) 2016 Framefield. All rights reserved.
// Released under the MIT license. (see LICENSE.txt)

using System;
using System.Collections.Generic;
using SharpDX;

namespace Framefield.Core.OperatorPartTraits
{

    public interface ITraverseModifier
    {
        IEnumerable<OperatorPart> GetRelevantConnections();
    }

}


text:
@interface APRequestEditGroupTitle () {
 @public
  APGroupOutPeer *groupPeer_;
  jlong rid_;
  NSString *title_;
}

@end

J2OBJC_FIELD_SETTER(APRequestEditGroupTitle, groupPeer_, APGroupOutPeer *)
J2OBJC_FIELD_SETTER(APRequestEditGroupTitle, title_, NSString *)

@implementation APRequestEditGroupTitle

+ (APRequestEditGroupTitle *)fromBytesWithByteArray:(IOSByteArray *)data {
  return APRequestEditGroupTitle_fromBytesWithByteArray_(data);
}

- (instancetype)initWithAPGroupOutPeer:(APGroupOutPeer *)groupPeer
                              withLong:(jlong)rid
                          withNSString:(NSString *)title {
  APRequestEditGroupTitle_initWithAPGroupOutPeer_withLong_withNSString_(self, groupPeer, rid, title);
  return self;
}

- (instancetype)init {
  APRequestEditGroupTitle_init(self);
  return self;
}

- (APGroupOutPeer *)getGroupPeer {
  return self->groupPeer_;
}

- (jlong)getRid {
  return self->rid_;
}

- (NSString *)getTitle {
  return self->title_;
}

- (void)parseWithBSBserValues:(BSBserValues *)values {
  self->groupPeer_ = [((BSBserValues *) nil_chk(values)) getObjWithInt:1 withBSBserObject:new_APGroupOutPeer_init()];
  self->rid_ = [values getLongWithInt:4];
  self->title_ = [values getStringWithInt:3];
}

- (void)serializeWithBSBserWriter:(BSBserWriter *)writer {
  if (self->groupPeer_ == nil) {
    @throw new_JavaIoIOException_init();
  }
  [((BSBserWriter *) nil_chk(writer)) writeObjectWithInt:1 withBSBserObject:self->groupPeer_];
  [writer writeLongWithInt:4 withLong:self->rid_];
  if (self->title_ == nil) {
    @throw new_JavaIoIOException_init();
  }
  [writer writeStringWithInt:3 withNSString:self->title_];
}

- (NSString *)description {
  NSString *res = @"rpc EditGroupTitle{";
  res = JreStrcat("$$", res, JreStrcat("$@", @"groupPeer=", self->groupPeer_));
  res = JreStrcat("$$", res, JreStrcat("$J", @", rid=", self->rid_));
  res = JreStrcat("$$", res, JreStrcat("$$", @", title=", self->title_));
  res = JreStrcat("$C", res, '}');
  return res;
}

- (jint)getHeaderKey {
  return APRequestEditGroupTitle_HEADER;
}

@end

APRequestEditGroupTitle *APRequestEditGroupTitle_fromBytesWithByteArray_(IOSByteArray *data) {
  APRequestEditGroupTitle_initialize();
  return ((APRequestEditGroupTitle *) BSBser_parseWithBSBserObject_withByteArray_(new_APRequestEditGroupTitle_init(), data));
}

void APRequestEditGroupTitle_initWithAPGroupOutPeer_withLong_withNSString_(APRequestEditGroupTitle *self, APGroupOutPeer *groupPeer, jlong rid, NSString *title) {
  (void) APRequest_init(self);
  self->groupPeer_ = groupPeer;
  self->rid_ = rid;
  self->title_ = title;
}

APRequestEditGroupTitle *new_APRequestEditGroupTitle_initWithAPGroupOutPeer_withLong_withNSString_(APGroupOutPeer *groupPeer, jlong rid, NSString *title) {
  APRequestEditGroupTitle *self = [APRequestEditGroupTitle alloc];
  APRequestEditGroupTitle_initWithAPGroupOutPeer_withLong_withNSString_(self, groupPeer, rid, title);
  return self;
}

void APRequestEditGroupTitle_init(APRequestEditGroupTitle *self) {
  (void) APRequest_init(self);
}

APRequestEditGroupTitle *new_APRequestEditGroupTitle_init() {
  APRequestEditGroupTitle *self = [APRequestEditGroupTitle alloc];
  APRequestEditGroupTitle_init(self);
  return self;
}

J2OBJC_CLASS_TYPE_LITERAL_SOURCE(APRequestEditGroupTitle)


text:
package org.elasticsearch.action.admin.indices.template.post;

import org.elasticsearch.action.ActionType;

public class SimulateIndexTemplateAction extends ActionType<SimulateIndexTemplateResponse> {

    public static final SimulateIndexTemplateAction INSTANCE = new SimulateIndexTemplateAction();
    public static final String NAME = "indices:admin/index_template/simulate_index";

    private SimulateIndexTemplateAction() {
        super(NAME, SimulateIndexTemplateResponse::new);
    }

}


text:
require 'spec_helper'
require 'mortar/s3'
require 's3_faker'

module Mortar
  describe S3 do
    before(:each) do
      @s3 = Mortar::S3::S3.new
    end
    context("download s3 commands") do
      keys = [
        FakeObject.new("key1", true),
        FakeObject.new("direc/key2", true),
        FakeObject.new("direc/key3", true),
        FakeObject.new("direc/.hidden_key4", true),
        FakeObject.new("direc/another_direc/key", true)
      ]

      before(:each) do
        ENV["AWS_ACCESS_KEY"] = "foo"
        ENV["AWS_SECRET_KEY"] = "bar"
        buckets = [
          {:bucket => "good_bucket", :keys =>keys, :does_exist => true},
          {:bucket => "bad_bucket", :keys=> [], :does_exist => false}]
        stub_s3(buckets, ENV["AWS_ACCESS_KEY"], ENV["AWS_SECRET_KEY"])

      end

      context("string functions") do
        it "should check if the valid path" do
          bucket, key = @s3.get_bucket_and_key('s3://bucket/key')
          bucket.should eq('bucket')
          key.should eq('key')
          bucket, key = @s3.get_bucket_and_key('s3://bucket/deeper/level/key')
          bucket.should eq('bucket')
          key.should eq('deeper/level/key')
        end

        it "should throw appropriate error if path is not valid" do
          bad_bucket = 'bad'
          previous_stderr, $stderr = $stderr, StringIO.new
          begin
            expect { @s3.get_bucket_and_key(bad_bucket) }.to raise_error(SystemExit)
            $stderr.string.should eq(" !    Requested S3 path, #{bad_bucket}, is invalid. Please ensure that your S3 path begins with 's3://'.  Example: s3://my-bucket/my-key.\n")
          ensure
            $stderr = previous_stderr
          end
        end

        it "should throw error if bucket has underscore" do
          path = "s3://will_fail/key"
          previous_stderr, $stderr = $stderr, StringIO.new
          begin
            expect { @s3.get_bucket_and_key(path) }.to raise_error(SystemExit)
            $stderr.string.should eq(" !    the scheme s3 does not accept registry part: will_fail (or bad hostname?).\n !    It is strongly suggested that your bucket name does not contain an underscore character.\n !    Please see http://blog.mortardata.com/post/58920122308/s3-hadoop-performance at tip #4.\n")
          ensure
            $stderr = previous_stderr
          end
        end

        it "should remove / if at the end" do
          str = "with/"
          str = @s3.remove_slash(str)
          str.should eq("with")
        end
        it "should not remove / if not at the end" do
          str = "without"
          @s3.remove_slash(str)
          str.should eq("without")
        end

        it "should get just the file" do
          key = "folder"
          path = "folder/file"
          @s3.is_file(path, key).should eq(true)

        end

        it "should get nothing" do
          key = "folder"
          path = "folder/file_$folder$"
          @s3.is_file(path, key).should eq(false)
          path = "folder/folder/"
          @s3.is_file(path, key).should eq(false)
        end

      end

      context("s3 functions") do
        s3 = nil
        before (:each) do
          any_instance_of(Mortar::Local::Controller) do |ctrl|
            mock(ctrl).require_aws_keys
          end
          s3 = @s3.get_s3
        end

        it "should check if bucket and key exists" do
          bucket = "good_bucket"
          key = "key1"
          @s3.check_bucket(s3, bucket).should eq(true)

          bucket = "bad_bucket"
          key = "bad_key"
          @s3.check_bucket(s3, bucket).should eq(false)
        end

        it "should get s3_objects" do
          bucket = "good_bucket"
          key = "key1"
          result = @s3.get_s3_objects(s3, bucket, key)
          result.length.should eq(1)
          result[0].key.should eq(key)

          bucket = "good_bucket"
          key = "direc"
          result = @s3.get_s3_objects(s3, bucket, key)
          result.length.should eq(2)
        end

        it "should return emtpy list if s3_objects are empty" do
          bucket = "good_bucket"
          key = "dire"
          result = @s3.get_s3_objects(s3, bucket, key)
          result.length.should eq(0)
        end

        it "should check content that is written" do
          bucket = "good_bucket"
          key = "key1"
          mock(@s3).write_s3_to_file(keys[0], 'output/key1', 'w+')
          @s3.download_s3(s3, bucket, key, 'output')
        end

        it "should check all files are written" do
          bucket = "good_bucket"
          key = "direc"
          mock(@s3).write_s3_to_file(keys[1], 'output/key2', 'w+')
          mock(@s3).write_s3_to_file(keys[2], 'output/key3', 'w+')
          @s3.download_s3(s3, bucket, key, 'output')
        end

        it "should concat all files to one and delete out file when already exists" do
          bucket = "good_bucket"
          key = "direc"
          mock(File).file?("output/output"){true}
          mock(FileUtils).remove("output/output")
          mock(@s3).write_s3_to_file(keys[1], 'output/output', 'a')
          mock(@s3).write_s3_to_file(keys[2], 'output/output', 'a')
          @s3.download_s3(s3, bucket, key, 'output', true)
        end
      end
    end
  end
end