 bondscell_results $9fe42679-dce3-4ee3-b565-eed4ff7d8e4dqueued¤logsrunning¦outputbody<div class="markdown"><h3>Figure 5.2:</h3>
<p>The optimal policy and state-value function for blackjack found by Monte Carlo ES.  The state value function shown was computed from the action-value function found by Monte Carlo ES</p>
</div>mimetext/htmlrootassigneelast_run_timestampA"'аpersist_js_state·has_pluto_hook_features§cell_id$9fe42679-dce3-4ee3-b565-eed4ff7d8e4ddepends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$06960937-a87a-4015-bdeb-5d17aa41fe6bqueued¤logsrunning¦outputbody5plot_blackjack_value (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA%ۘpersist_js_state·has_pluto_hook_features§cell_id$06960937-a87a-4015-bdeb-5d17aa41fe6bdepends_on_disabled_cells§runtime dpublished_object_keysdepends_on_skipped_cells§errored$abdcbbad-747a-41ba-a95d-82404e735793queued¤logsrunning¦outputbody4make_ϵsoft_policy! (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA(persist_js_state·has_pluto_hook_features§cell_id$abdcbbad-747a-41ba-a95d-82404e735793depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$846ccb44-a18b-4d87-bbf8-fc59eaf87708queued¤logsrunning¦outputbody<div class="markdown"><p>Number of Episodes: <bond def="opmc1" unique_id="cLzytx4IJAJe"><span style='display: contents;'>
	<input type='number' min='1' step='1' max='10000000' value='1000'>
	<input type=submit id='teixlucpgs'>
	<script id='teixlucpgs'>

let key = "teixlucpgs"

let div = currentScript.parentElement
let button = currentScript.previousElementSibling
let input = div.firstElementChild
if(input === button) {
	return
}


let set_input_value = (() => {
	let result = null
	try {
	result = setBoundElementValueLikePluto
} catch (e) {
	result = ((input, new_value) => {
	// fallback in case https://github.com/fonsp/Pluto.jl/pull/1755 is not available
    if (new_value == null) {
        //@ts-ignore
        input.value = new_value
        return
    }
    if (input instanceof HTMLInputElement) {
        switch (input.type) {
            case "range":
            case "number": {
                if (input.valueAsNumber !== new_value) {
                    input.valueAsNumber = new_value
                }
                return
            }
            case "date": {
                if (input.valueAsDate == null || Number(input.valueAsDate) !== Number(new_value)) {
                    input.valueAsDate = new_value
                }
                return
            }
            case "checkbox": {
                if (input.checked !== new_value) {
                    input.checked = new_value
                }
                return
            }
            case "file": {
                // Can't set files :(
                return
            }
        }
    } else if (input instanceof HTMLSelectElement && input.multiple) {
        for (let option of Array.from(input.options)) {
            option.selected = new_value.includes(option.value)
        }
        return
    }
    //@ts-ignore
    if (input.value !== new_value) {
        //@ts-ignore
        input.value = new_value
    }
})
}
return result
})()



let private_value = null
let public_value = null




private_value = public_value = div.value
if(private_value != null) {
	set_input_value(input, private_value)
} else {

	// private_value = public_value = input.value
}

input.oninput = (e) => {
	e.stopPropagation()
}
const gen = Generators.input(input)

// If the child does not have an initial value, the `gen.next().value` promise will never resolve. If it does, then it resolves instantly.
let first_value = await Promise.any([
	gen.next().value,
	Promise.resolve(undefined)
])
private_value = public_value = first_value

;(async () => {
	while(true) {
		private_value = await gen.next().value
		// div.dispatchEvent(new CustomEvent("input", {}))
	}
})()

button.addEventListener("click", () => {
	public_value = private_value
	div.dispatchEvent(new CustomEvent("input", {}))
})


Object.defineProperty(div, 'value', {
	get: () => public_value,
	set: (newval) => {
		private_value = newval
		public_value = newval
		
		set_input_value(input, newval)
	},
	configurable: true,
});

</script></span></bond></p>
</div>mimetext/htmlrootassigneelast_run_timestampA0persist_js_state·has_pluto_hook_features§cell_id$846ccb44-a18b-4d87-bbf8-fc59eaf87708depends_on_disabled_cells§runtime/+published_object_keysdepends_on_skipped_cells§errored$154edd83-350d-4acf-adfb-6a2d20599b53queued¤logsrunning¦outputbody)showrace (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA/fpersist_js_state·has_pluto_hook_features§cell_id$154edd83-350d-4acf-adfb-6a2d20599b53depends_on_disabled_cells§runtime 6]published_object_keysdepends_on_skipped_cells§errored$ff9276eb-2151-4a6f-8257-8348047a9f4equeued¤logsrunning¦outputbodyelementsprefixI@NamedTuple{position::Tuple{Int64, Int64}, velocity::Tuple{Int64, Int64}}elementselementspositionelements6text/plain0text/plaintypeTupleobjectid9cbae2ac4ef69449!application/vnd.pluto.tree+objectvelocityelements0text/plain0text/plaintypeTupleobjectid9b52efd7a2a08bd5!application/vnd.pluto.tree+objecttypeNamedTupleobjectid38489c3038c1df3d!application/vnd.pluto.tree+objectelementspositionelements7text/plain0text/plaintypeTupleobjectid627f1c091b0a4b9c!application/vnd.pluto.tree+objectvelocityelements1text/plain0text/plaintypeTupleobjectid1539b04621ff8c7d!application/vnd.pluto.tree+objecttypeNamedTupleobjectid10ed139d1891153d!application/vnd.pluto.tree+objectelementspositionelements8text/plain1text/plaintypeTupleobjectid6d43cd1c8dd97fd1!application/vnd.pluto.tree+objectvelocityelements1text/plain1text/plaintypeTupleobjectid78e123e4f427692a!application/vnd.pluto.tree+objecttypeNamedTupleobjectidba6e6e87bab90698!application/vnd.pluto.tree+objectelementspositionelements10text/plain1text/plaintypeTupleobjectiddad6dff378d50b10!application/vnd.pluto.tree+objectvelocityelements2text/plain0text/plaintypeTupleobjectid83bf2aef4031930b!application/vnd.pluto.tree+objecttypeNamedTupleobjectid7f05885cf5a97609!application/vnd.pluto.tree+objectelementspositionelements12text/plain1text/plaintypeTupleobjectidba2d0d303a66d681!application/vnd.pluto.tree+objectvelocityelements2text/plain0text/plaintypeTupleobjectid83bf2aef4031930b!application/vnd.pluto.tree+objecttypeNamedTupleobjectid4fdd2575d8325500!application/vnd.pluto.tree+objectelementspositionelements13text/plain1text/plaintypeTupleobjectide6f480949e3f3c15!application/vnd.pluto.tree+objectvelocityelements1text/plain0text/plaintypeTupleobjectid1539b04621ff8c7d!application/vnd.pluto.tree+objecttypeNamedTupleobjectid1dfbc9164ac7630!application/vnd.pluto.tree+objectelementspositionelements14text/plain1text/plaintypeTupleobjectid7717f5f1045ca395!application/vnd.pluto.tree+objectvelocityelements1text/plain0text/plaintypeTupleobjectid1539b04621ff8c7d!application/vnd.pluto.tree+objecttypeNamedTupleobjectid4cab6926e0cac33!application/vnd.pluto.tree+objectelementspositionelements16text/plain1text/plaintypeTupleobjectid9466b49b27b0fbe4!application/vnd.pluto.tree+objectvelocityelements2text/plain0text/plaintypeTupleobjectid83bf2aef4031930b!application/vnd.pluto.tree+objecttypeNamedTupleobjectid7215dbdcb350d980!application/vnd.pluto.tree+object	elementspositionelements17text/plain1text/plaintypeTupleobjectid5cabddc83be126e5!application/vnd.pluto.tree+objectvelocityelements1text/plain0text/plaintypeTupleobjectid1539b04621ff8c7d!application/vnd.pluto.tree+objecttypeNamedTupleobjectid80c7dd8e4d5c743a!application/vnd.pluto.tree+objectmoreFelementspositionelements29text/plain29text/plaintypeTupleobjectid7233ef8a34e83c81!application/vnd.pluto.tree+objectvelocityelements3text/plain3text/plaintypeTupleobjectid3ed622ab32dfec93!application/vnd.pluto.tree+objecttypeNamedTupleobjectid56645bf7a9faff88!application/vnd.pluto.tree+objecttypeArrayprefix_shortobjectid47e58d64316784d!application/vnd.pluto.tree+objectprefixTuple{Int64, Int64}elementselements0text/plain0text/plaintypeTupleobjectid9b52efd7a2a08bd5!application/vnd.pluto.tree+objectelements0text/plain1text/plaintypeTupleobjectid86128cc9b5ae8f4a!application/vnd.pluto.tree+objectelements1text/plain-1text/plaintypeTupleobjectid467534c86eaf64c9!application/vnd.pluto.tree+objectelements0text/plain0text/plaintypeTupleobjectid9b52efd7a2a08bd5!application/vnd.pluto.tree+objectelements-1text/plain-1text/plaintypeTupleobjectida5f5003e88013c47!application/vnd.pluto.tree+objectelements0text/plain0text/plaintypeTupleobjectid9b52efd7a2a08bd5!application/vnd.pluto.tree+objectelements1text/plain0text/plaintypeTupleobjectid1539b04621ff8c7d!application/vnd.pluto.tree+objectelements-1text/plain0text/plaintypeTupleobjectid29547c053cf46d53!application/vnd.pluto.tree+object	elements1text/plain1text/plaintypeTupleobjectid78e123e4f427692a!application/vnd.pluto.tree+objectmoreFelements0text/plain0text/plaintypeTupleobjectid9b52efd7a2a08bd5!application/vnd.pluto.tree+objecttypeArrayprefix_shortobjectide60c88608632daae!application/vnd.pluto.tree+objectprefixFloat32elements-1.0text/plain-1.0text/plain-1.0text/plain-1.0text/plain-1.0text/plain-1.0text/plain-1.0text/plain-1.0text/plain	-1.0text/plainmoreF-1.0text/plaintypeArrayprefix_shortobjectideac5b2068fa52d22!application/vnd.pluto.tree+objecttypeTupleobjectid19350ad34cc18b19mime!application/vnd.pluto.tree+objectrootassigneerace_episode2last_run_timestampA0a-ܰpersist_js_state·has_pluto_hook_features§cell_id$ff9276eb-2151-4a6f-8257-8348047a9f4edepends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$6f914006-1d8d-41f5-ae8a-fbe0b336946cqueued¤logsrunning¦outputbody 1;	<div style = "display: flex;">
	<div>
Race finished in 11 steps
<div style="background-color: white; color: black;">
	<div style="display:flex; align-items: flex-start">
	<div class = "track">
		<div class = "start" style="grid-column-start: 8; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 5; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 14; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "-1" dvy = "0" style="grid-column-start: 16; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 3; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 11; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 19; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 22; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 6; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 17; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 21; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 13; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 9; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 18; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 2; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 20; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 1; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 23; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 7; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 12; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 10; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 15; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 4; grid-row-start: 1;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 5;"></div><div class = "" vx = "1" vy = "2" dvx = "0" dvy = "1" style="grid-column-start: 17; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 12;"></div><div class = "" vx = "2" vy = "4" dvx = "1" dvy = "-1" style="grid-column-start: 21; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 26;"></div><div class = "" vx = "3" vy = "3" dvx = "1" dvy = "-1" style="grid-column-start: 24; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 3;"></div><div class = "" vx = "4" vy = "2" dvx = "1" dvy = "0" style="grid-column-start: 28; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 8;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "-1" style="grid-column-start: 16; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 5;"></div><div class = "" vx = "1" vy = "3" dvx = "0" dvy = "1" style="grid-column-start: 18; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 24;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "1" style="grid-column-start: 16; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 12;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "1" style="grid-column-start: 16; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 14;"></div><div class = "" vx = "1" vy = "4" dvx = "1" dvy = "1" style="grid-column-start: 19; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 16;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "0" style="grid-column-start: 16; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 27;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 30;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 27;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 23;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 28;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 29;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 26;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 25;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 24;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 22;"></div>
	</div>
	Finish <br> line
	</div>
	<div>Starting line</div>
</div>
</div>

	<div>
Race finished in 22 steps
<div style="background-color: white; color: black;">
	<div style="display:flex; align-items: flex-start">
	<div class = "track">
		<div class = "start" style="grid-column-start: 8; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 5; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 14; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 16; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 3; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 11; grid-row-start: 1;"></div><div class = "start" vx = "1" vy = "0" dvx = "0" dvy = "1" style="grid-column-start: 19; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 22; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "0" dvy = "-1" style="grid-column-start: 6; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 17; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 21; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 13; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 9; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "-1" dvy = "-1" style="grid-column-start: 18; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 2; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 20; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 1; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 23; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 7; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 12; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 10; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 15; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 4; grid-row-start: 1;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 12;"></div><div class = "" vx = "1" vy = "2" dvx = "0" dvy = "0" style="grid-column-start: 19; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 8;"></div><div class = "" vx = "1" vy = "2" dvx = "-1" dvy = "0" style="grid-column-start: 20; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 23;"></div><div class = "" vx = "3" vy = "2" dvx = "1" dvy = "1" style="grid-column-start: 26; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 16;"></div><div class = "" vx = "3" vy = "0" dvx = "-1" dvy = "1" style="grid-column-start: 13; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 11;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "0" style="grid-column-start: 20; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 28;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "-1" style="grid-column-start: 6; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 7;"></div><div class = "" vx = "2" vy = "1" dvx = "-1" dvy = "1" style="grid-column-start: 18; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 3;"></div><div class = "" vx = "1" vy = "0" dvx = "1" dvy = "0" style="grid-column-start: 8; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 5;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "0" style="grid-column-start: 20; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 11;"></div><div class = "" vx = "1" vy = "1" dvx = "0" dvy = "-1" style="grid-column-start: 20; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 24;"></div><div class = "" vx = "1" vy = "2" dvx = "1" dvy = "-1" style="grid-column-start: 16; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 28;"></div><div class = "" vx = "2" vy = "1" dvx = "-1" dvy = "1" style="grid-column-start: 15; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 20;"></div><div class = "" vx = "1" vy = "0" dvx = "-1" dvy = "-1" style="grid-column-start: 7; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 23;"></div><div class = "" vx = "1" vy = "0" dvx = "0" dvy = "1" style="grid-column-start: 21; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 27;"></div><div class = "" vx = "2" vy = "0" dvx = "1" dvy = "-1" style="grid-column-start: 10; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 28;"></div><div class = "" vx = "1" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 22; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 23;"></div><div class = "" vx = "2" vy = "3" dvx = "1" dvy = "-1" style="grid-column-start: 23; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 13;"></div><div class = "" vx = "1" vy = "2" dvx = "1" dvy = "1" style="grid-column-start: 21; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 20;"></div><div class = "" vx = "4" vy = "3" dvx = "-1" dvy = "1" style="grid-column-start: 30; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 27;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 30;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 27;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 23;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 28;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 29;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 26;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 25;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 24;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 22;"></div>
	</div>
	Finish <br> line
	</div>
	<div>Starting line</div>
</div>
</div>

	</div>
mimetext/htmlrootassigneelast_run_timestampA4tpersist_js_state·has_pluto_hook_features§cell_id$6f914006-1d8d-41f5-ae8a-fbe0b336946cdepends_on_disabled_cells§runtime1]published_object_keysdepends_on_skipped_cells§errored$4197cc28-b24c-48cb-bd8d-ef998983ad77queued¤logsrunning¦outputbodymimetext/plainrootassigneelast_run_timestampA)T\persist_js_state·has_pluto_hook_features§cell_id$4197cc28-b24c-48cb-bd8d-ef998983ad77depends_on_disabled_cells§runtime ?Opublished_object_keysdepends_on_skipped_cells§errored$e67d9deb-a074-48ba-84db-2e6938ea01f8queued¤logsrunning¦outputbody3monte_carlo_pred_Q (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA-Upersist_js_state·has_pluto_hook_features§cell_id$e67d9deb-a074-48ba-84db-2e6938ea01f8depends_on_disabled_cells§runtime 2published_object_keysdepends_on_skipped_cells§errored$82a1f11e-b1b3-4c7d-ab9d-9f6136ae8195queued¤logsrunning¦outputbody2×1 Matrix{Float32}:
 0.5
 0.5mimetext/plainrootassigneeconst onestate_π_blast_run_timestampA,epersist_js_state·has_pluto_hook_features§cell_id$82a1f11e-b1b3-4c7d-ab9d-9f6136ae8195depends_on_disabled_cells§runtime&published_object_keysdepends_on_skipped_cells§errored$11f8290f-f589-49ff-9602-99ccc4192884queued¤logsrunning¦outputbodym<div class="markdown"><p>Statistics for Steps to Finish Race on Track 2</p>

<table><tr><th align="right">Statistic</th><th align="right"><div class="markdown"><p>Off policy MC Control</p>
</div></th><th align="right">Random Policy</th></tr><tr><td align="right">Mean</td><td align="right">290</td><td align="right">286</td></tr><tr><td align="right">Median</td><td align="right">218</td><td align="right">194</td></tr><tr><td align="right">Std</td><td align="right">263</td><td align="right">282</td></tr><tr><td align="right">Minimum</td><td align="right">10</td><td align="right">10</td></tr><tr><td align="right">Maximum</td><td align="right">1848</td><td align="right">1999</td></tr></table>
<p>Cummulative Distribution Function of Steps to Finish Race 	<script id='plot_1'>
		// We start by putting all the variable interpolation here at the beginning
		// We have to convert all typedarrays in the layout to normal arrays. See Issue #25
		// We use lodash for this for compactness
		function removeTypedArray(o) {
			return _.isTypedArray(o) ? Array.from(o) :
			_.isPlainObject(o) ? _.mapValues(o, removeTypedArray) : 
			o
		}

		// Publish the plot object to JS
		let plot_obj = _.update(/* See the documentation for AbstractPlutoDingetjes.Display.published_to_js */ getPublishedObject("c6e0de0c-3901-11f0-234e-bd09c571f662/8b2f6661ab801d2c"), "layout", removeTypedArray)
		// Get the plotly listeners
		const plotly_listeners = {}
		// Get the JS listeners
		const js_listeners = {}
		// Deal with eventual custom classes
		let custom_classlist = []


		// Load the plotly library
		let Plotly = undefined
		try {
			let _mod = await import("./plotlyjs/plotlyjs-2.26.2.min.js")
			Plotly = _mod.default
		} catch (e) {
			console.log("Local load failed, trying with the web esm.sh version")
			let _mod = await import("https://esm.sh/plotly.js-dist-min@2.26.2/es2022/plotly.js-dist-min.mjs")
			Plotly = _mod.default
		}

		// Check if we have to force local mathjax font cache
		if (false && window?.MathJax?.config?.svg?.fontCache === 'global') {
			window.MathJax.config.svg.fontCache = 'local'
		}

		// Flag to check if this cell was  manually ran or reactively ran
const firstRun = this ? false : true
const CONTAINER = this ?? html`<div class='plutoplotly-container'>`
const PLOT = CONTAINER.querySelector('.js-plotly-plot') ?? CONTAINER.appendChild(html`<div>`)
const parent = CONTAINER.parentElement
// We use a controller to remove event listeners upon invalidation
const controller = new AbortController()
// We have to add this to keep supporting @bind with the old API using PLOT
PLOT.addEventListener('input', (e) => {
	CONTAINER.value = PLOT.value
	if (e.bubbles) {
		return
	}
	CONTAINER.dispatchEvent(new CustomEvent('input'))
}, { signal: controller.signal })

	// This create the style subdiv on first run
	firstRun && CONTAINER.appendChild(html`
	<style>
	.plutoplotly-container {
		width: 100%;
		height: 100%;
		min-height: 0;
		min-width: 0;
	}
	.plutoplotly-container .js-plotly-plot .plotly div {
		margin: 0 auto; // This centers the plot
	}
	.plutoplotly-container.popped-out {
		overflow: auto;
		z-index: 1000;
		position: fixed;
		resize: both;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		border-top-left-radius: 0px;
		border-top-right-radius: 0px;
	}
	.plutoplotly-clipboard-header {
		display: flex;
		flex-flow: row wrap;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-top-left-radius: 12px;
		border-top-right-radius: 12px;
		position: fixed;
		z-index: 1001;
		cursor: move;
		transform: translate(0px, -100%);
		padding: 5px;
	}
	.plutoplotly-clipboard-header span {
		display: inline-block;
		flex: 1
	}
	.plutoplotly-clipboard-header.hidden {
		display: none;
	}
	.clipboard-span {
		position: relative;
	}
	.clipboard-value {
		padding-right: 5px;
		padding-left: 2px;
		cursor: text;
	}
	.clipboard-span.format {
		display: none;
	}
	.clipboard-span.filename {
		flex: 0 0 100%;
		text-align: center;
		border-top: 3px solid var(--kbd-border-color);
		margin-top: 5px;
		display: none;
	}
	.plutoplotly-container.filesave .clipboard-span.filename {
		display: inline-block;
	}
	.clipboard-value.filename {
		margin-left: 3px;
		text-align: left;
		min-width: min(60%, min-content);
	}
	.plutoplotly-container.filesave .clipboard-span.format {
		display: inline-flex;
	}
	.clipboard-span.format .label {
		flex: 0 0 0;
	}
	.clipboard-value.format {
		position: relative;
		flex: 1 0 auto;
		min-width: 30px;
		margin-right: 10px;
	}
	div.format-options {
		display: inline-flex;
		flex-flow: column;
		position: absolute;
		background: var(--main-bg-color);
		border-radius: 12px;
		padding-left: 3px;
		z-index: 2000;
	}
	div.format-options:hover {
		cursor: pointer;
		border: 3px solid var(--kbd-border-color);
		padding: 3px;
		transform: translate(-3px, -6px);
	}
	div.format-options .format-option {
		display: none;
	}
	div.format-options:hover .format-option {
		display: inline-block;
	}
	.format-option:not(.selected) {
		margin-top: 3px;
	}
	div.format-options .format-option.selected {
		order: -1;
		display: inline-block;
	}
	.format-option:hover {
		background-color: var(--kbd-border-color);
	}
	span.config-value {
		font-weight: normal;
		color: var(--pluto-output-color);
		display: none;
		position: absolute;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		transform: translate(0px, calc(-100% - 10px));
		padding: 5px;
	}
	.label {
		user-select: none;
	}
	.label:hover span.config-value {
		display: inline-block;
		min-width: 150px;
	}
	.clipboard-span.matching-config .label {
		color: var(--cm-macro-color);
		font-weight: bold;
	}
	.clipboard-span.different-config .label {
		color: var(--cm-tag-color);
		font-weight: bold;
	}
</style>
`)

let original_height = plot_obj.layout.height
let original_width = plot_obj.layout.width
// For the height we have to also put a fixed value in case the plot is put on a non-fixed-size container (like the default wrapper)
// We define a variable to check whether we still have to remove the fixed height
let remove_container_size = firstRun
let container_height = original_height ?? PLOT.container_height ?? 400
CONTAINER.style.height = container_height + 'px'

// We create a Promise version of setTimeout
function delay(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

// We import interact for dragging/resizing
const { default: interact } = await import('https://esm.sh/interactjs@1.10.19')


function getImageOptions() {
  const o = plot_obj.config.toImageButtonOptions ?? {};
  return {
    format: o.format ?? "png",
    width: o.width ?? original_width,
    height: o.height ?? original_height,
    scale: o.scale ?? 1,
    filename: o.filename ?? "newplot",
  };
}

const CLIPBOARD_HEADER =
  CONTAINER.querySelector(".plutoplotly-clipboard-header") ??
  CONTAINER.insertAdjacentElement(
    "afterbegin",
    html`<div class="plutoplotly-clipboard-header hidden">
      <span class="clipboard-span format"
        ><span class="label">Format:</span
        ><span class="clipboard-value format"></span
      ></span>
      <span class="clipboard-span width"
        ><span class="label">Width:</span
        ><span class="clipboard-value width"></span>px</span
      >
      <span class="clipboard-span height"
        ><span class="label">Height:</span
        ><span class="clipboard-value height"></span>px</span
      >
      <span class="clipboard-span scale"
        ><span class="label">Scale:</span
        ><span class="clipboard-value scale"></span
      ></span>
      <button class="clipboard-span set">Set</button>
      <button class="clipboard-span unset">Unset</button>
      <span class="clipboard-span filename"
        ><span class="label">Filename:</span
        ><span class="clipboard-value filename"></span
      ></span>
    </div>`
  );

function checkConfigSync(container) {
  const valid_classes = [
    "missing-config",
    "matching-config",
    "different-config",
  ];
  function setClass(cl) {
    for (const name of valid_classes) {
      container.classList.toggle(name, name == cl);
    }
  }
  // We use the custom getters we'll set up in the container
  const { ui_value, config_value, config_span, key } = container;
  if (config_value === undefined) {
    setClass("missing-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> is not present in the config.`;
  } else if (ui_value == config_value) {
    setClass("matching-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has the same value in the config and in the header.`;
  } else {
    setClass("different-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has a different value (<em>${config_value}</em>) in the config.`;
  }
  // Add info about setting and unsetting
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click on the label <em><b>once</b></em> to set the current UI value in the config.`
  );
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click <em><b>twice</b></em> to remove this key from the config.`
  );
}

const valid_formats = ["png", "svg", "webp", "jpeg", "full-json"];
function initializeUIValueSpan(span, key, value) {
  const container = span.closest(".clipboard-span");
  span.contentEditable = key === "format" ? "false" : "true";
  let parse = (x) => x;
  let update = (x) => (span.textContent = x);
  if (key === "width" || key === "height") {
    parse = (x) => Math.round(parseFloat(x));
  } else if (key === "scale") {
    parse = parseFloat;
  } else if (key === "format") {
    // We remove contentEditable
    span.contentEditable = "false";
    // Here we first add the subspans for each option
    const opts_div = span.appendChild(html`<div class="format-options"></div>`);
    for (const fmt of valid_formats) {
      const opt = opts_div.appendChild(
        html`<span class="format-option ${fmt}">${fmt}</span>`
      );
      opt.onclick = (e) => {
        span.value = opt.textContent;
      };
    }
    parse = (x) => {
      return valid_formats.includes(x) ? x : localValue;
    };
    update = (x) => {
      for (const opt of opts_div.children) {
        opt.classList.toggle("selected", opt.textContent === x);
      }
    };
  } else {
    // We only have filename here
  }
  let localValue;
  Object.defineProperty(span, "value", {
    get: () => {
      return localValue;
    },
    set: (val) => {
      if (val !== "") {
        localValue = parse(val);
      }
      update(localValue);
      checkConfigSync(container);
    },
  });
  // We also assign a listener so that the editable is blurred when enter is pressed
  span.onkeydown = (e) => {
    if (e.keyCode === 13) {
      e.preventDefault();
      span.blur();
    }
  };
  span.value = value;
}

function initializeConfigValueSpan(span, key) {
  // Here we mostly want to define the setter and getter
  const container = span.closest(".clipboard-span");
  Object.defineProperty(span, "value", {
    get: () => {
      return plot_obj.config.toImageButtonOptions[key];
    },
    set: (val) => {
      // if undefined is passed, we remove the entry from the options
      if (val === undefined) {
        delete plot_obj.config.toImageButtonOptions[key];
      } else {
        plot_obj.config.toImageButtonOptions[key] = val;
      }
      checkConfigSync(container);
    },
  });
}

const config_spans = {};
for (const [key, value] of Object.entries(getImageOptions())) {
  const container = CLIPBOARD_HEADER.querySelector(`.clipboard-span.${key}`);
  const label = container.querySelector(".label");
  // We give the label a function that on single click will set the current value and with double click will unset it
  label.onclick = DualClick(
    () => {
      container.config_value = container.ui_value;
    },
    (e) => {
      console.log("e", e);
      e.preventDefault();
      container.config_value = undefined;
    }
  );
  const ui_value_span = container.querySelector(".clipboard-value");
  const config_value_span =
    container.querySelector(".config-value") ??
    label.insertAdjacentElement(
      "afterbegin",
      html`<span class="config-value"></span>`
    );
  // Assing the two spans as properties of the containing span
  container.ui_span = ui_value_span;
  container.config_span = config_value_span;
  container.key = key;
  config_spans[key] = container;
  if (firstRun) {
    plot_obj.config.toImageButtonOptions =
      plot_obj.config.toImageButtonOptions ?? {};
    // We do the initialization of the value span
    initializeUIValueSpan(ui_value_span, key, value);
    // Then we initialize the config value
    initializeConfigValueSpan(config_value_span, key);
    // We put some convenience getters/setters
    // ui_value forward
    Object.defineProperty(container, "ui_value", {
      get: () => ui_value_span.value,
      set: (val) => {
        ui_value_span.value = val;
      },
    });
    // config_value forward
    Object.defineProperty(container, "config_value", {
      get: () => config_value_span.value,
      set: (val) => {
        config_value_span.value = val;
      },
    });
  }
}

// These objects will contain the default value

// This code updates the image options in the PLOT config with the provided ones
function setImageOptions(o) {
  for (const [key, container] of Object.entries(config_spans)) {
    container.config_value = o[key];
  }
}
function unsetImageOptions() {
  setImageOptions({});
}

const set_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.set");
const unset_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.unset");
if (firstRun) {
  set_button.onclick = (e) => {
    for (const container of Object.values(config_spans)) {
      container.config_value = container.ui_value;
    }
  };
  unset_button.onclick = unsetImageOptions;
}

// We add a function to check if the clipboard is popped out
CONTAINER.isPoppedOut = () => {
  return CONTAINER.classList.contains("popped-out");
};

CLIPBOARD_HEADER.onmousedown = function (event) {
  if (event.target.matches("span.clipboard-value")) {
    console.log("We don't move!");
    return;
  }
  const start = {
    left: parseFloat(CONTAINER.style.left),
    top: parseFloat(CONTAINER.style.top),
    X: event.pageX,
    Y: event.pageY,
  };
  function moveAt(event, start) {
    const top = event.pageY - start.Y + start.top + "px";
    const left = event.pageX - start.X + start.left + "px";
    CLIPBOARD_HEADER.style.left = left;
    CONTAINER.style.left = left;
    CONTAINER.style.top = top;
  }

  // move our absolutely positioned ball under the pointer
  moveAt(event, start);
  function onMouseMove(event) {
    moveAt(event, start);
  }

  // We use this to remove the mousemove when clicking outside of the container
  const controller = new AbortController();

  // move the container on mousemove
  document.addEventListener("mousemove", onMouseMove, {
    signal: controller.signal,
  });
  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        cleanUp();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );

  function cleanUp() {
    console.log("cleaning up the plot move listener");
    controller.abort();
    CLIPBOARD_HEADER.onmouseup = null;
  }

  // (3) drop the ball, remove unneeded handlers
  CLIPBOARD_HEADER.onmouseup = cleanUp;
};

function sendToClipboard(blob) {
  if (!navigator.clipboard) {
    alert(
      "The Clipboard API does not seem to be available, make sure the Pluto notebook is being used from either localhost or an https source."
    );
  }
  navigator.clipboard
    .write([
      new ClipboardItem({
        // The key is determined dynamically based on the blob's type.
        [blob.type]: blob,
      }),
    ])
    .then(
      function () {
        console.log("Async: Copying to clipboard was successful!");
      },
      function (err) {
        console.error("Async: Could not copy text: ", err);
      }
    );
}

function copyImageToClipboard() {
  // We extract the image options from the provided parameters (if they exist)
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key. We also ignore format because the clipboard only supports png.
    if (val === undefined || key === "format") {
      continue;
    }
    config[key] = val;
  }
  Plotly.toImage(PLOT, config).then(function (dataUrl) {
    fetch(dataUrl)
      .then((res) => res.blob())
      .then((blob) => {
        const paste_receiver = document.querySelector('paste-receiver.plutoplotly')
        if (paste_receiver) {
          paste_receiver.attachImage(dataUrl, CONTAINER)
        }
        sendToClipboard(blob)
      });
  });
}

function saveImageToFile() {
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key.
    if (val === undefined) {
      continue;
    }
    config[key] = val;
  }
  Plotly.downloadImage(PLOT, config);
}

let container_rect = { width: 0, height: 0, top: 0, left: 0 };
function unpop_container(cl) {
  CONTAINER.classList.toggle("popped-out", false);
  CONTAINER.classList.toggle(cl, false);
  // We fix the height back to the value it had before popout, also setting the flag to signal that upon first resize we remove the fixed inline-style
  CONTAINER.style.height = container_rect.height + "px";
  remove_container_size = true;
  // We set the other fixed inline-styles to null
  CONTAINER.style.width = "";
  CONTAINER.style.top = "";
  CONTAINER.style.left = "";
  // We also remove the CLIPBOARD_HEADER
  CLIPBOARD_HEADER.style.width = "";
  CLIPBOARD_HEADER.style.left = "";
  // Finally we remove the hidden class to the header
  CLIPBOARD_HEADER.classList.toggle("hidden", true);
  return;
}
function popout_container(opts) {
  const cl = opts?.cl;
  const target_container_size = opts?.target_container_size ?? {};
  const target_plot_size = opts?.target_plot_size ?? {};
  if (CONTAINER.isPoppedOut()) {
    return unpop_container(cl);
  }
  CONTAINER.classList.toggle(cl, cl === undefined ? false : true);
  // We extract the current size of the container, save them and fix them
  const { width, height, top, left } = CONTAINER.getBoundingClientRect();
  container_rect = { width, height, top, left };
  // We save the current plot size before we pop as it will fill the screen
  const current_plot_size = {
    width: PLOT._fullLayout.width,
    height: PLOT._fullLayout.height,
  };
  // We have to save the pad data before popping so we can resize precisely
  const pad = {};
  pad.unpopped = getSizeData().container_pad;
  CONTAINER.classList.toggle("popped-out", true);
  pad.popped = getSizeData().container_pad;
  // We do top and left based on the current rect
  for (const key of ["top", "left"]) {
    const start_val = target_container_size[key] ?? container_rect[key];
    let offset = 0;
    for (const kind of ["padding", "border"]) {
      offset += pad.popped[kind][key] - pad.unpopped[kind][key];
    }
    CONTAINER.style[key] = start_val - offset + "px";
    if (key === "left") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  // We compute the width and height depending on eventual config data
  const csz = computeContainerSize({
    width:
      target_plot_size.width ??
      config_spans.width.config_value ??
      current_plot_size.width,
    height:
      target_plot_size.height ??
      config_spans.height.config_value ??
      current_plot_size.height,
  });
  for (const key of ["width", "height"]) {
    const val = target_container_size[key] ?? csz[key];
    CONTAINER.style[key] = val + "px";
    if (key === "width") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  CLIPBOARD_HEADER.classList.toggle("hidden", false);
  const controller = new AbortController();

  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        unpop_container();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );
}

CONTAINER.popOut = popout_container;

function DualClick(single_func, dbl_func) {
  let nclicks = 0;
  return function (...args) {
    nclicks += 1;
    if (nclicks > 1) {
      dbl_func(...args);
      nclicks = 0;
    } else {
      delay(300).then(() => {
        if (nclicks == 1) {
          single_func(...args);
        }
        nclicks = 0;
      });
    }
  };
}

// We remove the default download image button
plot_obj.config.modeBarButtonsToRemove = _.union(
  plot_obj.config.modeBarButtonsToRemove,
  ["toImage"]
);
// We add the custom button to the modebar
plot_obj.config.modeBarButtonsToAdd = _.union(
  plot_obj.config.modeBarButtonsToAdd,
  [
    {
      name: "Copy PNG to Clipboard",
      icon: {
        height: 520,
        width: 520,
        path: "M280 64h40c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128C0 92.7 28.7 64 64 64h40 9.6C121 27.5 153.3 0 192 0s71 27.5 78.4 64H280zM64 112c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16H320c8.8 0 16-7.2 16-16V128c0-8.8-7.2-16-16-16H304v24c0 13.3-10.7 24-24 24H192 104c-13.3 0-24-10.7-24-24V112H64zm128-8a24 24 0 1 0 0-48 24 24 0 1 0 0 48z",
      },
      direction: "up",
      click: DualClick(copyImageToClipboard, () => {
        popout_container();
      }),
    },
    {
      name: "Download Image",
      icon: Plotly.Icons.camera,
      direction: "up",
      click: DualClick(saveImageToFile, () => {
        popout_container({ cl: "filesave" });
      }),
    },
  ]
);

function getOffsetData(el) {
  let cs = window.getComputedStyle(el, null);
  const odata = {
    padding: {
      left: parseFloat(cs.paddingLeft),
      right: parseFloat(cs.paddingRight),
      top: parseFloat(cs.paddingTop),
      bottom: parseFloat(cs.paddingBottom),
      width: parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight),
      height: parseFloat(cs.paddingTop) + parseFloat(cs.paddingBottom),
    },
    border: {
      left: parseFloat(cs.borderLeftWidth),
      right: parseFloat(cs.borderRightWidth),
      top: parseFloat(cs.borderTopWidth),
      bottom: parseFloat(cs.borderBottomWidth),
      width: parseFloat(cs.borderLeftWidth) + parseFloat(cs.borderRightWidth),
      height: parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth),
    }
  };
  if (el === PLOT) {
    // For the PLOT we also want to take into account the offset
    odata.offset = {
      top: PLOT.offsetParent == CONTAINER ? PLOT.offsetTop : 0,
      left: PLOT.offsetParent == CONTAINER ? PLOT.offsetLeft : 0,
    }
  }
  return odata;
}
function getSizeData() {
  const data = {
    plot_pad: getOffsetData(PLOT),
    plot_rect: PLOT.getBoundingClientRect(),
    container_pad: getOffsetData(CONTAINER),
    container_rect: CONTAINER.getBoundingClientRect(),
  };
  return data;
}
function computeContainerSize({ width, height }, sizeData = getSizeData()) {
  const computed_size = computePlotSize(sizeData);
  const offsets = computed_size.offsets;

  const plot_data = {
    width: width ?? computed_size.width,
    height: height ?? computed_size.height,
  };

  return {
    width: (width ?? computed_size.width) + offsets.width,
    height: (height ?? computed_size.height) + offsets.height,
    noChange: width == computed_size.width && height == computed_size.height,
  }
}

// This function will change the container size so that the resulting plot will be matching the provided specs
function changeContainerSize({ width, height }, sizeData = getSizeData()) {
  if (!CONTAINER.isPoppedOut()) {
    console.log("Tried to change container size when not popped, ignoring");
    return;
  }

  const csz = computeContainerSize({ width, height }, sizeData);

  if (csz.noChange) {
    console.log("Size is the same as current, ignoring");
    return
  }
  // We are now going to set he width and height of the container
  for (const key of ["width", "height"]) {
    CONTAINER.style[key] = csz[key] + "px";
  }
}
// We now create the function that will update the plot based on the values specified
function updateFromHeader() {
  const header_data = {
    height: config_spans.height.ui_value,
    width: config_spans.width.ui_value,
  };
  changeContainerSize(header_data);
}
// We assign this function to the onblur event of width and height
if (firstRun) {
  for (const container of Object.values(config_spans)) {
    container.ui_span.onblur = (e) => {
      container.ui_value = container.ui_span.textContent;
      updateFromHeader();
    };
  }
}
// This function computes the plot size to use for relayout as a function of the container size
function computePlotSize(data = getSizeData()) {
  // Remove Padding
  const { container_pad, plot_pad, container_rect } = data;
  const offsets = {
    width:
      plot_pad.padding.width +
      plot_pad.border.width +
      plot_pad.offset.left +
      container_pad.padding.width +
      container_pad.border.width,
    height:
      plot_pad.padding.height +
      plot_pad.border.height +
      plot_pad.offset.top +
      container_pad.padding.height +
      container_pad.border.height,
  };
  const sz = {
    width: Math.round(container_rect.width - offsets.width),
    height: Math.round(container_rect.height - offsets.height),
    offsets,
  };
  return sz;
}

// Create the resizeObserver to make the plot even more responsive! :magic:
const resizeObserver = new ResizeObserver((entries) => {
  const sizeData = getSizeData();
  const {container_rect, container_pad} = sizeData;
  let plot_size = computePlotSize(sizeData);
  // We save the height in the PLOT object
  PLOT.container_height = container_rect.height;
  // We deal with some stuff if the container is poppped
  CLIPBOARD_HEADER.style.width = container_rect.width + "px";
  CLIPBOARD_HEADER.style.left = container_rect.left + "px";
  config_spans.height.ui_value = plot_size.height;
  config_spans.width.ui_value = plot_size.width;
  /* 
		The addition of the invalid argument `plutoresize` seems to fix the problem with calling `relayout` simply with `{autosize: true}` as update breaking mouse relayout events tracking. 
		See https://github.com/plotly/plotly.js/issues/6156 for details
		*/
  let config = {
    // If this is popped out, we ignore the original width/height
    width: (CONTAINER.isPoppedOut() ? undefined : original_width) ?? plot_size.width,
    height: (CONTAINER.isPoppedOut() ? undefined : original_height) ?? plot_size.height,
    plutoresize: true,
  };
  Plotly.relayout(PLOT, config).then(() => {
    if (remove_container_size && !CONTAINER.isPoppedOut()) {
      // This is needed to avoid the first resize upon plot creation to already be without a fixed height
      CONTAINER.style.height = "";
      CONTAINER.style.width = "";
      remove_container_size = false;
    }
  });
});

resizeObserver.observe(CONTAINER);


Plotly.react(PLOT, plot_obj).then(() => {
	// Assign the Plotly event listeners
	for (const [key, listener_vec] of Object.entries(plotly_listeners)) {
		for (const listener of listener_vec) {
			PLOT.on(key, listener)
		}
	}
	// Assign the JS event listeners
	for (const [key, listener_vec] of Object.entries(js_listeners)) {
		for (const listener of listener_vec) {
			PLOT.addEventListener(key, listener, {
				signal: controller.signal
			})
		}
	}
}
)


invalidation.then(() => {
	// Remove all plotly listeners
	PLOT.removeAllListeners()
	// Remove all JS listeners
	controller.abort()
	// Remove the resizeObserver
	resizeObserver.disconnect()
})



		return CONTAINER
	</script>
</p>
</div>mimetext/htmlrootassigneelast_run_timestampA2OHpersist_js_state·has_pluto_hook_features§cell_id$11f8290f-f589-49ff-9602-99ccc4192884depends_on_disabled_cells§runtimeSpublished_object_keys5c6e0de0c-3901-11f0-234e-bd09c571f662/8b2f6661ab801d2cdepends_on_skipped_cells§errored$7fb4244c-828a-49d6-a15b-178fa3a42e00queued¤logsrunning¦outputbodyٿ2×200 Matrix{Float32}:
 1.0  1.0  1.0  1.0  1.0  1.0  1.0  1.0  …  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0     1.0  1.0  1.0  1.0  1.0  1.0  1.0  1.0mimetext/plainrootassigneeconst π_blackjack1last_run_timestampA%h
persist_js_state·has_pluto_hook_features§cell_id$7fb4244c-828a-49d6-a15b-178fa3a42e00depends_on_disabled_cells§runtimeɧ	published_object_keysdepends_on_skipped_cells§errored$0609ad22-0adc-4e4f-afed-b7a46d216576queued¤logsrunning¦outputbodym<div class="markdown"><p>Statistics for Steps to Finish Race on Track 1</p>

<table><tr><th align="right">Statistic</th><th align="right"><div class="markdown"><p>Monte Carlo Exploring Starts</p>
</div></th><th align="right">Random Policy</th></tr><tr><td align="right">Mean</td><td align="right">66</td><td align="right">2397</td></tr><tr><td align="right">Median</td><td align="right">48</td><td align="right">1754</td></tr><tr><td align="right">Std</td><td align="right">56</td><td align="right">2118</td></tr><tr><td align="right">Minimum</td><td align="right">14</td><td align="right">17</td></tr><tr><td align="right">Maximum</td><td align="right">372</td><td align="right">9985</td></tr></table>
<p>Cummulative Distribution Function of Steps to Finish Race 	<script id='plot_1'>
		// We start by putting all the variable interpolation here at the beginning
		// We have to convert all typedarrays in the layout to normal arrays. See Issue #25
		// We use lodash for this for compactness
		function removeTypedArray(o) {
			return _.isTypedArray(o) ? Array.from(o) :
			_.isPlainObject(o) ? _.mapValues(o, removeTypedArray) : 
			o
		}

		// Publish the plot object to JS
		let plot_obj = _.update(/* See the documentation for AbstractPlutoDingetjes.Display.published_to_js */ getPublishedObject("c6e0de0c-3901-11f0-234e-bd09c571f662/b6b6df0af3e3a8ae"), "layout", removeTypedArray)
		// Get the plotly listeners
		const plotly_listeners = {}
		// Get the JS listeners
		const js_listeners = {}
		// Deal with eventual custom classes
		let custom_classlist = []


		// Load the plotly library
		let Plotly = undefined
		try {
			let _mod = await import("./plotlyjs/plotlyjs-2.26.2.min.js")
			Plotly = _mod.default
		} catch (e) {
			console.log("Local load failed, trying with the web esm.sh version")
			let _mod = await import("https://esm.sh/plotly.js-dist-min@2.26.2/es2022/plotly.js-dist-min.mjs")
			Plotly = _mod.default
		}

		// Check if we have to force local mathjax font cache
		if (false && window?.MathJax?.config?.svg?.fontCache === 'global') {
			window.MathJax.config.svg.fontCache = 'local'
		}

		// Flag to check if this cell was  manually ran or reactively ran
const firstRun = this ? false : true
const CONTAINER = this ?? html`<div class='plutoplotly-container'>`
const PLOT = CONTAINER.querySelector('.js-plotly-plot') ?? CONTAINER.appendChild(html`<div>`)
const parent = CONTAINER.parentElement
// We use a controller to remove event listeners upon invalidation
const controller = new AbortController()
// We have to add this to keep supporting @bind with the old API using PLOT
PLOT.addEventListener('input', (e) => {
	CONTAINER.value = PLOT.value
	if (e.bubbles) {
		return
	}
	CONTAINER.dispatchEvent(new CustomEvent('input'))
}, { signal: controller.signal })

	// This create the style subdiv on first run
	firstRun && CONTAINER.appendChild(html`
	<style>
	.plutoplotly-container {
		width: 100%;
		height: 100%;
		min-height: 0;
		min-width: 0;
	}
	.plutoplotly-container .js-plotly-plot .plotly div {
		margin: 0 auto; // This centers the plot
	}
	.plutoplotly-container.popped-out {
		overflow: auto;
		z-index: 1000;
		position: fixed;
		resize: both;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		border-top-left-radius: 0px;
		border-top-right-radius: 0px;
	}
	.plutoplotly-clipboard-header {
		display: flex;
		flex-flow: row wrap;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-top-left-radius: 12px;
		border-top-right-radius: 12px;
		position: fixed;
		z-index: 1001;
		cursor: move;
		transform: translate(0px, -100%);
		padding: 5px;
	}
	.plutoplotly-clipboard-header span {
		display: inline-block;
		flex: 1
	}
	.plutoplotly-clipboard-header.hidden {
		display: none;
	}
	.clipboard-span {
		position: relative;
	}
	.clipboard-value {
		padding-right: 5px;
		padding-left: 2px;
		cursor: text;
	}
	.clipboard-span.format {
		display: none;
	}
	.clipboard-span.filename {
		flex: 0 0 100%;
		text-align: center;
		border-top: 3px solid var(--kbd-border-color);
		margin-top: 5px;
		display: none;
	}
	.plutoplotly-container.filesave .clipboard-span.filename {
		display: inline-block;
	}
	.clipboard-value.filename {
		margin-left: 3px;
		text-align: left;
		min-width: min(60%, min-content);
	}
	.plutoplotly-container.filesave .clipboard-span.format {
		display: inline-flex;
	}
	.clipboard-span.format .label {
		flex: 0 0 0;
	}
	.clipboard-value.format {
		position: relative;
		flex: 1 0 auto;
		min-width: 30px;
		margin-right: 10px;
	}
	div.format-options {
		display: inline-flex;
		flex-flow: column;
		position: absolute;
		background: var(--main-bg-color);
		border-radius: 12px;
		padding-left: 3px;
		z-index: 2000;
	}
	div.format-options:hover {
		cursor: pointer;
		border: 3px solid var(--kbd-border-color);
		padding: 3px;
		transform: translate(-3px, -6px);
	}
	div.format-options .format-option {
		display: none;
	}
	div.format-options:hover .format-option {
		display: inline-block;
	}
	.format-option:not(.selected) {
		margin-top: 3px;
	}
	div.format-options .format-option.selected {
		order: -1;
		display: inline-block;
	}
	.format-option:hover {
		background-color: var(--kbd-border-color);
	}
	span.config-value {
		font-weight: normal;
		color: var(--pluto-output-color);
		display: none;
		position: absolute;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		transform: translate(0px, calc(-100% - 10px));
		padding: 5px;
	}
	.label {
		user-select: none;
	}
	.label:hover span.config-value {
		display: inline-block;
		min-width: 150px;
	}
	.clipboard-span.matching-config .label {
		color: var(--cm-macro-color);
		font-weight: bold;
	}
	.clipboard-span.different-config .label {
		color: var(--cm-tag-color);
		font-weight: bold;
	}
</style>
`)

let original_height = plot_obj.layout.height
let original_width = plot_obj.layout.width
// For the height we have to also put a fixed value in case the plot is put on a non-fixed-size container (like the default wrapper)
// We define a variable to check whether we still have to remove the fixed height
let remove_container_size = firstRun
let container_height = original_height ?? PLOT.container_height ?? 400
CONTAINER.style.height = container_height + 'px'

// We create a Promise version of setTimeout
function delay(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

// We import interact for dragging/resizing
const { default: interact } = await import('https://esm.sh/interactjs@1.10.19')


function getImageOptions() {
  const o = plot_obj.config.toImageButtonOptions ?? {};
  return {
    format: o.format ?? "png",
    width: o.width ?? original_width,
    height: o.height ?? original_height,
    scale: o.scale ?? 1,
    filename: o.filename ?? "newplot",
  };
}

const CLIPBOARD_HEADER =
  CONTAINER.querySelector(".plutoplotly-clipboard-header") ??
  CONTAINER.insertAdjacentElement(
    "afterbegin",
    html`<div class="plutoplotly-clipboard-header hidden">
      <span class="clipboard-span format"
        ><span class="label">Format:</span
        ><span class="clipboard-value format"></span
      ></span>
      <span class="clipboard-span width"
        ><span class="label">Width:</span
        ><span class="clipboard-value width"></span>px</span
      >
      <span class="clipboard-span height"
        ><span class="label">Height:</span
        ><span class="clipboard-value height"></span>px</span
      >
      <span class="clipboard-span scale"
        ><span class="label">Scale:</span
        ><span class="clipboard-value scale"></span
      ></span>
      <button class="clipboard-span set">Set</button>
      <button class="clipboard-span unset">Unset</button>
      <span class="clipboard-span filename"
        ><span class="label">Filename:</span
        ><span class="clipboard-value filename"></span
      ></span>
    </div>`
  );

function checkConfigSync(container) {
  const valid_classes = [
    "missing-config",
    "matching-config",
    "different-config",
  ];
  function setClass(cl) {
    for (const name of valid_classes) {
      container.classList.toggle(name, name == cl);
    }
  }
  // We use the custom getters we'll set up in the container
  const { ui_value, config_value, config_span, key } = container;
  if (config_value === undefined) {
    setClass("missing-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> is not present in the config.`;
  } else if (ui_value == config_value) {
    setClass("matching-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has the same value in the config and in the header.`;
  } else {
    setClass("different-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has a different value (<em>${config_value}</em>) in the config.`;
  }
  // Add info about setting and unsetting
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click on the label <em><b>once</b></em> to set the current UI value in the config.`
  );
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click <em><b>twice</b></em> to remove this key from the config.`
  );
}

const valid_formats = ["png", "svg", "webp", "jpeg", "full-json"];
function initializeUIValueSpan(span, key, value) {
  const container = span.closest(".clipboard-span");
  span.contentEditable = key === "format" ? "false" : "true";
  let parse = (x) => x;
  let update = (x) => (span.textContent = x);
  if (key === "width" || key === "height") {
    parse = (x) => Math.round(parseFloat(x));
  } else if (key === "scale") {
    parse = parseFloat;
  } else if (key === "format") {
    // We remove contentEditable
    span.contentEditable = "false";
    // Here we first add the subspans for each option
    const opts_div = span.appendChild(html`<div class="format-options"></div>`);
    for (const fmt of valid_formats) {
      const opt = opts_div.appendChild(
        html`<span class="format-option ${fmt}">${fmt}</span>`
      );
      opt.onclick = (e) => {
        span.value = opt.textContent;
      };
    }
    parse = (x) => {
      return valid_formats.includes(x) ? x : localValue;
    };
    update = (x) => {
      for (const opt of opts_div.children) {
        opt.classList.toggle("selected", opt.textContent === x);
      }
    };
  } else {
    // We only have filename here
  }
  let localValue;
  Object.defineProperty(span, "value", {
    get: () => {
      return localValue;
    },
    set: (val) => {
      if (val !== "") {
        localValue = parse(val);
      }
      update(localValue);
      checkConfigSync(container);
    },
  });
  // We also assign a listener so that the editable is blurred when enter is pressed
  span.onkeydown = (e) => {
    if (e.keyCode === 13) {
      e.preventDefault();
      span.blur();
    }
  };
  span.value = value;
}

function initializeConfigValueSpan(span, key) {
  // Here we mostly want to define the setter and getter
  const container = span.closest(".clipboard-span");
  Object.defineProperty(span, "value", {
    get: () => {
      return plot_obj.config.toImageButtonOptions[key];
    },
    set: (val) => {
      // if undefined is passed, we remove the entry from the options
      if (val === undefined) {
        delete plot_obj.config.toImageButtonOptions[key];
      } else {
        plot_obj.config.toImageButtonOptions[key] = val;
      }
      checkConfigSync(container);
    },
  });
}

const config_spans = {};
for (const [key, value] of Object.entries(getImageOptions())) {
  const container = CLIPBOARD_HEADER.querySelector(`.clipboard-span.${key}`);
  const label = container.querySelector(".label");
  // We give the label a function that on single click will set the current value and with double click will unset it
  label.onclick = DualClick(
    () => {
      container.config_value = container.ui_value;
    },
    (e) => {
      console.log("e", e);
      e.preventDefault();
      container.config_value = undefined;
    }
  );
  const ui_value_span = container.querySelector(".clipboard-value");
  const config_value_span =
    container.querySelector(".config-value") ??
    label.insertAdjacentElement(
      "afterbegin",
      html`<span class="config-value"></span>`
    );
  // Assing the two spans as properties of the containing span
  container.ui_span = ui_value_span;
  container.config_span = config_value_span;
  container.key = key;
  config_spans[key] = container;
  if (firstRun) {
    plot_obj.config.toImageButtonOptions =
      plot_obj.config.toImageButtonOptions ?? {};
    // We do the initialization of the value span
    initializeUIValueSpan(ui_value_span, key, value);
    // Then we initialize the config value
    initializeConfigValueSpan(config_value_span, key);
    // We put some convenience getters/setters
    // ui_value forward
    Object.defineProperty(container, "ui_value", {
      get: () => ui_value_span.value,
      set: (val) => {
        ui_value_span.value = val;
      },
    });
    // config_value forward
    Object.defineProperty(container, "config_value", {
      get: () => config_value_span.value,
      set: (val) => {
        config_value_span.value = val;
      },
    });
  }
}

// These objects will contain the default value

// This code updates the image options in the PLOT config with the provided ones
function setImageOptions(o) {
  for (const [key, container] of Object.entries(config_spans)) {
    container.config_value = o[key];
  }
}
function unsetImageOptions() {
  setImageOptions({});
}

const set_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.set");
const unset_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.unset");
if (firstRun) {
  set_button.onclick = (e) => {
    for (const container of Object.values(config_spans)) {
      container.config_value = container.ui_value;
    }
  };
  unset_button.onclick = unsetImageOptions;
}

// We add a function to check if the clipboard is popped out
CONTAINER.isPoppedOut = () => {
  return CONTAINER.classList.contains("popped-out");
};

CLIPBOARD_HEADER.onmousedown = function (event) {
  if (event.target.matches("span.clipboard-value")) {
    console.log("We don't move!");
    return;
  }
  const start = {
    left: parseFloat(CONTAINER.style.left),
    top: parseFloat(CONTAINER.style.top),
    X: event.pageX,
    Y: event.pageY,
  };
  function moveAt(event, start) {
    const top = event.pageY - start.Y + start.top + "px";
    const left = event.pageX - start.X + start.left + "px";
    CLIPBOARD_HEADER.style.left = left;
    CONTAINER.style.left = left;
    CONTAINER.style.top = top;
  }

  // move our absolutely positioned ball under the pointer
  moveAt(event, start);
  function onMouseMove(event) {
    moveAt(event, start);
  }

  // We use this to remove the mousemove when clicking outside of the container
  const controller = new AbortController();

  // move the container on mousemove
  document.addEventListener("mousemove", onMouseMove, {
    signal: controller.signal,
  });
  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        cleanUp();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );

  function cleanUp() {
    console.log("cleaning up the plot move listener");
    controller.abort();
    CLIPBOARD_HEADER.onmouseup = null;
  }

  // (3) drop the ball, remove unneeded handlers
  CLIPBOARD_HEADER.onmouseup = cleanUp;
};

function sendToClipboard(blob) {
  if (!navigator.clipboard) {
    alert(
      "The Clipboard API does not seem to be available, make sure the Pluto notebook is being used from either localhost or an https source."
    );
  }
  navigator.clipboard
    .write([
      new ClipboardItem({
        // The key is determined dynamically based on the blob's type.
        [blob.type]: blob,
      }),
    ])
    .then(
      function () {
        console.log("Async: Copying to clipboard was successful!");
      },
      function (err) {
        console.error("Async: Could not copy text: ", err);
      }
    );
}

function copyImageToClipboard() {
  // We extract the image options from the provided parameters (if they exist)
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key. We also ignore format because the clipboard only supports png.
    if (val === undefined || key === "format") {
      continue;
    }
    config[key] = val;
  }
  Plotly.toImage(PLOT, config).then(function (dataUrl) {
    fetch(dataUrl)
      .then((res) => res.blob())
      .then((blob) => {
        const paste_receiver = document.querySelector('paste-receiver.plutoplotly')
        if (paste_receiver) {
          paste_receiver.attachImage(dataUrl, CONTAINER)
        }
        sendToClipboard(blob)
      });
  });
}

function saveImageToFile() {
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key.
    if (val === undefined) {
      continue;
    }
    config[key] = val;
  }
  Plotly.downloadImage(PLOT, config);
}

let container_rect = { width: 0, height: 0, top: 0, left: 0 };
function unpop_container(cl) {
  CONTAINER.classList.toggle("popped-out", false);
  CONTAINER.classList.toggle(cl, false);
  // We fix the height back to the value it had before popout, also setting the flag to signal that upon first resize we remove the fixed inline-style
  CONTAINER.style.height = container_rect.height + "px";
  remove_container_size = true;
  // We set the other fixed inline-styles to null
  CONTAINER.style.width = "";
  CONTAINER.style.top = "";
  CONTAINER.style.left = "";
  // We also remove the CLIPBOARD_HEADER
  CLIPBOARD_HEADER.style.width = "";
  CLIPBOARD_HEADER.style.left = "";
  // Finally we remove the hidden class to the header
  CLIPBOARD_HEADER.classList.toggle("hidden", true);
  return;
}
function popout_container(opts) {
  const cl = opts?.cl;
  const target_container_size = opts?.target_container_size ?? {};
  const target_plot_size = opts?.target_plot_size ?? {};
  if (CONTAINER.isPoppedOut()) {
    return unpop_container(cl);
  }
  CONTAINER.classList.toggle(cl, cl === undefined ? false : true);
  // We extract the current size of the container, save them and fix them
  const { width, height, top, left } = CONTAINER.getBoundingClientRect();
  container_rect = { width, height, top, left };
  // We save the current plot size before we pop as it will fill the screen
  const current_plot_size = {
    width: PLOT._fullLayout.width,
    height: PLOT._fullLayout.height,
  };
  // We have to save the pad data before popping so we can resize precisely
  const pad = {};
  pad.unpopped = getSizeData().container_pad;
  CONTAINER.classList.toggle("popped-out", true);
  pad.popped = getSizeData().container_pad;
  // We do top and left based on the current rect
  for (const key of ["top", "left"]) {
    const start_val = target_container_size[key] ?? container_rect[key];
    let offset = 0;
    for (const kind of ["padding", "border"]) {
      offset += pad.popped[kind][key] - pad.unpopped[kind][key];
    }
    CONTAINER.style[key] = start_val - offset + "px";
    if (key === "left") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  // We compute the width and height depending on eventual config data
  const csz = computeContainerSize({
    width:
      target_plot_size.width ??
      config_spans.width.config_value ??
      current_plot_size.width,
    height:
      target_plot_size.height ??
      config_spans.height.config_value ??
      current_plot_size.height,
  });
  for (const key of ["width", "height"]) {
    const val = target_container_size[key] ?? csz[key];
    CONTAINER.style[key] = val + "px";
    if (key === "width") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  CLIPBOARD_HEADER.classList.toggle("hidden", false);
  const controller = new AbortController();

  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        unpop_container();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );
}

CONTAINER.popOut = popout_container;

function DualClick(single_func, dbl_func) {
  let nclicks = 0;
  return function (...args) {
    nclicks += 1;
    if (nclicks > 1) {
      dbl_func(...args);
      nclicks = 0;
    } else {
      delay(300).then(() => {
        if (nclicks == 1) {
          single_func(...args);
        }
        nclicks = 0;
      });
    }
  };
}

// We remove the default download image button
plot_obj.config.modeBarButtonsToRemove = _.union(
  plot_obj.config.modeBarButtonsToRemove,
  ["toImage"]
);
// We add the custom button to the modebar
plot_obj.config.modeBarButtonsToAdd = _.union(
  plot_obj.config.modeBarButtonsToAdd,
  [
    {
      name: "Copy PNG to Clipboard",
      icon: {
        height: 520,
        width: 520,
        path: "M280 64h40c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128C0 92.7 28.7 64 64 64h40 9.6C121 27.5 153.3 0 192 0s71 27.5 78.4 64H280zM64 112c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16H320c8.8 0 16-7.2 16-16V128c0-8.8-7.2-16-16-16H304v24c0 13.3-10.7 24-24 24H192 104c-13.3 0-24-10.7-24-24V112H64zm128-8a24 24 0 1 0 0-48 24 24 0 1 0 0 48z",
      },
      direction: "up",
      click: DualClick(copyImageToClipboard, () => {
        popout_container();
      }),
    },
    {
      name: "Download Image",
      icon: Plotly.Icons.camera,
      direction: "up",
      click: DualClick(saveImageToFile, () => {
        popout_container({ cl: "filesave" });
      }),
    },
  ]
);

function getOffsetData(el) {
  let cs = window.getComputedStyle(el, null);
  const odata = {
    padding: {
      left: parseFloat(cs.paddingLeft),
      right: parseFloat(cs.paddingRight),
      top: parseFloat(cs.paddingTop),
      bottom: parseFloat(cs.paddingBottom),
      width: parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight),
      height: parseFloat(cs.paddingTop) + parseFloat(cs.paddingBottom),
    },
    border: {
      left: parseFloat(cs.borderLeftWidth),
      right: parseFloat(cs.borderRightWidth),
      top: parseFloat(cs.borderTopWidth),
      bottom: parseFloat(cs.borderBottomWidth),
      width: parseFloat(cs.borderLeftWidth) + parseFloat(cs.borderRightWidth),
      height: parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth),
    }
  };
  if (el === PLOT) {
    // For the PLOT we also want to take into account the offset
    odata.offset = {
      top: PLOT.offsetParent == CONTAINER ? PLOT.offsetTop : 0,
      left: PLOT.offsetParent == CONTAINER ? PLOT.offsetLeft : 0,
    }
  }
  return odata;
}
function getSizeData() {
  const data = {
    plot_pad: getOffsetData(PLOT),
    plot_rect: PLOT.getBoundingClientRect(),
    container_pad: getOffsetData(CONTAINER),
    container_rect: CONTAINER.getBoundingClientRect(),
  };
  return data;
}
function computeContainerSize({ width, height }, sizeData = getSizeData()) {
  const computed_size = computePlotSize(sizeData);
  const offsets = computed_size.offsets;

  const plot_data = {
    width: width ?? computed_size.width,
    height: height ?? computed_size.height,
  };

  return {
    width: (width ?? computed_size.width) + offsets.width,
    height: (height ?? computed_size.height) + offsets.height,
    noChange: width == computed_size.width && height == computed_size.height,
  }
}

// This function will change the container size so that the resulting plot will be matching the provided specs
function changeContainerSize({ width, height }, sizeData = getSizeData()) {
  if (!CONTAINER.isPoppedOut()) {
    console.log("Tried to change container size when not popped, ignoring");
    return;
  }

  const csz = computeContainerSize({ width, height }, sizeData);

  if (csz.noChange) {
    console.log("Size is the same as current, ignoring");
    return
  }
  // We are now going to set he width and height of the container
  for (const key of ["width", "height"]) {
    CONTAINER.style[key] = csz[key] + "px";
  }
}
// We now create the function that will update the plot based on the values specified
function updateFromHeader() {
  const header_data = {
    height: config_spans.height.ui_value,
    width: config_spans.width.ui_value,
  };
  changeContainerSize(header_data);
}
// We assign this function to the onblur event of width and height
if (firstRun) {
  for (const container of Object.values(config_spans)) {
    container.ui_span.onblur = (e) => {
      container.ui_value = container.ui_span.textContent;
      updateFromHeader();
    };
  }
}
// This function computes the plot size to use for relayout as a function of the container size
function computePlotSize(data = getSizeData()) {
  // Remove Padding
  const { container_pad, plot_pad, container_rect } = data;
  const offsets = {
    width:
      plot_pad.padding.width +
      plot_pad.border.width +
      plot_pad.offset.left +
      container_pad.padding.width +
      container_pad.border.width,
    height:
      plot_pad.padding.height +
      plot_pad.border.height +
      plot_pad.offset.top +
      container_pad.padding.height +
      container_pad.border.height,
  };
  const sz = {
    width: Math.round(container_rect.width - offsets.width),
    height: Math.round(container_rect.height - offsets.height),
    offsets,
  };
  return sz;
}

// Create the resizeObserver to make the plot even more responsive! :magic:
const resizeObserver = new ResizeObserver((entries) => {
  const sizeData = getSizeData();
  const {container_rect, container_pad} = sizeData;
  let plot_size = computePlotSize(sizeData);
  // We save the height in the PLOT object
  PLOT.container_height = container_rect.height;
  // We deal with some stuff if the container is poppped
  CLIPBOARD_HEADER.style.width = container_rect.width + "px";
  CLIPBOARD_HEADER.style.left = container_rect.left + "px";
  config_spans.height.ui_value = plot_size.height;
  config_spans.width.ui_value = plot_size.width;
  /* 
		The addition of the invalid argument `plutoresize` seems to fix the problem with calling `relayout` simply with `{autosize: true}` as update breaking mouse relayout events tracking. 
		See https://github.com/plotly/plotly.js/issues/6156 for details
		*/
  let config = {
    // If this is popped out, we ignore the original width/height
    width: (CONTAINER.isPoppedOut() ? undefined : original_width) ?? plot_size.width,
    height: (CONTAINER.isPoppedOut() ? undefined : original_height) ?? plot_size.height,
    plutoresize: true,
  };
  Plotly.relayout(PLOT, config).then(() => {
    if (remove_container_size && !CONTAINER.isPoppedOut()) {
      // This is needed to avoid the first resize upon plot creation to already be without a fixed height
      CONTAINER.style.height = "";
      CONTAINER.style.width = "";
      remove_container_size = false;
    }
  });
});

resizeObserver.observe(CONTAINER);


Plotly.react(PLOT, plot_obj).then(() => {
	// Assign the Plotly event listeners
	for (const [key, listener_vec] of Object.entries(plotly_listeners)) {
		for (const listener of listener_vec) {
			PLOT.on(key, listener)
		}
	}
	// Assign the JS event listeners
	for (const [key, listener_vec] of Object.entries(js_listeners)) {
		for (const listener of listener_vec) {
			PLOT.addEventListener(key, listener, {
				signal: controller.signal
			})
		}
	}
}
)


invalidation.then(() => {
	// Remove all plotly listeners
	PLOT.removeAllListeners()
	// Remove all JS listeners
	controller.abort()
	// Remove the resizeObserver
	resizeObserver.disconnect()
})



		return CONTAINER
	</script>
</p>
</div>mimetext/htmlrootassigneelast_run_timestampA3!persist_js_state·has_pluto_hook_features§cell_id$0609ad22-0adc-4e4f-afed-b7a46d216576depends_on_disabled_cells§runtimeX6$published_object_keys5c6e0de0c-3901-11f0-234e-bd09c571f662/b6b6df0af3e3a8aedepends_on_skipped_cells§errored$61eb74eb-88e0-42e6-a14b-3730a800694dqueued¤logsrunning¦outputbody2×1 Matrix{Float32}:
 1.0
 0.0mimetext/plainrootassigneeconst onestate_π_targetlast_run_timestampA,ǰpersist_js_state·has_pluto_hook_features§cell_id$61eb74eb-88e0-42e6-a14b-3730a800694ddepends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cells§errored$6a96304b-add3-4135-8ccf-46cc23859d53queued¤logsrunning¦outputbodyN<div class="markdown"><h4>Off-policy MC Control Racetrack Solution</h4>
</div>mimetext/htmlrootassigneelast_run_timestampA"*wѰpersist_js_state·has_pluto_hook_features§cell_id$6a96304b-add3-4135-8ccf-46cc23859d53depends_on_disabled_cells§runtime 鲵published_object_keysdepends_on_skipped_cells§errored$c883748c-76b9-4086-8698-b40df51390daqueued¤logsrunning¦outputbody'<div class="markdown"><blockquote>
<h3><em>Exercise 5.4</em></h3>
<p>The pseudocode for Monte Carlo ES is inefficient because, for each state-action pair, it maintains a list of all returns and repeatedly calculates their mean.  It would be more dfficient to use techniques similar to those explained in Section 2.4 to maintain just the mean and a count &#40;for each state-action pair&#41; and update them incrementally.  Describe how the pseudocode would be altered to achieve this.</p>
</blockquote>
<p>Returns&#40;s,a&#41; will not maintain a list but instead be a list of single values for each state-action pair.  Additionally, another list Counts&#40;s,a&#41; should be initialized at 0 for each pair.  When new G values are obtained for state-action pairs, the Count&#40;s,a&#41; value should be incremented by 1.  Then Returns&#40;s,a&#41; can be updated with the following formula: </p>
<p class="tex">$$\text&#123;Returns&#125;&#40;s,a&#41; &#61; \frac&#123;\text&#123;Returns&#125;&#40;s,a&#41; \times &#40;\text&#123;Count&#125;&#40;s,a&#41; - 1&#41; &#43; G&#40;s,a&#41;&#125;&#123;\text&#123;Count&#125;&#40;s,a&#41;&#125; &#61; \text&#123;Returns&#125;&#40;s,a&#41; &#43; \frac&#123;G&#40;s,a&#41; - \text&#123;Returns&#125;&#40;s,a&#41;&#125;&#123;\text&#123;Count&#125;&#40;s,a&#41;&#125;$$</p>
</div>mimetext/htmlrootassigneelast_run_timestampA"')persist_js_state·has_pluto_hook_features§cell_id$c883748c-76b9-4086-8698-b40df51390dadepends_on_disabled_cells§runtime 'published_object_keysdepends_on_skipped_cells§errored$f071b7e2-3f78-4132-8b84-f810f178c89dqueued¤logsrunning¦outputbodyprefixNMDP_Opaque{OneState, OneStateAction, typeof(one_state_simulator), var"#48#49"}elementsstatesprefixMain.var"workspace#3".OneStateelementsprefixOneStateelementstypestructprefix_shortOneStateobjectidffffffff38bdf29f!application/vnd.pluto.tree+objecttypeArrayprefix_shortobjectidf894cef2b5e927e6!application/vnd.pluto.tree+objectstatelookupprefix+Dict{Main.var"workspace#3".OneState, Int64}elementsprefixOneStateelementstypestructprefix_shortOneStateobjectidffffffff38bdf29f!application/vnd.pluto.tree+object1text/plaintypeDictprefix_shortDictobjectid62a6db26cb4a56b2!application/vnd.pluto.tree+objectactionsprefix$Main.var"workspace#3".OneStateActionelementsprefixLeftelementstypestructprefix_shortLeftobjectidffffffff5e48f957!application/vnd.pluto.tree+objectprefixRightelementstypestructprefix_shortRightobjectidffffffff2428617a!application/vnd.pluto.tree+objecttypeArrayprefix_shortobjectid6ea419802207c1a3!application/vnd.pluto.tree+objectactionlookupprefix1Dict{Main.var"workspace#3".OneStateAction, Int64}elementsprefixLeftelementstypestructprefix_shortLeftobjectidffffffff5e48f957!application/vnd.pluto.tree+object1text/plainprefixRightelementstypestructprefix_shortRightobjectidffffffff2428617a!application/vnd.pluto.tree+object2text/plaintypeDictprefix_shortDictobjectid86f98bf29f7f50c5!application/vnd.pluto.tree+objectstate_init$#48 (generic function with 1 method)text/plainsimulator4one_state_simulator (generic function with 1 method)text/plaintypestructprefix_shortMDP_Opaqueobjectida8df05bb1d73c880mime!application/vnd.pluto.tree+objectrootassigneelast_run_timestampA,:persist_js_state·has_pluto_hook_features§cell_id$f071b7e2-3f78-4132-8b84-f810f178c89ddepends_on_disabled_cells§runtimeVpublished_object_keysdepends_on_skipped_cells§errored$8d7b9826-b52c-4d5a-8c63-e83a1229a0bequeued¤logsrunning¦outputbodyk<div class="markdown"><p>Example trajectories after training for 1000 episodes with ϵ&#61; 0.01</p>
</div>mimetext/htmlrootassigneelast_run_timestampA3persist_js_state·has_pluto_hook_features§cell_id$8d7b9826-b52c-4d5a-8c63-e83a1229a0bedepends_on_disabled_cells§runtime ,published_object_keysdepends_on_skipped_cells§errored$67e535c7-437a-49ba-b5ab-9dfe63fe4aaaqueued¤logsrunning¦outputbodyA<div class="markdown"><h4>Racetrack Environment Setup</h4>
</div>mimetext/htmlrootassigneelast_run_timestampA")gpersist_js_state·has_pluto_hook_features§cell_id$67e535c7-437a-49ba-b5ab-9dfe63fe4aaadepends_on_disabled_cells§runtime ꣵpublished_object_keysdepends_on_skipped_cells§errored$c8f3f7e3-be7e-4615-a667-d9f789928883queued¤logsrunning¦outputbody,updatevalue (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA)`ðpersist_js_state·has_pluto_hook_features§cell_id$c8f3f7e3-be7e-4615-a667-d9f789928883depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$30809344-b4ab-468b-b4b7-5ef3dca5ffc7queued¤logsrunning¦outputbody<div class="markdown"><blockquote>
<h3><em>Exercise 5.2</em></h3>
<p>Suppose every-visit MC was used instead of first-visit MC on the blackjack task.  Would you expect the results to be very different?  Why or why not?</p>
</blockquote>
<p>As an episode proceeds in blackjack the states will not repeat since every time a card is dealt the player sum changes, or the usable Ace flag changes.  Thus the check ensuring that only the first visit to a state is counted in the return average will have no effect on the MC evaluation.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA"&'persist_js_state·has_pluto_hook_features§cell_id$30809344-b4ab-468b-b4b7-5ef3dca5ffc7depends_on_disabled_cells§runtime upublished_object_keysdepends_on_skipped_cells§errored$e2a720b0-a8c4-43a2-bf34-750ff3323004queued¤logsrunning¦outputbody<div class="markdown"><h2>5.4 Monte Carlo Control without Exploring Starts</h2>
<p>To only way to ensure all state-action pairs are visited without exploring starts is to use a policy with a non-zero probability of visiting all such states.  One policy that meets this criterion is an <em>ϵ-soft</em> policy meaning that <span class="tex">$\pi&#40;a \vert s&#41; &gt; 0 \: \forall \: s \in \mathcal&#123;S&#125;$</span>.  To achieve this with Monte Carlo Control, we simply update the policy to be <span class="tex">$\epsilon$</span>-greedy for every Q update, so the maximizing &#40;greedy&#41; action is given a probability <span class="tex">$1 - \epsilon &#43; \frac&#123;\epsilon&#125;&#123;\vert \mathcal&#123;A&#125;&#40;s&#41; \vert&#125;$</span> and all other actions are given the probability <span class="tex">$\frac&#123;\epsilon&#125;&#123;\vert \mathcal&#123;A&#125;&#40;s&#41; \vert&#125;$</span>.</p>
<p>Below is code implementing MC control for ϵ-soft policies.  It is mostly identical to the every visit method except the policy is always used to select the initial action and the policy update uses an ϵ-greedy update rather than a greedy one.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA"'Mpersist_js_state·has_pluto_hook_features§cell_id$e2a720b0-a8c4-43a2-bf34-750ff3323004depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$1067fcc4-cbc6-453c-a996-d420c498619aqueued¤logsrunning¦outputbodym<div class="markdown"><p>Statistics for Steps to Finish Race on Track 1</p>

<table><tr><th align="right">Statistic</th><th align="right"><div class="markdown"><p>Off policy MC Control</p>
</div></th><th align="right">Random Policy</th></tr><tr><td align="right">Mean</td><td align="right">2689</td><td align="right">2445</td></tr><tr><td align="right">Median</td><td align="right">2228</td><td align="right">1801</td></tr><tr><td align="right">Std</td><td align="right">2148</td><td align="right">2174</td></tr><tr><td align="right">Minimum</td><td align="right">14</td><td align="right">17</td></tr><tr><td align="right">Maximum</td><td align="right">9983</td><td align="right">9986</td></tr></table>
<p>Cummulative Distribution Function of Steps to Finish Race 	<script id='plot_1'>
		// We start by putting all the variable interpolation here at the beginning
		// We have to convert all typedarrays in the layout to normal arrays. See Issue #25
		// We use lodash for this for compactness
		function removeTypedArray(o) {
			return _.isTypedArray(o) ? Array.from(o) :
			_.isPlainObject(o) ? _.mapValues(o, removeTypedArray) : 
			o
		}

		// Publish the plot object to JS
		let plot_obj = _.update(/* See the documentation for AbstractPlutoDingetjes.Display.published_to_js */ getPublishedObject("c6e0de0c-3901-11f0-234e-bd09c571f662/49c525f145d8c899"), "layout", removeTypedArray)
		// Get the plotly listeners
		const plotly_listeners = {}
		// Get the JS listeners
		const js_listeners = {}
		// Deal with eventual custom classes
		let custom_classlist = []


		// Load the plotly library
		let Plotly = undefined
		try {
			let _mod = await import("./plotlyjs/plotlyjs-2.26.2.min.js")
			Plotly = _mod.default
		} catch (e) {
			console.log("Local load failed, trying with the web esm.sh version")
			let _mod = await import("https://esm.sh/plotly.js-dist-min@2.26.2/es2022/plotly.js-dist-min.mjs")
			Plotly = _mod.default
		}

		// Check if we have to force local mathjax font cache
		if (false && window?.MathJax?.config?.svg?.fontCache === 'global') {
			window.MathJax.config.svg.fontCache = 'local'
		}

		// Flag to check if this cell was  manually ran or reactively ran
const firstRun = this ? false : true
const CONTAINER = this ?? html`<div class='plutoplotly-container'>`
const PLOT = CONTAINER.querySelector('.js-plotly-plot') ?? CONTAINER.appendChild(html`<div>`)
const parent = CONTAINER.parentElement
// We use a controller to remove event listeners upon invalidation
const controller = new AbortController()
// We have to add this to keep supporting @bind with the old API using PLOT
PLOT.addEventListener('input', (e) => {
	CONTAINER.value = PLOT.value
	if (e.bubbles) {
		return
	}
	CONTAINER.dispatchEvent(new CustomEvent('input'))
}, { signal: controller.signal })

	// This create the style subdiv on first run
	firstRun && CONTAINER.appendChild(html`
	<style>
	.plutoplotly-container {
		width: 100%;
		height: 100%;
		min-height: 0;
		min-width: 0;
	}
	.plutoplotly-container .js-plotly-plot .plotly div {
		margin: 0 auto; // This centers the plot
	}
	.plutoplotly-container.popped-out {
		overflow: auto;
		z-index: 1000;
		position: fixed;
		resize: both;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		border-top-left-radius: 0px;
		border-top-right-radius: 0px;
	}
	.plutoplotly-clipboard-header {
		display: flex;
		flex-flow: row wrap;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-top-left-radius: 12px;
		border-top-right-radius: 12px;
		position: fixed;
		z-index: 1001;
		cursor: move;
		transform: translate(0px, -100%);
		padding: 5px;
	}
	.plutoplotly-clipboard-header span {
		display: inline-block;
		flex: 1
	}
	.plutoplotly-clipboard-header.hidden {
		display: none;
	}
	.clipboard-span {
		position: relative;
	}
	.clipboard-value {
		padding-right: 5px;
		padding-left: 2px;
		cursor: text;
	}
	.clipboard-span.format {
		display: none;
	}
	.clipboard-span.filename {
		flex: 0 0 100%;
		text-align: center;
		border-top: 3px solid var(--kbd-border-color);
		margin-top: 5px;
		display: none;
	}
	.plutoplotly-container.filesave .clipboard-span.filename {
		display: inline-block;
	}
	.clipboard-value.filename {
		margin-left: 3px;
		text-align: left;
		min-width: min(60%, min-content);
	}
	.plutoplotly-container.filesave .clipboard-span.format {
		display: inline-flex;
	}
	.clipboard-span.format .label {
		flex: 0 0 0;
	}
	.clipboard-value.format {
		position: relative;
		flex: 1 0 auto;
		min-width: 30px;
		margin-right: 10px;
	}
	div.format-options {
		display: inline-flex;
		flex-flow: column;
		position: absolute;
		background: var(--main-bg-color);
		border-radius: 12px;
		padding-left: 3px;
		z-index: 2000;
	}
	div.format-options:hover {
		cursor: pointer;
		border: 3px solid var(--kbd-border-color);
		padding: 3px;
		transform: translate(-3px, -6px);
	}
	div.format-options .format-option {
		display: none;
	}
	div.format-options:hover .format-option {
		display: inline-block;
	}
	.format-option:not(.selected) {
		margin-top: 3px;
	}
	div.format-options .format-option.selected {
		order: -1;
		display: inline-block;
	}
	.format-option:hover {
		background-color: var(--kbd-border-color);
	}
	span.config-value {
		font-weight: normal;
		color: var(--pluto-output-color);
		display: none;
		position: absolute;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		transform: translate(0px, calc(-100% - 10px));
		padding: 5px;
	}
	.label {
		user-select: none;
	}
	.label:hover span.config-value {
		display: inline-block;
		min-width: 150px;
	}
	.clipboard-span.matching-config .label {
		color: var(--cm-macro-color);
		font-weight: bold;
	}
	.clipboard-span.different-config .label {
		color: var(--cm-tag-color);
		font-weight: bold;
	}
</style>
`)

let original_height = plot_obj.layout.height
let original_width = plot_obj.layout.width
// For the height we have to also put a fixed value in case the plot is put on a non-fixed-size container (like the default wrapper)
// We define a variable to check whether we still have to remove the fixed height
let remove_container_size = firstRun
let container_height = original_height ?? PLOT.container_height ?? 400
CONTAINER.style.height = container_height + 'px'

// We create a Promise version of setTimeout
function delay(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

// We import interact for dragging/resizing
const { default: interact } = await import('https://esm.sh/interactjs@1.10.19')


function getImageOptions() {
  const o = plot_obj.config.toImageButtonOptions ?? {};
  return {
    format: o.format ?? "png",
    width: o.width ?? original_width,
    height: o.height ?? original_height,
    scale: o.scale ?? 1,
    filename: o.filename ?? "newplot",
  };
}

const CLIPBOARD_HEADER =
  CONTAINER.querySelector(".plutoplotly-clipboard-header") ??
  CONTAINER.insertAdjacentElement(
    "afterbegin",
    html`<div class="plutoplotly-clipboard-header hidden">
      <span class="clipboard-span format"
        ><span class="label">Format:</span
        ><span class="clipboard-value format"></span
      ></span>
      <span class="clipboard-span width"
        ><span class="label">Width:</span
        ><span class="clipboard-value width"></span>px</span
      >
      <span class="clipboard-span height"
        ><span class="label">Height:</span
        ><span class="clipboard-value height"></span>px</span
      >
      <span class="clipboard-span scale"
        ><span class="label">Scale:</span
        ><span class="clipboard-value scale"></span
      ></span>
      <button class="clipboard-span set">Set</button>
      <button class="clipboard-span unset">Unset</button>
      <span class="clipboard-span filename"
        ><span class="label">Filename:</span
        ><span class="clipboard-value filename"></span
      ></span>
    </div>`
  );

function checkConfigSync(container) {
  const valid_classes = [
    "missing-config",
    "matching-config",
    "different-config",
  ];
  function setClass(cl) {
    for (const name of valid_classes) {
      container.classList.toggle(name, name == cl);
    }
  }
  // We use the custom getters we'll set up in the container
  const { ui_value, config_value, config_span, key } = container;
  if (config_value === undefined) {
    setClass("missing-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> is not present in the config.`;
  } else if (ui_value == config_value) {
    setClass("matching-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has the same value in the config and in the header.`;
  } else {
    setClass("different-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has a different value (<em>${config_value}</em>) in the config.`;
  }
  // Add info about setting and unsetting
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click on the label <em><b>once</b></em> to set the current UI value in the config.`
  );
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click <em><b>twice</b></em> to remove this key from the config.`
  );
}

const valid_formats = ["png", "svg", "webp", "jpeg", "full-json"];
function initializeUIValueSpan(span, key, value) {
  const container = span.closest(".clipboard-span");
  span.contentEditable = key === "format" ? "false" : "true";
  let parse = (x) => x;
  let update = (x) => (span.textContent = x);
  if (key === "width" || key === "height") {
    parse = (x) => Math.round(parseFloat(x));
  } else if (key === "scale") {
    parse = parseFloat;
  } else if (key === "format") {
    // We remove contentEditable
    span.contentEditable = "false";
    // Here we first add the subspans for each option
    const opts_div = span.appendChild(html`<div class="format-options"></div>`);
    for (const fmt of valid_formats) {
      const opt = opts_div.appendChild(
        html`<span class="format-option ${fmt}">${fmt}</span>`
      );
      opt.onclick = (e) => {
        span.value = opt.textContent;
      };
    }
    parse = (x) => {
      return valid_formats.includes(x) ? x : localValue;
    };
    update = (x) => {
      for (const opt of opts_div.children) {
        opt.classList.toggle("selected", opt.textContent === x);
      }
    };
  } else {
    // We only have filename here
  }
  let localValue;
  Object.defineProperty(span, "value", {
    get: () => {
      return localValue;
    },
    set: (val) => {
      if (val !== "") {
        localValue = parse(val);
      }
      update(localValue);
      checkConfigSync(container);
    },
  });
  // We also assign a listener so that the editable is blurred when enter is pressed
  span.onkeydown = (e) => {
    if (e.keyCode === 13) {
      e.preventDefault();
      span.blur();
    }
  };
  span.value = value;
}

function initializeConfigValueSpan(span, key) {
  // Here we mostly want to define the setter and getter
  const container = span.closest(".clipboard-span");
  Object.defineProperty(span, "value", {
    get: () => {
      return plot_obj.config.toImageButtonOptions[key];
    },
    set: (val) => {
      // if undefined is passed, we remove the entry from the options
      if (val === undefined) {
        delete plot_obj.config.toImageButtonOptions[key];
      } else {
        plot_obj.config.toImageButtonOptions[key] = val;
      }
      checkConfigSync(container);
    },
  });
}

const config_spans = {};
for (const [key, value] of Object.entries(getImageOptions())) {
  const container = CLIPBOARD_HEADER.querySelector(`.clipboard-span.${key}`);
  const label = container.querySelector(".label");
  // We give the label a function that on single click will set the current value and with double click will unset it
  label.onclick = DualClick(
    () => {
      container.config_value = container.ui_value;
    },
    (e) => {
      console.log("e", e);
      e.preventDefault();
      container.config_value = undefined;
    }
  );
  const ui_value_span = container.querySelector(".clipboard-value");
  const config_value_span =
    container.querySelector(".config-value") ??
    label.insertAdjacentElement(
      "afterbegin",
      html`<span class="config-value"></span>`
    );
  // Assing the two spans as properties of the containing span
  container.ui_span = ui_value_span;
  container.config_span = config_value_span;
  container.key = key;
  config_spans[key] = container;
  if (firstRun) {
    plot_obj.config.toImageButtonOptions =
      plot_obj.config.toImageButtonOptions ?? {};
    // We do the initialization of the value span
    initializeUIValueSpan(ui_value_span, key, value);
    // Then we initialize the config value
    initializeConfigValueSpan(config_value_span, key);
    // We put some convenience getters/setters
    // ui_value forward
    Object.defineProperty(container, "ui_value", {
      get: () => ui_value_span.value,
      set: (val) => {
        ui_value_span.value = val;
      },
    });
    // config_value forward
    Object.defineProperty(container, "config_value", {
      get: () => config_value_span.value,
      set: (val) => {
        config_value_span.value = val;
      },
    });
  }
}

// These objects will contain the default value

// This code updates the image options in the PLOT config with the provided ones
function setImageOptions(o) {
  for (const [key, container] of Object.entries(config_spans)) {
    container.config_value = o[key];
  }
}
function unsetImageOptions() {
  setImageOptions({});
}

const set_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.set");
const unset_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.unset");
if (firstRun) {
  set_button.onclick = (e) => {
    for (const container of Object.values(config_spans)) {
      container.config_value = container.ui_value;
    }
  };
  unset_button.onclick = unsetImageOptions;
}

// We add a function to check if the clipboard is popped out
CONTAINER.isPoppedOut = () => {
  return CONTAINER.classList.contains("popped-out");
};

CLIPBOARD_HEADER.onmousedown = function (event) {
  if (event.target.matches("span.clipboard-value")) {
    console.log("We don't move!");
    return;
  }
  const start = {
    left: parseFloat(CONTAINER.style.left),
    top: parseFloat(CONTAINER.style.top),
    X: event.pageX,
    Y: event.pageY,
  };
  function moveAt(event, start) {
    const top = event.pageY - start.Y + start.top + "px";
    const left = event.pageX - start.X + start.left + "px";
    CLIPBOARD_HEADER.style.left = left;
    CONTAINER.style.left = left;
    CONTAINER.style.top = top;
  }

  // move our absolutely positioned ball under the pointer
  moveAt(event, start);
  function onMouseMove(event) {
    moveAt(event, start);
  }

  // We use this to remove the mousemove when clicking outside of the container
  const controller = new AbortController();

  // move the container on mousemove
  document.addEventListener("mousemove", onMouseMove, {
    signal: controller.signal,
  });
  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        cleanUp();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );

  function cleanUp() {
    console.log("cleaning up the plot move listener");
    controller.abort();
    CLIPBOARD_HEADER.onmouseup = null;
  }

  // (3) drop the ball, remove unneeded handlers
  CLIPBOARD_HEADER.onmouseup = cleanUp;
};

function sendToClipboard(blob) {
  if (!navigator.clipboard) {
    alert(
      "The Clipboard API does not seem to be available, make sure the Pluto notebook is being used from either localhost or an https source."
    );
  }
  navigator.clipboard
    .write([
      new ClipboardItem({
        // The key is determined dynamically based on the blob's type.
        [blob.type]: blob,
      }),
    ])
    .then(
      function () {
        console.log("Async: Copying to clipboard was successful!");
      },
      function (err) {
        console.error("Async: Could not copy text: ", err);
      }
    );
}

function copyImageToClipboard() {
  // We extract the image options from the provided parameters (if they exist)
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key. We also ignore format because the clipboard only supports png.
    if (val === undefined || key === "format") {
      continue;
    }
    config[key] = val;
  }
  Plotly.toImage(PLOT, config).then(function (dataUrl) {
    fetch(dataUrl)
      .then((res) => res.blob())
      .then((blob) => {
        const paste_receiver = document.querySelector('paste-receiver.plutoplotly')
        if (paste_receiver) {
          paste_receiver.attachImage(dataUrl, CONTAINER)
        }
        sendToClipboard(blob)
      });
  });
}

function saveImageToFile() {
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key.
    if (val === undefined) {
      continue;
    }
    config[key] = val;
  }
  Plotly.downloadImage(PLOT, config);
}

let container_rect = { width: 0, height: 0, top: 0, left: 0 };
function unpop_container(cl) {
  CONTAINER.classList.toggle("popped-out", false);
  CONTAINER.classList.toggle(cl, false);
  // We fix the height back to the value it had before popout, also setting the flag to signal that upon first resize we remove the fixed inline-style
  CONTAINER.style.height = container_rect.height + "px";
  remove_container_size = true;
  // We set the other fixed inline-styles to null
  CONTAINER.style.width = "";
  CONTAINER.style.top = "";
  CONTAINER.style.left = "";
  // We also remove the CLIPBOARD_HEADER
  CLIPBOARD_HEADER.style.width = "";
  CLIPBOARD_HEADER.style.left = "";
  // Finally we remove the hidden class to the header
  CLIPBOARD_HEADER.classList.toggle("hidden", true);
  return;
}
function popout_container(opts) {
  const cl = opts?.cl;
  const target_container_size = opts?.target_container_size ?? {};
  const target_plot_size = opts?.target_plot_size ?? {};
  if (CONTAINER.isPoppedOut()) {
    return unpop_container(cl);
  }
  CONTAINER.classList.toggle(cl, cl === undefined ? false : true);
  // We extract the current size of the container, save them and fix them
  const { width, height, top, left } = CONTAINER.getBoundingClientRect();
  container_rect = { width, height, top, left };
  // We save the current plot size before we pop as it will fill the screen
  const current_plot_size = {
    width: PLOT._fullLayout.width,
    height: PLOT._fullLayout.height,
  };
  // We have to save the pad data before popping so we can resize precisely
  const pad = {};
  pad.unpopped = getSizeData().container_pad;
  CONTAINER.classList.toggle("popped-out", true);
  pad.popped = getSizeData().container_pad;
  // We do top and left based on the current rect
  for (const key of ["top", "left"]) {
    const start_val = target_container_size[key] ?? container_rect[key];
    let offset = 0;
    for (const kind of ["padding", "border"]) {
      offset += pad.popped[kind][key] - pad.unpopped[kind][key];
    }
    CONTAINER.style[key] = start_val - offset + "px";
    if (key === "left") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  // We compute the width and height depending on eventual config data
  const csz = computeContainerSize({
    width:
      target_plot_size.width ??
      config_spans.width.config_value ??
      current_plot_size.width,
    height:
      target_plot_size.height ??
      config_spans.height.config_value ??
      current_plot_size.height,
  });
  for (const key of ["width", "height"]) {
    const val = target_container_size[key] ?? csz[key];
    CONTAINER.style[key] = val + "px";
    if (key === "width") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  CLIPBOARD_HEADER.classList.toggle("hidden", false);
  const controller = new AbortController();

  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        unpop_container();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );
}

CONTAINER.popOut = popout_container;

function DualClick(single_func, dbl_func) {
  let nclicks = 0;
  return function (...args) {
    nclicks += 1;
    if (nclicks > 1) {
      dbl_func(...args);
      nclicks = 0;
    } else {
      delay(300).then(() => {
        if (nclicks == 1) {
          single_func(...args);
        }
        nclicks = 0;
      });
    }
  };
}

// We remove the default download image button
plot_obj.config.modeBarButtonsToRemove = _.union(
  plot_obj.config.modeBarButtonsToRemove,
  ["toImage"]
);
// We add the custom button to the modebar
plot_obj.config.modeBarButtonsToAdd = _.union(
  plot_obj.config.modeBarButtonsToAdd,
  [
    {
      name: "Copy PNG to Clipboard",
      icon: {
        height: 520,
        width: 520,
        path: "M280 64h40c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128C0 92.7 28.7 64 64 64h40 9.6C121 27.5 153.3 0 192 0s71 27.5 78.4 64H280zM64 112c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16H320c8.8 0 16-7.2 16-16V128c0-8.8-7.2-16-16-16H304v24c0 13.3-10.7 24-24 24H192 104c-13.3 0-24-10.7-24-24V112H64zm128-8a24 24 0 1 0 0-48 24 24 0 1 0 0 48z",
      },
      direction: "up",
      click: DualClick(copyImageToClipboard, () => {
        popout_container();
      }),
    },
    {
      name: "Download Image",
      icon: Plotly.Icons.camera,
      direction: "up",
      click: DualClick(saveImageToFile, () => {
        popout_container({ cl: "filesave" });
      }),
    },
  ]
);

function getOffsetData(el) {
  let cs = window.getComputedStyle(el, null);
  const odata = {
    padding: {
      left: parseFloat(cs.paddingLeft),
      right: parseFloat(cs.paddingRight),
      top: parseFloat(cs.paddingTop),
      bottom: parseFloat(cs.paddingBottom),
      width: parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight),
      height: parseFloat(cs.paddingTop) + parseFloat(cs.paddingBottom),
    },
    border: {
      left: parseFloat(cs.borderLeftWidth),
      right: parseFloat(cs.borderRightWidth),
      top: parseFloat(cs.borderTopWidth),
      bottom: parseFloat(cs.borderBottomWidth),
      width: parseFloat(cs.borderLeftWidth) + parseFloat(cs.borderRightWidth),
      height: parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth),
    }
  };
  if (el === PLOT) {
    // For the PLOT we also want to take into account the offset
    odata.offset = {
      top: PLOT.offsetParent == CONTAINER ? PLOT.offsetTop : 0,
      left: PLOT.offsetParent == CONTAINER ? PLOT.offsetLeft : 0,
    }
  }
  return odata;
}
function getSizeData() {
  const data = {
    plot_pad: getOffsetData(PLOT),
    plot_rect: PLOT.getBoundingClientRect(),
    container_pad: getOffsetData(CONTAINER),
    container_rect: CONTAINER.getBoundingClientRect(),
  };
  return data;
}
function computeContainerSize({ width, height }, sizeData = getSizeData()) {
  const computed_size = computePlotSize(sizeData);
  const offsets = computed_size.offsets;

  const plot_data = {
    width: width ?? computed_size.width,
    height: height ?? computed_size.height,
  };

  return {
    width: (width ?? computed_size.width) + offsets.width,
    height: (height ?? computed_size.height) + offsets.height,
    noChange: width == computed_size.width && height == computed_size.height,
  }
}

// This function will change the container size so that the resulting plot will be matching the provided specs
function changeContainerSize({ width, height }, sizeData = getSizeData()) {
  if (!CONTAINER.isPoppedOut()) {
    console.log("Tried to change container size when not popped, ignoring");
    return;
  }

  const csz = computeContainerSize({ width, height }, sizeData);

  if (csz.noChange) {
    console.log("Size is the same as current, ignoring");
    return
  }
  // We are now going to set he width and height of the container
  for (const key of ["width", "height"]) {
    CONTAINER.style[key] = csz[key] + "px";
  }
}
// We now create the function that will update the plot based on the values specified
function updateFromHeader() {
  const header_data = {
    height: config_spans.height.ui_value,
    width: config_spans.width.ui_value,
  };
  changeContainerSize(header_data);
}
// We assign this function to the onblur event of width and height
if (firstRun) {
  for (const container of Object.values(config_spans)) {
    container.ui_span.onblur = (e) => {
      container.ui_value = container.ui_span.textContent;
      updateFromHeader();
    };
  }
}
// This function computes the plot size to use for relayout as a function of the container size
function computePlotSize(data = getSizeData()) {
  // Remove Padding
  const { container_pad, plot_pad, container_rect } = data;
  const offsets = {
    width:
      plot_pad.padding.width +
      plot_pad.border.width +
      plot_pad.offset.left +
      container_pad.padding.width +
      container_pad.border.width,
    height:
      plot_pad.padding.height +
      plot_pad.border.height +
      plot_pad.offset.top +
      container_pad.padding.height +
      container_pad.border.height,
  };
  const sz = {
    width: Math.round(container_rect.width - offsets.width),
    height: Math.round(container_rect.height - offsets.height),
    offsets,
  };
  return sz;
}

// Create the resizeObserver to make the plot even more responsive! :magic:
const resizeObserver = new ResizeObserver((entries) => {
  const sizeData = getSizeData();
  const {container_rect, container_pad} = sizeData;
  let plot_size = computePlotSize(sizeData);
  // We save the height in the PLOT object
  PLOT.container_height = container_rect.height;
  // We deal with some stuff if the container is poppped
  CLIPBOARD_HEADER.style.width = container_rect.width + "px";
  CLIPBOARD_HEADER.style.left = container_rect.left + "px";
  config_spans.height.ui_value = plot_size.height;
  config_spans.width.ui_value = plot_size.width;
  /* 
		The addition of the invalid argument `plutoresize` seems to fix the problem with calling `relayout` simply with `{autosize: true}` as update breaking mouse relayout events tracking. 
		See https://github.com/plotly/plotly.js/issues/6156 for details
		*/
  let config = {
    // If this is popped out, we ignore the original width/height
    width: (CONTAINER.isPoppedOut() ? undefined : original_width) ?? plot_size.width,
    height: (CONTAINER.isPoppedOut() ? undefined : original_height) ?? plot_size.height,
    plutoresize: true,
  };
  Plotly.relayout(PLOT, config).then(() => {
    if (remove_container_size && !CONTAINER.isPoppedOut()) {
      // This is needed to avoid the first resize upon plot creation to already be without a fixed height
      CONTAINER.style.height = "";
      CONTAINER.style.width = "";
      remove_container_size = false;
    }
  });
});

resizeObserver.observe(CONTAINER);


Plotly.react(PLOT, plot_obj).then(() => {
	// Assign the Plotly event listeners
	for (const [key, listener_vec] of Object.entries(plotly_listeners)) {
		for (const listener of listener_vec) {
			PLOT.on(key, listener)
		}
	}
	// Assign the JS event listeners
	for (const [key, listener_vec] of Object.entries(js_listeners)) {
		for (const listener of listener_vec) {
			PLOT.addEventListener(key, listener, {
				signal: controller.signal
			})
		}
	}
}
)


invalidation.then(() => {
	// Remove all plotly listeners
	PLOT.removeAllListeners()
	// Remove all JS listeners
	controller.abort()
	// Remove the resizeObserver
	resizeObserver.disconnect()
})



		return CONTAINER
	</script>
</p>
</div>mimetext/htmlrootassigneelast_run_timestampA2ipersist_js_state·has_pluto_hook_features§cell_id$1067fcc4-cbc6-453c-a996-d420c498619adepends_on_disabled_cells§runtime)published_object_keys5c6e0de0c-3901-11f0-234e-bd09c571f662/49c525f145d8c899depends_on_skipped_cells§errored$6496c993-6d47-4a6e-a497-2a2de172fbc3queued¤logsrunning¦outputbodyي<div class="markdown"><h3>Off-policy Monte-Carlo Prediction Algorithm for Estimating <span class="tex">$Q \approx q_π$</span></h3>
</div>mimetext/htmlrootassigneelast_run_timestampA")Ѱpersist_js_state·has_pluto_hook_features§cell_id$6496c993-6d47-4a6e-a497-2a2de172fbc3depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$aa647f3e-a4b2-4825-bb2a-1c2469d2c0ebqueued¤logsrunning¦outputbodym<div class="markdown"><p>Statistics for Steps to Finish Race on Track 2</p>

<table><tr><th align="right">Statistic</th><th align="right"><div class="markdown"><p>Monte Carlo Exploring Starts</p>
</div></th><th align="right">Random Policy</th></tr><tr><td align="right">Mean</td><td align="right">26</td><td align="right">293</td></tr><tr><td align="right">Median</td><td align="right">21</td><td align="right">220</td></tr><tr><td align="right">Std</td><td align="right">15</td><td align="right">263</td></tr><tr><td align="right">Minimum</td><td align="right">12</td><td align="right">11</td></tr><tr><td align="right">Maximum</td><td align="right">112</td><td align="right">1894</td></tr></table>
<p>Cummulative Distribution Function of Steps to Finish Race 	<script id='plot_1'>
		// We start by putting all the variable interpolation here at the beginning
		// We have to convert all typedarrays in the layout to normal arrays. See Issue #25
		// We use lodash for this for compactness
		function removeTypedArray(o) {
			return _.isTypedArray(o) ? Array.from(o) :
			_.isPlainObject(o) ? _.mapValues(o, removeTypedArray) : 
			o
		}

		// Publish the plot object to JS
		let plot_obj = _.update(/* See the documentation for AbstractPlutoDingetjes.Display.published_to_js */ getPublishedObject("c6e0de0c-3901-11f0-234e-bd09c571f662/e01572e8e76890cd"), "layout", removeTypedArray)
		// Get the plotly listeners
		const plotly_listeners = {}
		// Get the JS listeners
		const js_listeners = {}
		// Deal with eventual custom classes
		let custom_classlist = []


		// Load the plotly library
		let Plotly = undefined
		try {
			let _mod = await import("./plotlyjs/plotlyjs-2.26.2.min.js")
			Plotly = _mod.default
		} catch (e) {
			console.log("Local load failed, trying with the web esm.sh version")
			let _mod = await import("https://esm.sh/plotly.js-dist-min@2.26.2/es2022/plotly.js-dist-min.mjs")
			Plotly = _mod.default
		}

		// Check if we have to force local mathjax font cache
		if (false && window?.MathJax?.config?.svg?.fontCache === 'global') {
			window.MathJax.config.svg.fontCache = 'local'
		}

		// Flag to check if this cell was  manually ran or reactively ran
const firstRun = this ? false : true
const CONTAINER = this ?? html`<div class='plutoplotly-container'>`
const PLOT = CONTAINER.querySelector('.js-plotly-plot') ?? CONTAINER.appendChild(html`<div>`)
const parent = CONTAINER.parentElement
// We use a controller to remove event listeners upon invalidation
const controller = new AbortController()
// We have to add this to keep supporting @bind with the old API using PLOT
PLOT.addEventListener('input', (e) => {
	CONTAINER.value = PLOT.value
	if (e.bubbles) {
		return
	}
	CONTAINER.dispatchEvent(new CustomEvent('input'))
}, { signal: controller.signal })

	// This create the style subdiv on first run
	firstRun && CONTAINER.appendChild(html`
	<style>
	.plutoplotly-container {
		width: 100%;
		height: 100%;
		min-height: 0;
		min-width: 0;
	}
	.plutoplotly-container .js-plotly-plot .plotly div {
		margin: 0 auto; // This centers the plot
	}
	.plutoplotly-container.popped-out {
		overflow: auto;
		z-index: 1000;
		position: fixed;
		resize: both;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		border-top-left-radius: 0px;
		border-top-right-radius: 0px;
	}
	.plutoplotly-clipboard-header {
		display: flex;
		flex-flow: row wrap;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-top-left-radius: 12px;
		border-top-right-radius: 12px;
		position: fixed;
		z-index: 1001;
		cursor: move;
		transform: translate(0px, -100%);
		padding: 5px;
	}
	.plutoplotly-clipboard-header span {
		display: inline-block;
		flex: 1
	}
	.plutoplotly-clipboard-header.hidden {
		display: none;
	}
	.clipboard-span {
		position: relative;
	}
	.clipboard-value {
		padding-right: 5px;
		padding-left: 2px;
		cursor: text;
	}
	.clipboard-span.format {
		display: none;
	}
	.clipboard-span.filename {
		flex: 0 0 100%;
		text-align: center;
		border-top: 3px solid var(--kbd-border-color);
		margin-top: 5px;
		display: none;
	}
	.plutoplotly-container.filesave .clipboard-span.filename {
		display: inline-block;
	}
	.clipboard-value.filename {
		margin-left: 3px;
		text-align: left;
		min-width: min(60%, min-content);
	}
	.plutoplotly-container.filesave .clipboard-span.format {
		display: inline-flex;
	}
	.clipboard-span.format .label {
		flex: 0 0 0;
	}
	.clipboard-value.format {
		position: relative;
		flex: 1 0 auto;
		min-width: 30px;
		margin-right: 10px;
	}
	div.format-options {
		display: inline-flex;
		flex-flow: column;
		position: absolute;
		background: var(--main-bg-color);
		border-radius: 12px;
		padding-left: 3px;
		z-index: 2000;
	}
	div.format-options:hover {
		cursor: pointer;
		border: 3px solid var(--kbd-border-color);
		padding: 3px;
		transform: translate(-3px, -6px);
	}
	div.format-options .format-option {
		display: none;
	}
	div.format-options:hover .format-option {
		display: inline-block;
	}
	.format-option:not(.selected) {
		margin-top: 3px;
	}
	div.format-options .format-option.selected {
		order: -1;
		display: inline-block;
	}
	.format-option:hover {
		background-color: var(--kbd-border-color);
	}
	span.config-value {
		font-weight: normal;
		color: var(--pluto-output-color);
		display: none;
		position: absolute;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		transform: translate(0px, calc(-100% - 10px));
		padding: 5px;
	}
	.label {
		user-select: none;
	}
	.label:hover span.config-value {
		display: inline-block;
		min-width: 150px;
	}
	.clipboard-span.matching-config .label {
		color: var(--cm-macro-color);
		font-weight: bold;
	}
	.clipboard-span.different-config .label {
		color: var(--cm-tag-color);
		font-weight: bold;
	}
</style>
`)

let original_height = plot_obj.layout.height
let original_width = plot_obj.layout.width
// For the height we have to also put a fixed value in case the plot is put on a non-fixed-size container (like the default wrapper)
// We define a variable to check whether we still have to remove the fixed height
let remove_container_size = firstRun
let container_height = original_height ?? PLOT.container_height ?? 400
CONTAINER.style.height = container_height + 'px'

// We create a Promise version of setTimeout
function delay(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

// We import interact for dragging/resizing
const { default: interact } = await import('https://esm.sh/interactjs@1.10.19')


function getImageOptions() {
  const o = plot_obj.config.toImageButtonOptions ?? {};
  return {
    format: o.format ?? "png",
    width: o.width ?? original_width,
    height: o.height ?? original_height,
    scale: o.scale ?? 1,
    filename: o.filename ?? "newplot",
  };
}

const CLIPBOARD_HEADER =
  CONTAINER.querySelector(".plutoplotly-clipboard-header") ??
  CONTAINER.insertAdjacentElement(
    "afterbegin",
    html`<div class="plutoplotly-clipboard-header hidden">
      <span class="clipboard-span format"
        ><span class="label">Format:</span
        ><span class="clipboard-value format"></span
      ></span>
      <span class="clipboard-span width"
        ><span class="label">Width:</span
        ><span class="clipboard-value width"></span>px</span
      >
      <span class="clipboard-span height"
        ><span class="label">Height:</span
        ><span class="clipboard-value height"></span>px</span
      >
      <span class="clipboard-span scale"
        ><span class="label">Scale:</span
        ><span class="clipboard-value scale"></span
      ></span>
      <button class="clipboard-span set">Set</button>
      <button class="clipboard-span unset">Unset</button>
      <span class="clipboard-span filename"
        ><span class="label">Filename:</span
        ><span class="clipboard-value filename"></span
      ></span>
    </div>`
  );

function checkConfigSync(container) {
  const valid_classes = [
    "missing-config",
    "matching-config",
    "different-config",
  ];
  function setClass(cl) {
    for (const name of valid_classes) {
      container.classList.toggle(name, name == cl);
    }
  }
  // We use the custom getters we'll set up in the container
  const { ui_value, config_value, config_span, key } = container;
  if (config_value === undefined) {
    setClass("missing-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> is not present in the config.`;
  } else if (ui_value == config_value) {
    setClass("matching-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has the same value in the config and in the header.`;
  } else {
    setClass("different-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has a different value (<em>${config_value}</em>) in the config.`;
  }
  // Add info about setting and unsetting
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click on the label <em><b>once</b></em> to set the current UI value in the config.`
  );
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click <em><b>twice</b></em> to remove this key from the config.`
  );
}

const valid_formats = ["png", "svg", "webp", "jpeg", "full-json"];
function initializeUIValueSpan(span, key, value) {
  const container = span.closest(".clipboard-span");
  span.contentEditable = key === "format" ? "false" : "true";
  let parse = (x) => x;
  let update = (x) => (span.textContent = x);
  if (key === "width" || key === "height") {
    parse = (x) => Math.round(parseFloat(x));
  } else if (key === "scale") {
    parse = parseFloat;
  } else if (key === "format") {
    // We remove contentEditable
    span.contentEditable = "false";
    // Here we first add the subspans for each option
    const opts_div = span.appendChild(html`<div class="format-options"></div>`);
    for (const fmt of valid_formats) {
      const opt = opts_div.appendChild(
        html`<span class="format-option ${fmt}">${fmt}</span>`
      );
      opt.onclick = (e) => {
        span.value = opt.textContent;
      };
    }
    parse = (x) => {
      return valid_formats.includes(x) ? x : localValue;
    };
    update = (x) => {
      for (const opt of opts_div.children) {
        opt.classList.toggle("selected", opt.textContent === x);
      }
    };
  } else {
    // We only have filename here
  }
  let localValue;
  Object.defineProperty(span, "value", {
    get: () => {
      return localValue;
    },
    set: (val) => {
      if (val !== "") {
        localValue = parse(val);
      }
      update(localValue);
      checkConfigSync(container);
    },
  });
  // We also assign a listener so that the editable is blurred when enter is pressed
  span.onkeydown = (e) => {
    if (e.keyCode === 13) {
      e.preventDefault();
      span.blur();
    }
  };
  span.value = value;
}

function initializeConfigValueSpan(span, key) {
  // Here we mostly want to define the setter and getter
  const container = span.closest(".clipboard-span");
  Object.defineProperty(span, "value", {
    get: () => {
      return plot_obj.config.toImageButtonOptions[key];
    },
    set: (val) => {
      // if undefined is passed, we remove the entry from the options
      if (val === undefined) {
        delete plot_obj.config.toImageButtonOptions[key];
      } else {
        plot_obj.config.toImageButtonOptions[key] = val;
      }
      checkConfigSync(container);
    },
  });
}

const config_spans = {};
for (const [key, value] of Object.entries(getImageOptions())) {
  const container = CLIPBOARD_HEADER.querySelector(`.clipboard-span.${key}`);
  const label = container.querySelector(".label");
  // We give the label a function that on single click will set the current value and with double click will unset it
  label.onclick = DualClick(
    () => {
      container.config_value = container.ui_value;
    },
    (e) => {
      console.log("e", e);
      e.preventDefault();
      container.config_value = undefined;
    }
  );
  const ui_value_span = container.querySelector(".clipboard-value");
  const config_value_span =
    container.querySelector(".config-value") ??
    label.insertAdjacentElement(
      "afterbegin",
      html`<span class="config-value"></span>`
    );
  // Assing the two spans as properties of the containing span
  container.ui_span = ui_value_span;
  container.config_span = config_value_span;
  container.key = key;
  config_spans[key] = container;
  if (firstRun) {
    plot_obj.config.toImageButtonOptions =
      plot_obj.config.toImageButtonOptions ?? {};
    // We do the initialization of the value span
    initializeUIValueSpan(ui_value_span, key, value);
    // Then we initialize the config value
    initializeConfigValueSpan(config_value_span, key);
    // We put some convenience getters/setters
    // ui_value forward
    Object.defineProperty(container, "ui_value", {
      get: () => ui_value_span.value,
      set: (val) => {
        ui_value_span.value = val;
      },
    });
    // config_value forward
    Object.defineProperty(container, "config_value", {
      get: () => config_value_span.value,
      set: (val) => {
        config_value_span.value = val;
      },
    });
  }
}

// These objects will contain the default value

// This code updates the image options in the PLOT config with the provided ones
function setImageOptions(o) {
  for (const [key, container] of Object.entries(config_spans)) {
    container.config_value = o[key];
  }
}
function unsetImageOptions() {
  setImageOptions({});
}

const set_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.set");
const unset_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.unset");
if (firstRun) {
  set_button.onclick = (e) => {
    for (const container of Object.values(config_spans)) {
      container.config_value = container.ui_value;
    }
  };
  unset_button.onclick = unsetImageOptions;
}

// We add a function to check if the clipboard is popped out
CONTAINER.isPoppedOut = () => {
  return CONTAINER.classList.contains("popped-out");
};

CLIPBOARD_HEADER.onmousedown = function (event) {
  if (event.target.matches("span.clipboard-value")) {
    console.log("We don't move!");
    return;
  }
  const start = {
    left: parseFloat(CONTAINER.style.left),
    top: parseFloat(CONTAINER.style.top),
    X: event.pageX,
    Y: event.pageY,
  };
  function moveAt(event, start) {
    const top = event.pageY - start.Y + start.top + "px";
    const left = event.pageX - start.X + start.left + "px";
    CLIPBOARD_HEADER.style.left = left;
    CONTAINER.style.left = left;
    CONTAINER.style.top = top;
  }

  // move our absolutely positioned ball under the pointer
  moveAt(event, start);
  function onMouseMove(event) {
    moveAt(event, start);
  }

  // We use this to remove the mousemove when clicking outside of the container
  const controller = new AbortController();

  // move the container on mousemove
  document.addEventListener("mousemove", onMouseMove, {
    signal: controller.signal,
  });
  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        cleanUp();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );

  function cleanUp() {
    console.log("cleaning up the plot move listener");
    controller.abort();
    CLIPBOARD_HEADER.onmouseup = null;
  }

  // (3) drop the ball, remove unneeded handlers
  CLIPBOARD_HEADER.onmouseup = cleanUp;
};

function sendToClipboard(blob) {
  if (!navigator.clipboard) {
    alert(
      "The Clipboard API does not seem to be available, make sure the Pluto notebook is being used from either localhost or an https source."
    );
  }
  navigator.clipboard
    .write([
      new ClipboardItem({
        // The key is determined dynamically based on the blob's type.
        [blob.type]: blob,
      }),
    ])
    .then(
      function () {
        console.log("Async: Copying to clipboard was successful!");
      },
      function (err) {
        console.error("Async: Could not copy text: ", err);
      }
    );
}

function copyImageToClipboard() {
  // We extract the image options from the provided parameters (if they exist)
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key. We also ignore format because the clipboard only supports png.
    if (val === undefined || key === "format") {
      continue;
    }
    config[key] = val;
  }
  Plotly.toImage(PLOT, config).then(function (dataUrl) {
    fetch(dataUrl)
      .then((res) => res.blob())
      .then((blob) => {
        const paste_receiver = document.querySelector('paste-receiver.plutoplotly')
        if (paste_receiver) {
          paste_receiver.attachImage(dataUrl, CONTAINER)
        }
        sendToClipboard(blob)
      });
  });
}

function saveImageToFile() {
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key.
    if (val === undefined) {
      continue;
    }
    config[key] = val;
  }
  Plotly.downloadImage(PLOT, config);
}

let container_rect = { width: 0, height: 0, top: 0, left: 0 };
function unpop_container(cl) {
  CONTAINER.classList.toggle("popped-out", false);
  CONTAINER.classList.toggle(cl, false);
  // We fix the height back to the value it had before popout, also setting the flag to signal that upon first resize we remove the fixed inline-style
  CONTAINER.style.height = container_rect.height + "px";
  remove_container_size = true;
  // We set the other fixed inline-styles to null
  CONTAINER.style.width = "";
  CONTAINER.style.top = "";
  CONTAINER.style.left = "";
  // We also remove the CLIPBOARD_HEADER
  CLIPBOARD_HEADER.style.width = "";
  CLIPBOARD_HEADER.style.left = "";
  // Finally we remove the hidden class to the header
  CLIPBOARD_HEADER.classList.toggle("hidden", true);
  return;
}
function popout_container(opts) {
  const cl = opts?.cl;
  const target_container_size = opts?.target_container_size ?? {};
  const target_plot_size = opts?.target_plot_size ?? {};
  if (CONTAINER.isPoppedOut()) {
    return unpop_container(cl);
  }
  CONTAINER.classList.toggle(cl, cl === undefined ? false : true);
  // We extract the current size of the container, save them and fix them
  const { width, height, top, left } = CONTAINER.getBoundingClientRect();
  container_rect = { width, height, top, left };
  // We save the current plot size before we pop as it will fill the screen
  const current_plot_size = {
    width: PLOT._fullLayout.width,
    height: PLOT._fullLayout.height,
  };
  // We have to save the pad data before popping so we can resize precisely
  const pad = {};
  pad.unpopped = getSizeData().container_pad;
  CONTAINER.classList.toggle("popped-out", true);
  pad.popped = getSizeData().container_pad;
  // We do top and left based on the current rect
  for (const key of ["top", "left"]) {
    const start_val = target_container_size[key] ?? container_rect[key];
    let offset = 0;
    for (const kind of ["padding", "border"]) {
      offset += pad.popped[kind][key] - pad.unpopped[kind][key];
    }
    CONTAINER.style[key] = start_val - offset + "px";
    if (key === "left") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  // We compute the width and height depending on eventual config data
  const csz = computeContainerSize({
    width:
      target_plot_size.width ??
      config_spans.width.config_value ??
      current_plot_size.width,
    height:
      target_plot_size.height ??
      config_spans.height.config_value ??
      current_plot_size.height,
  });
  for (const key of ["width", "height"]) {
    const val = target_container_size[key] ?? csz[key];
    CONTAINER.style[key] = val + "px";
    if (key === "width") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  CLIPBOARD_HEADER.classList.toggle("hidden", false);
  const controller = new AbortController();

  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        unpop_container();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );
}

CONTAINER.popOut = popout_container;

function DualClick(single_func, dbl_func) {
  let nclicks = 0;
  return function (...args) {
    nclicks += 1;
    if (nclicks > 1) {
      dbl_func(...args);
      nclicks = 0;
    } else {
      delay(300).then(() => {
        if (nclicks == 1) {
          single_func(...args);
        }
        nclicks = 0;
      });
    }
  };
}

// We remove the default download image button
plot_obj.config.modeBarButtonsToRemove = _.union(
  plot_obj.config.modeBarButtonsToRemove,
  ["toImage"]
);
// We add the custom button to the modebar
plot_obj.config.modeBarButtonsToAdd = _.union(
  plot_obj.config.modeBarButtonsToAdd,
  [
    {
      name: "Copy PNG to Clipboard",
      icon: {
        height: 520,
        width: 520,
        path: "M280 64h40c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128C0 92.7 28.7 64 64 64h40 9.6C121 27.5 153.3 0 192 0s71 27.5 78.4 64H280zM64 112c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16H320c8.8 0 16-7.2 16-16V128c0-8.8-7.2-16-16-16H304v24c0 13.3-10.7 24-24 24H192 104c-13.3 0-24-10.7-24-24V112H64zm128-8a24 24 0 1 0 0-48 24 24 0 1 0 0 48z",
      },
      direction: "up",
      click: DualClick(copyImageToClipboard, () => {
        popout_container();
      }),
    },
    {
      name: "Download Image",
      icon: Plotly.Icons.camera,
      direction: "up",
      click: DualClick(saveImageToFile, () => {
        popout_container({ cl: "filesave" });
      }),
    },
  ]
);

function getOffsetData(el) {
  let cs = window.getComputedStyle(el, null);
  const odata = {
    padding: {
      left: parseFloat(cs.paddingLeft),
      right: parseFloat(cs.paddingRight),
      top: parseFloat(cs.paddingTop),
      bottom: parseFloat(cs.paddingBottom),
      width: parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight),
      height: parseFloat(cs.paddingTop) + parseFloat(cs.paddingBottom),
    },
    border: {
      left: parseFloat(cs.borderLeftWidth),
      right: parseFloat(cs.borderRightWidth),
      top: parseFloat(cs.borderTopWidth),
      bottom: parseFloat(cs.borderBottomWidth),
      width: parseFloat(cs.borderLeftWidth) + parseFloat(cs.borderRightWidth),
      height: parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth),
    }
  };
  if (el === PLOT) {
    // For the PLOT we also want to take into account the offset
    odata.offset = {
      top: PLOT.offsetParent == CONTAINER ? PLOT.offsetTop : 0,
      left: PLOT.offsetParent == CONTAINER ? PLOT.offsetLeft : 0,
    }
  }
  return odata;
}
function getSizeData() {
  const data = {
    plot_pad: getOffsetData(PLOT),
    plot_rect: PLOT.getBoundingClientRect(),
    container_pad: getOffsetData(CONTAINER),
    container_rect: CONTAINER.getBoundingClientRect(),
  };
  return data;
}
function computeContainerSize({ width, height }, sizeData = getSizeData()) {
  const computed_size = computePlotSize(sizeData);
  const offsets = computed_size.offsets;

  const plot_data = {
    width: width ?? computed_size.width,
    height: height ?? computed_size.height,
  };

  return {
    width: (width ?? computed_size.width) + offsets.width,
    height: (height ?? computed_size.height) + offsets.height,
    noChange: width == computed_size.width && height == computed_size.height,
  }
}

// This function will change the container size so that the resulting plot will be matching the provided specs
function changeContainerSize({ width, height }, sizeData = getSizeData()) {
  if (!CONTAINER.isPoppedOut()) {
    console.log("Tried to change container size when not popped, ignoring");
    return;
  }

  const csz = computeContainerSize({ width, height }, sizeData);

  if (csz.noChange) {
    console.log("Size is the same as current, ignoring");
    return
  }
  // We are now going to set he width and height of the container
  for (const key of ["width", "height"]) {
    CONTAINER.style[key] = csz[key] + "px";
  }
}
// We now create the function that will update the plot based on the values specified
function updateFromHeader() {
  const header_data = {
    height: config_spans.height.ui_value,
    width: config_spans.width.ui_value,
  };
  changeContainerSize(header_data);
}
// We assign this function to the onblur event of width and height
if (firstRun) {
  for (const container of Object.values(config_spans)) {
    container.ui_span.onblur = (e) => {
      container.ui_value = container.ui_span.textContent;
      updateFromHeader();
    };
  }
}
// This function computes the plot size to use for relayout as a function of the container size
function computePlotSize(data = getSizeData()) {
  // Remove Padding
  const { container_pad, plot_pad, container_rect } = data;
  const offsets = {
    width:
      plot_pad.padding.width +
      plot_pad.border.width +
      plot_pad.offset.left +
      container_pad.padding.width +
      container_pad.border.width,
    height:
      plot_pad.padding.height +
      plot_pad.border.height +
      plot_pad.offset.top +
      container_pad.padding.height +
      container_pad.border.height,
  };
  const sz = {
    width: Math.round(container_rect.width - offsets.width),
    height: Math.round(container_rect.height - offsets.height),
    offsets,
  };
  return sz;
}

// Create the resizeObserver to make the plot even more responsive! :magic:
const resizeObserver = new ResizeObserver((entries) => {
  const sizeData = getSizeData();
  const {container_rect, container_pad} = sizeData;
  let plot_size = computePlotSize(sizeData);
  // We save the height in the PLOT object
  PLOT.container_height = container_rect.height;
  // We deal with some stuff if the container is poppped
  CLIPBOARD_HEADER.style.width = container_rect.width + "px";
  CLIPBOARD_HEADER.style.left = container_rect.left + "px";
  config_spans.height.ui_value = plot_size.height;
  config_spans.width.ui_value = plot_size.width;
  /* 
		The addition of the invalid argument `plutoresize` seems to fix the problem with calling `relayout` simply with `{autosize: true}` as update breaking mouse relayout events tracking. 
		See https://github.com/plotly/plotly.js/issues/6156 for details
		*/
  let config = {
    // If this is popped out, we ignore the original width/height
    width: (CONTAINER.isPoppedOut() ? undefined : original_width) ?? plot_size.width,
    height: (CONTAINER.isPoppedOut() ? undefined : original_height) ?? plot_size.height,
    plutoresize: true,
  };
  Plotly.relayout(PLOT, config).then(() => {
    if (remove_container_size && !CONTAINER.isPoppedOut()) {
      // This is needed to avoid the first resize upon plot creation to already be without a fixed height
      CONTAINER.style.height = "";
      CONTAINER.style.width = "";
      remove_container_size = false;
    }
  });
});

resizeObserver.observe(CONTAINER);


Plotly.react(PLOT, plot_obj).then(() => {
	// Assign the Plotly event listeners
	for (const [key, listener_vec] of Object.entries(plotly_listeners)) {
		for (const listener of listener_vec) {
			PLOT.on(key, listener)
		}
	}
	// Assign the JS event listeners
	for (const [key, listener_vec] of Object.entries(js_listeners)) {
		for (const listener of listener_vec) {
			PLOT.addEventListener(key, listener, {
				signal: controller.signal
			})
		}
	}
}
)


invalidation.then(() => {
	// Remove all plotly listeners
	PLOT.removeAllListeners()
	// Remove all JS listeners
	controller.abort()
	// Remove the resizeObserver
	resizeObserver.disconnect()
})



		return CONTAINER
	</script>
</p>
</div>mimetext/htmlrootassigneelast_run_timestampA38Ѱpersist_js_state·has_pluto_hook_features§cell_id$aa647f3e-a4b2-4825-bb2a-1c2469d2c0ebdepends_on_disabled_cells§runtime`published_object_keys5c6e0de0c-3901-11f0-234e-bd09c571f662/e01572e8e76890cddepends_on_skipped_cells§errored$1d3d509c-b11b-4c57-b100-9bcf0489af2bqueued¤logsrunning¦outputbody5create_greedy_policy (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA%zpersist_js_state·has_pluto_hook_features§cell_id$1d3d509c-b11b-4c57-b100-9bcf0489af2bdepends_on_disabled_cells§runtime '2published_object_keysdepends_on_skipped_cells§errored$989ccacd-b410-4967-bf6a-9244e3be785dqueued¤logsrunning¦outputbody<div class="markdown"><p>Number of Episodes: <bond def="mces1" unique_id="8HtqeGHqSRbX"><span style='display: contents;'>
	<input type='number' min='1' step='1' max='10000000' value='1000'>
	<input type=submit id='hidwhufxvo'>
	<script id='hidwhufxvo'>

let key = "hidwhufxvo"

let div = currentScript.parentElement
let button = currentScript.previousElementSibling
let input = div.firstElementChild
if(input === button) {
	return
}


let set_input_value = (() => {
	let result = null
	try {
	result = setBoundElementValueLikePluto
} catch (e) {
	result = ((input, new_value) => {
	// fallback in case https://github.com/fonsp/Pluto.jl/pull/1755 is not available
    if (new_value == null) {
        //@ts-ignore
        input.value = new_value
        return
    }
    if (input instanceof HTMLInputElement) {
        switch (input.type) {
            case "range":
            case "number": {
                if (input.valueAsNumber !== new_value) {
                    input.valueAsNumber = new_value
                }
                return
            }
            case "date": {
                if (input.valueAsDate == null || Number(input.valueAsDate) !== Number(new_value)) {
                    input.valueAsDate = new_value
                }
                return
            }
            case "checkbox": {
                if (input.checked !== new_value) {
                    input.checked = new_value
                }
                return
            }
            case "file": {
                // Can't set files :(
                return
            }
        }
    } else if (input instanceof HTMLSelectElement && input.multiple) {
        for (let option of Array.from(input.options)) {
            option.selected = new_value.includes(option.value)
        }
        return
    }
    //@ts-ignore
    if (input.value !== new_value) {
        //@ts-ignore
        input.value = new_value
    }
})
}
return result
})()



let private_value = null
let public_value = null




private_value = public_value = div.value
if(private_value != null) {
	set_input_value(input, private_value)
} else {

	// private_value = public_value = input.value
}

input.oninput = (e) => {
	e.stopPropagation()
}
const gen = Generators.input(input)

// If the child does not have an initial value, the `gen.next().value` promise will never resolve. If it does, then it resolves instantly.
let first_value = await Promise.any([
	gen.next().value,
	Promise.resolve(undefined)
])
private_value = public_value = first_value

;(async () => {
	while(true) {
		private_value = await gen.next().value
		// div.dispatchEvent(new CustomEvent("input", {}))
	}
})()

button.addEventListener("click", () => {
	public_value = private_value
	div.dispatchEvent(new CustomEvent("input", {}))
})


Object.defineProperty(div, 'value', {
	get: () => public_value,
	set: (newval) => {
		private_value = newval
		public_value = newval
		
		set_input_value(input, newval)
	},
	configurable: true,
});

</script></span></bond></p>
</div>mimetext/htmlrootassigneelast_run_timestampA2Vpersist_js_state·has_pluto_hook_features§cell_id$989ccacd-b410-4967-bf6a-9244e3be785ddepends_on_disabled_cells§runtime IApublished_object_keysdepends_on_skipped_cells§errored$b352d98e-0854-45e3-ac73-8ef434525563queued¤logsrunning¦outputbody-<div class="markdown"><h5>Track 1</h5>
</div>mimetext/htmlrootassigneelast_run_timestampA"*persist_js_state·has_pluto_hook_features§cell_id$b352d98e-0854-45e3-ac73-8ef434525563depends_on_disabled_cells§runtime 2published_object_keysdepends_on_skipped_cells§errored$202eb066-877d-4537-85b2-31b41db8eca0queued¤logsrunning¦outputbody7initialize_state_value (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA$apersist_js_state·has_pluto_hook_features§cell_id$202eb066-877d-4537-85b2-31b41db8eca0depends_on_disabled_cells§runtime zpublished_object_keysdepends_on_skipped_cells§errored$3955d71a-3105-445a-868d-66ba0b3dc515queued¤logsrunning¦outputbodyelementsprefixI@NamedTuple{position::Tuple{Int64, Int64}, velocity::Tuple{Int64, Int64}}elementselementspositionelements5text/plain0text/plaintypeTupleobjectid973ae957c0c386bd!application/vnd.pluto.tree+objectvelocityelements0text/plain0text/plaintypeTupleobjectid9b52efd7a2a08bd5!application/vnd.pluto.tree+objecttypeNamedTupleobjectid38a36543e5c0565d!application/vnd.pluto.tree+objectelementspositionelements5text/plain1text/plaintypeTupleobjectidaa0ea68f3321721e!application/vnd.pluto.tree+objectvelocityelements0text/plain1text/plaintypeTupleobjectid86128cc9b5ae8f4a!application/vnd.pluto.tree+objecttypeNamedTupleobjectida5ae9d4489cafe9e!application/vnd.pluto.tree+objectelementspositionelements5text/plain2text/plaintypeTupleobjectidb43f250e13820c5d!application/vnd.pluto.tree+objectvelocityelements0text/plain1text/plaintypeTupleobjectid86128cc9b5ae8f4a!application/vnd.pluto.tree+objecttypeNamedTupleobjectidc78b25d0de97c561!application/vnd.pluto.tree+objectelementspositionelements0text/plain0text/plaintypeTupleobjectid9b52efd7a2a08bd5!application/vnd.pluto.tree+objectvelocityelements0text/plain0text/plaintypeTupleobjectid9b52efd7a2a08bd5!application/vnd.pluto.tree+objecttypeNamedTupleobjectidd890206a17017f05!application/vnd.pluto.tree+objectelementspositionelements0text/plain1text/plaintypeTupleobjectid86128cc9b5ae8f4a!application/vnd.pluto.tree+objectvelocityelements0text/plain1text/plaintypeTupleobjectid86128cc9b5ae8f4a!application/vnd.pluto.tree+objecttypeNamedTupleobjectida73e50cd8a791327!application/vnd.pluto.tree+objectelementspositionelements1text/plain1text/plaintypeTupleobjectid78e123e4f427692a!application/vnd.pluto.tree+objectvelocityelements1text/plain0text/plaintypeTupleobjectid1539b04621ff8c7d!application/vnd.pluto.tree+objecttypeNamedTupleobjectid9cf524b963504fed!application/vnd.pluto.tree+objectelementspositionelements3text/plain1text/plaintypeTupleobjectidec7c7c340006434b!application/vnd.pluto.tree+objectvelocityelements2text/plain0text/plaintypeTupleobjectid83bf2aef4031930b!application/vnd.pluto.tree+objecttypeNamedTupleobjectidd15eb91b7380924b!application/vnd.pluto.tree+objectelementspositionelements5text/plain1text/plaintypeTupleobjectidaa0ea68f3321721e!application/vnd.pluto.tree+objectvelocityelements2text/plain0text/plaintypeTupleobjectid83bf2aef4031930b!application/vnd.pluto.tree+objecttypeNamedTupleobjectidb886071211e2d247!application/vnd.pluto.tree+object	elementspositionelements3text/plain0text/plaintypeTupleobjectidaa4c36dcad24fa29!application/vnd.pluto.tree+objectvelocityelements0text/plain0text/plaintypeTupleobjectid9b52efd7a2a08bd5!application/vnd.pluto.tree+objecttypeNamedTupleobjectidcbb4b2033bae62e6!application/vnd.pluto.tree+objectmore)elementspositionelements11text/plain31text/plaintypeTupleobjectid708b97aaecca0215!application/vnd.pluto.tree+objectvelocityelements2text/plain0text/plaintypeTupleobjectid83bf2aef4031930b!application/vnd.pluto.tree+objecttypeNamedTupleobjectid16b090449ff3fea9!application/vnd.pluto.tree+objecttypeArrayprefix_shortobjectidecbb05fe5d574067!application/vnd.pluto.tree+objectprefixTuple{Int64, Int64}elementselements0text/plain1text/plaintypeTupleobjectid86128cc9b5ae8f4a!application/vnd.pluto.tree+objectelements-1text/plain-1text/plaintypeTupleobjectida5f5003e88013c47!application/vnd.pluto.tree+objectelements0text/plain-1text/plaintypeTupleobjectid4b2797d2a8e67906!application/vnd.pluto.tree+objectelements-1text/plain-1text/plaintypeTupleobjectida5f5003e88013c47!application/vnd.pluto.tree+objectelements-1text/plain-1text/plaintypeTupleobjectida5f5003e88013c47!application/vnd.pluto.tree+objectelements1text/plain0text/plaintypeTupleobjectid1539b04621ff8c7d!application/vnd.pluto.tree+objectelements-1text/plain-1text/plaintypeTupleobjectida5f5003e88013c47!application/vnd.pluto.tree+objectelements-1text/plain-1text/plaintypeTupleobjectida5f5003e88013c47!application/vnd.pluto.tree+object	elements-1text/plain0text/plaintypeTupleobjectid29547c053cf46d53!application/vnd.pluto.tree+objectmore)elements1text/plain-1text/plaintypeTupleobjectid467534c86eaf64c9!application/vnd.pluto.tree+objecttypeArrayprefix_shortobjectid9e75db11c0cce9ef!application/vnd.pluto.tree+objectprefixFloat32elements-1.0text/plain-1.0text/plain-1.0text/plain-1.0text/plain-1.0text/plain-1.0text/plain-1.0text/plain-1.0text/plain	-1.0text/plainmore)-1.0text/plaintypeArrayprefix_shortobjectide00184e643e43cd3!application/vnd.pluto.tree+objecttypeTupleobjectid1f1e7dd1b96b7efemime!application/vnd.pluto.tree+objectrootassigneerace_episode1last_run_timestampA0`persist_js_state·has_pluto_hook_features§cell_id$3955d71a-3105-445a-868d-66ba0b3dc515depends_on_disabled_cells§runtime
;published_object_keysdepends_on_skipped_cells§errored$f406be9e-3e3f-4b55-99b0-4858c774ed96queued¤logsrunning¦outputbodyQ<div class="markdown"><h2>5.2 Monte Carlo Estimation of Action Values</h2>
</div>mimetext/htmlrootassigneelast_run_timestampA"&persist_js_state·has_pluto_hook_features§cell_id$f406be9e-3e3f-4b55-99b0-4858c774ed96depends_on_disabled_cells§runtime epublished_object_keysdepends_on_skipped_cells§errored$648bfc3f-0649-4401-a97f-89e21057f7b7queued¤logsrunning¦outputbodyk<div class="markdown"><p>Example trajectories after training for 1000 episodes with ϵ&#61; 0.01</p>
</div>mimetext/htmlrootassigneelast_run_timestampA3~persist_js_state·has_pluto_hook_features§cell_id$648bfc3f-0649-4401-a97f-89e21057f7b7depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$e10378eb-12b3-4468-9c22-1838107da450queued¤logsrunning¦outputbodyD<div class="markdown"><h3>Example 5.5: Infinite Variance</h3>
</div>mimetext/htmlrootassigneelast_run_timestampA"(<persist_js_state·has_pluto_hook_features§cell_id$e10378eb-12b3-4468-9c22-1838107da450depends_on_disabled_cells§runtime ԯpublished_object_keysdepends_on_skipped_cells§errored$2e57e4b5-d228-4ce3-b9d8-cf4375bb7c50queued¤logsrunning¦outputbody?<div class="markdown"><h1>Dependencies and Settings</h1>
</div>mimetext/htmlrootassigneelast_run_timestampA",Cpersist_js_state·has_pluto_hook_features§cell_id$2e57e4b5-d228-4ce3-b9d8-cf4375bb7c50depends_on_disabled_cells§runtime ⓵published_object_keysdepends_on_skipped_cells§errored$edb4ad06-5e6e-48c4-9ee4-ae0b92927a91queued¤logsrunning¦outputbodyX<div class="markdown"><p>Example trajectories after 1000 episodes of training</p>
</div>mimetext/htmlrootassigneelast_run_timestampA3(persist_js_state·has_pluto_hook_features§cell_id$edb4ad06-5e6e-48c4-9ee4-ae0b92927a91depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$9df79a71-e58a-497b-bb02-debb69144925queued¤logsrunning¦outputbodyprefixMDP_Opaque{@NamedTuple{position::Tuple{Int64, Int64}, velocity::Tuple{Int64, Int64}}, Tuple{Int64, Int64}, var"#simulator#140"{Float64, @NamedTuple{start::Set{Tuple{Int64, Int64}}, finish::Set{Tuple{Int64, Int64}}, body::Set{Tuple{Int64, Int64}}}, var"#take_action#139"{Dict{@NamedTuple{position::Tuple{Int64, Int64}, velocity::Tuple{Int64, Int64}}, Int64}}}, var"#state_init#138"{@NamedTuple{start::Set{Tuple{Int64, Int64}}, finish::Set{Tuple{Int64, Int64}}, body::Set{Tuple{Int64, Int64}}}}}elementsstatesprefixI@NamedTuple{position::Tuple{Int64, Int64}, velocity::Tuple{Int64, Int64}}elementselementspositionelements1text/plain28text/plaintypeTupleobjectid72e21e63940a8fea!application/vnd.pluto.tree+objectvelocityelements0text/plain0text/plaintypeTupleobjectid9b52efd7a2a08bd5!application/vnd.pluto.tree+objecttypeNamedTupleobjectide21e0d549cc4c557!application/vnd.pluto.tree+objectelementspositionelements1text/plain28text/plaintypeTupleobjectid72e21e63940a8fea!application/vnd.pluto.tree+objectvelocityelements0text/plain1text/plaintypeTupleobjectid86128cc9b5ae8f4a!application/vnd.pluto.tree+objecttypeNamedTupleobjectid7f58cd1418ac4ecf!application/vnd.pluto.tree+objectelementspositionelements1text/plain28text/plaintypeTupleobjectid72e21e63940a8fea!application/vnd.pluto.tree+objectvelocityelements0text/plain2text/plaintypeTupleobjectidfc41ae7a664555b0!application/vnd.pluto.tree+objecttypeNamedTupleobjectid1c9be938e1978e57!application/vnd.pluto.tree+objectelementspositionelements1text/plain28text/plaintypeTupleobjectid72e21e63940a8fea!application/vnd.pluto.tree+objectvelocityelements0text/plain3text/plaintypeTupleobjectid5a8d0f981b76571a!application/vnd.pluto.tree+objecttypeNamedTupleobjectidde42b54207e3ed51!application/vnd.pluto.tree+objectelementspositionelements1text/plain28text/plaintypeTupleobjectid72e21e63940a8fea!application/vnd.pluto.tree+objectvelocityelements0text/plain4text/plaintypeTupleobjectid6ac4b5902680c6bb!application/vnd.pluto.tree+objecttypeNamedTupleobjectidb60bb04f8974fbb6!application/vnd.pluto.tree+objectelementspositionelements1text/plain28text/plaintypeTupleobjectid72e21e63940a8fea!application/vnd.pluto.tree+objectvelocityelements1text/plain0text/plaintypeTupleobjectid1539b04621ff8c7d!application/vnd.pluto.tree+objecttypeNamedTupleobjectid811cc4bfed2188ee!application/vnd.pluto.tree+objectelementspositionelements1text/plain28text/plaintypeTupleobjectid72e21e63940a8fea!application/vnd.pluto.tree+objectvelocityelements1text/plain1text/plaintypeTupleobjectid78e123e4f427692a!application/vnd.pluto.tree+objecttypeNamedTupleobjectidba63b0bf4384bfeb!application/vnd.pluto.tree+objectelementspositionelements1text/plain28text/plaintypeTupleobjectid72e21e63940a8fea!application/vnd.pluto.tree+objectvelocityelements1text/plain2text/plaintypeTupleobjectide3e6b1884080a98d!application/vnd.pluto.tree+objecttypeNamedTupleobjectid588abfe8835e67f0!application/vnd.pluto.tree+object	elementspositionelements1text/plain28text/plaintypeTupleobjectid72e21e63940a8fea!application/vnd.pluto.tree+objectvelocityelements1text/plain3text/plaintypeTupleobjectid7d75a9159c58bddf!application/vnd.pluto.tree+objecttypeNamedTupleobjectide0a89afaeeb8cc2a!application/vnd.pluto.tree+objectmoreelementspositionelements11text/plain26text/plaintypeTupleobjectid1981f96b58fe709e!application/vnd.pluto.tree+objectvelocityelements4text/plain4text/plaintypeTupleobjectida7048b0d6f799239!application/vnd.pluto.tree+objecttypeNamedTupleobjectidd3ab164e30a99253!application/vnd.pluto.tree+objecttypeArrayprefix_shortobjectide421b5fa4b4d4a53!application/vnd.pluto.tree+objectstatelookupprefixVDict{@NamedTuple{position::Tuple{Int64, Int64}, velocity::Tuple{Int64, Int64}}, Int64}elementselementspositionelements11text/plain26text/plaintypeTupleobjectid1981f96b58fe709e!application/vnd.pluto.tree+objectvelocityelements1text/plain1text/plaintypeTupleobjectid78e123e4f427692a!application/vnd.pluto.tree+objecttypeNamedTupleobjectid971d69af0bd32d78!application/vnd.pluto.tree+object7282text/plainelementspositionelements1text/plain27text/plaintypeTupleobjectidc993a6666cbf7092!application/vnd.pluto.tree+objectvelocityelements1text/plain2text/plaintypeTupleobjectide3e6b1884080a98d!application/vnd.pluto.tree+objecttypeNamedTupleobjectid4d8f8079c2772807!application/vnd.pluto.tree+object1908text/plainelementspositionelements0text/plain19text/plaintypeTupleobjectid57770a702873d84e!application/vnd.pluto.tree+objectvelocityelements4text/plain4text/plaintypeTupleobjectida7048b0d6f799239!application/vnd.pluto.tree+objecttypeNamedTupleobjectida8405c040066ce51!application/vnd.pluto.tree+object3550text/plainelementspositionelements1text/plain22text/plaintypeTupleobjectid51a896f4005fc5cb!application/vnd.pluto.tree+objectvelocityelements1text/plain4text/plaintypeTupleobjectid3258627267de1f67!application/vnd.pluto.tree+objecttypeNamedTupleobjectidaaf4cf16033b1ed0!application/vnd.pluto.tree+object5310text/plainelementspositionelements5text/plain18text/plaintypeTupleobjectidf9eb085cdaf3608!application/vnd.pluto.tree+objectvelocityelements0text/plain0text/plaintypeTupleobjectid9b52efd7a2a08bd5!application/vnd.pluto.tree+objecttypeNamedTupleobjectidb1e9830ad348a6f5!application/vnd.pluto.tree+object6251text/plainelementspositionelements-2text/plain10text/plaintypeTupleobjectid9461b7cf1c0d4966!application/vnd.pluto.tree+objectvelocityelements4text/plain2text/plaintypeTupleobjectid27c77ee4a87cee0d!application/vnd.pluto.tree+objecttypeNamedTupleobjectiddfee357e5db661e7!application/vnd.pluto.tree+object223text/plainelementspositionelements5text/plain2text/plaintypeTupleobjectidb43f250e13820c5d!application/vnd.pluto.tree+objectvelocityelements0text/plain2text/plaintypeTupleobjectidfc41ae7a664555b0!application/vnd.pluto.tree+objecttypeNamedTupleobjectid8140d1c434ea8616!application/vnd.pluto.tree+object2703text/plainelementspositionelements-3text/plain25text/plaintypeTupleobjectidd19d751ad1b8973e!application/vnd.pluto.tree+objectvelocityelements2text/plain4text/plaintypeTupleobjectidfe67fb157b710308!application/vnd.pluto.tree+objecttypeNamedTupleobjectid67110a0493596685!application/vnd.pluto.tree+object2590text/plainelementspositionelements1text/plain28text/plaintypeTupleobjectid72e21e63940a8fea!application/vnd.pluto.tree+objectvelocityelements3text/plain0text/plaintypeTupleobjectidaa4c36dcad24fa29!application/vnd.pluto.tree+objecttypeNamedTupleobjectid500de2a9e8aa0c4f!application/vnd.pluto.tree+object16text/plainelementspositionelements3text/plain2text/plaintypeTupleobjectidc1258421771ca213!application/vnd.pluto.tree+objectvelocityelements4text/plain1text/plaintypeTupleobjectidab958923df88f7e9!application/vnd.pluto.tree+objecttypeNamedTupleobjectide0a57c37bcb0dd81!application/vnd.pluto.tree+object5972text/plainmoretypeDictprefix_shortDictobjectid90f6bc3c2d86001a!application/vnd.pluto.tree+objectactionsprefixTuple{Int64, Int64}elementselements-1text/plain-1text/plaintypeTupleobjectida5f5003e88013c47!application/vnd.pluto.tree+objectelements-1text/plain0text/plaintypeTupleobjectid29547c053cf46d53!application/vnd.pluto.tree+objectelements-1text/plain1text/plaintypeTupleobjectidd7f044f2876f60ea!application/vnd.pluto.tree+objectelements0text/plain-1text/plaintypeTupleobjectid4b2797d2a8e67906!application/vnd.pluto.tree+objectelements0text/plain0text/plaintypeTupleobjectid9b52efd7a2a08bd5!application/vnd.pluto.tree+objectelements0text/plain1text/plaintypeTupleobjectid86128cc9b5ae8f4a!application/vnd.pluto.tree+objectelements1text/plain-1text/plaintypeTupleobjectid467534c86eaf64c9!application/vnd.pluto.tree+objectelements1text/plain0text/plaintypeTupleobjectid1539b04621ff8c7d!application/vnd.pluto.tree+object	elements1text/plain1text/plaintypeTupleobjectid78e123e4f427692a!application/vnd.pluto.tree+objecttypeArrayprefix_shortobjectidd05a5360a94e8964!application/vnd.pluto.tree+objectactionlookupprefix Dict{Tuple{Int64, Int64}, Int64}elementselements0text/plain0text/plaintypeTupleobjectid9b52efd7a2a08bd5!application/vnd.pluto.tree+object5text/plainelements1text/plain-1text/plaintypeTupleobjectid467534c86eaf64c9!application/vnd.pluto.tree+object7text/plainelements-1text/plain0text/plaintypeTupleobjectid29547c053cf46d53!application/vnd.pluto.tree+object2text/plainelements0text/plain-1text/plaintypeTupleobjectid4b2797d2a8e67906!application/vnd.pluto.tree+object4text/plainelements0text/plain1text/plaintypeTupleobjectid86128cc9b5ae8f4a!application/vnd.pluto.tree+object6text/plainelements1text/plain1text/plaintypeTupleobjectid78e123e4f427692a!application/vnd.pluto.tree+object9text/plainelements-1text/plain-1text/plaintypeTupleobjectida5f5003e88013c47!application/vnd.pluto.tree+object1text/plainelements-1text/plain1text/plaintypeTupleobjectidd7f044f2876f60ea!application/vnd.pluto.tree+object3text/plainelements1text/plain0text/plaintypeTupleobjectid1539b04621ff8c7d!application/vnd.pluto.tree+object8text/plaintypeDictprefix_shortDictobjectida3900af5d2b89d05!application/vnd.pluto.tree+objectstate_initٿ(::Main.var"workspace#3".var"#state_init#138"{@NamedTuple{start::Set{Tuple{Int64, Int64}}, finish::Set{Tuple{Int64, Int64}}, body::Set{Tuple{Int64, Int64}}}}) (generic function with 1 method)text/plainsimulatorL(::Main.var"workspace#3".var"#simulator#140"{Float64, @NamedTuple{start::Set{Tuple{Int64, Int64}}, finish::Set{Tuple{Int64, Int64}}, body::Set{Tuple{Int64, Int64}}}, Main.var"workspace#3".var"#take_action#139"{Dict{@NamedTuple{position::Tuple{Int64, Int64}, velocity::Tuple{Int64, Int64}}, Int64}}}) (generic function with 1 method)text/plaintypestructprefix_shortMDP_Opaqueobjectidbc07d72df3db267amime!application/vnd.pluto.tree+objectrootassigneeconst track1_mdplast_run_timestampA/G$persist_js_state·has_pluto_hook_features§cell_id$9df79a71-e58a-497b-bb02-debb69144925depends_on_disabled_cells§runtimeppublished_object_keysdepends_on_skipped_cells§errored$cebb79b7-c9d6-4b79-ba0e-b2f3c7587724queued¤logsrunning¦outputbodyD<div class="markdown"><blockquote>
<h3><em>Exercise 5.12: Racetrack &#40;programming&#41;</em></h3>
<p>Consider driving a race car around a turn like those shown in Figure 5.5.  You want to go as fast as possible, but not so fast as to run off the track.  In our simplified racetrack, the car is at one of a discrete set of grid positions, the cells in the diagram.  The velocity is also discrete, a number of grid cells moved horizontally and vertically per time step.  The actions are increments to the velocity components.  Each may be changed by &#43;1, -1, or 0 in each step, for a total of nine &#40;3x3&#41; actions.  Both velocity components are restricted to be nonnegative and less than 5, and they cannot both be zero except at the starting line.  Each episode begins in one of the randomly selected start states with both velocity components zero and ends when the car crosses the finish line.  The rewards are -1 for each step until the car crosses the finish line.  If the car hits the track boundry, it is moved back to a random position on the starting line, both velocity components are reduced to zero, and the episode continues.  Before updating the car&#39;s location at each time step, check to see if the projected path of the car intersects the track boundary.  If it intersects the finish line, the episode ends; if it intersects anywhere else, the car is considered to have hit the track boundary and is sent back to the starting line.  To make the task more challenging, with probality 0.1 at each time step the velocity increments are both zero, independently of the intended increments.  Apply a Monte Carlo control method to this task to compute the optimal policy from each starting state.  Exhibit several trajectories following the optimal policy &#40;but turn the noise off for these trajectories&#41;.</p>
</blockquote>
</div>mimetext/htmlrootassigneelast_run_timestampA")$persist_js_state·has_pluto_hook_features§cell_id$cebb79b7-c9d6-4b79-ba0e-b2f3c7587724depends_on_disabled_cells§runtime 2ߵpublished_object_keysdepends_on_skipped_cells§errored$54f73eb8-dcea-4da0-83af-35720e56ccbcqueued¤logsrunning¦outputbody4monte_carlo_ϵsoft (generic function with 2 methods)mimetext/plainrootassigneelast_run_timestampA)ڰpersist_js_state·has_pluto_hook_features§cell_id$54f73eb8-dcea-4da0-83af-35720e56ccbcdepends_on_disabled_cells§runtime ,published_object_keysdepends_on_skipped_cells§errored$418c045d-90c7-42d8-9126-90185f7e197bqueued¤logsrunning¦outputbody <div class="markdown"><table><tr><th align="right"></th><th align="center"><span class="tex">$\pi_*$</span> &#40;Black &#61; Stick, White &#61; Hit&#41;</th><th align="center"><span class="tex">$v_*$</span></th></tr><tr><td align="right">Usable ace</td><td align="center">	<script id='plot_1'>
		// We start by putting all the variable interpolation here at the beginning
		// We have to convert all typedarrays in the layout to normal arrays. See Issue #25
		// We use lodash for this for compactness
		function removeTypedArray(o) {
			return _.isTypedArray(o) ? Array.from(o) :
			_.isPlainObject(o) ? _.mapValues(o, removeTypedArray) : 
			o
		}

		// Publish the plot object to JS
		let plot_obj = _.update(/* See the documentation for AbstractPlutoDingetjes.Display.published_to_js */ getPublishedObject("c6e0de0c-3901-11f0-234e-bd09c571f662/e97923405a5e6801"), "layout", removeTypedArray)
		// Get the plotly listeners
		const plotly_listeners = {}
		// Get the JS listeners
		const js_listeners = {}
		// Deal with eventual custom classes
		let custom_classlist = []


		// Load the plotly library
		let Plotly = undefined
		try {
			let _mod = await import("./plotlyjs/plotlyjs-2.26.2.min.js")
			Plotly = _mod.default
		} catch (e) {
			console.log("Local load failed, trying with the web esm.sh version")
			let _mod = await import("https://esm.sh/plotly.js-dist-min@2.26.2/es2022/plotly.js-dist-min.mjs")
			Plotly = _mod.default
		}

		// Check if we have to force local mathjax font cache
		if (false && window?.MathJax?.config?.svg?.fontCache === 'global') {
			window.MathJax.config.svg.fontCache = 'local'
		}

		// Flag to check if this cell was  manually ran or reactively ran
const firstRun = this ? false : true
const CONTAINER = this ?? html`<div class='plutoplotly-container'>`
const PLOT = CONTAINER.querySelector('.js-plotly-plot') ?? CONTAINER.appendChild(html`<div>`)
const parent = CONTAINER.parentElement
// We use a controller to remove event listeners upon invalidation
const controller = new AbortController()
// We have to add this to keep supporting @bind with the old API using PLOT
PLOT.addEventListener('input', (e) => {
	CONTAINER.value = PLOT.value
	if (e.bubbles) {
		return
	}
	CONTAINER.dispatchEvent(new CustomEvent('input'))
}, { signal: controller.signal })

	// This create the style subdiv on first run
	firstRun && CONTAINER.appendChild(html`
	<style>
	.plutoplotly-container {
		width: 100%;
		height: 100%;
		min-height: 0;
		min-width: 0;
	}
	.plutoplotly-container .js-plotly-plot .plotly div {
		margin: 0 auto; // This centers the plot
	}
	.plutoplotly-container.popped-out {
		overflow: auto;
		z-index: 1000;
		position: fixed;
		resize: both;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		border-top-left-radius: 0px;
		border-top-right-radius: 0px;
	}
	.plutoplotly-clipboard-header {
		display: flex;
		flex-flow: row wrap;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-top-left-radius: 12px;
		border-top-right-radius: 12px;
		position: fixed;
		z-index: 1001;
		cursor: move;
		transform: translate(0px, -100%);
		padding: 5px;
	}
	.plutoplotly-clipboard-header span {
		display: inline-block;
		flex: 1
	}
	.plutoplotly-clipboard-header.hidden {
		display: none;
	}
	.clipboard-span {
		position: relative;
	}
	.clipboard-value {
		padding-right: 5px;
		padding-left: 2px;
		cursor: text;
	}
	.clipboard-span.format {
		display: none;
	}
	.clipboard-span.filename {
		flex: 0 0 100%;
		text-align: center;
		border-top: 3px solid var(--kbd-border-color);
		margin-top: 5px;
		display: none;
	}
	.plutoplotly-container.filesave .clipboard-span.filename {
		display: inline-block;
	}
	.clipboard-value.filename {
		margin-left: 3px;
		text-align: left;
		min-width: min(60%, min-content);
	}
	.plutoplotly-container.filesave .clipboard-span.format {
		display: inline-flex;
	}
	.clipboard-span.format .label {
		flex: 0 0 0;
	}
	.clipboard-value.format {
		position: relative;
		flex: 1 0 auto;
		min-width: 30px;
		margin-right: 10px;
	}
	div.format-options {
		display: inline-flex;
		flex-flow: column;
		position: absolute;
		background: var(--main-bg-color);
		border-radius: 12px;
		padding-left: 3px;
		z-index: 2000;
	}
	div.format-options:hover {
		cursor: pointer;
		border: 3px solid var(--kbd-border-color);
		padding: 3px;
		transform: translate(-3px, -6px);
	}
	div.format-options .format-option {
		display: none;
	}
	div.format-options:hover .format-option {
		display: inline-block;
	}
	.format-option:not(.selected) {
		margin-top: 3px;
	}
	div.format-options .format-option.selected {
		order: -1;
		display: inline-block;
	}
	.format-option:hover {
		background-color: var(--kbd-border-color);
	}
	span.config-value {
		font-weight: normal;
		color: var(--pluto-output-color);
		display: none;
		position: absolute;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		transform: translate(0px, calc(-100% - 10px));
		padding: 5px;
	}
	.label {
		user-select: none;
	}
	.label:hover span.config-value {
		display: inline-block;
		min-width: 150px;
	}
	.clipboard-span.matching-config .label {
		color: var(--cm-macro-color);
		font-weight: bold;
	}
	.clipboard-span.different-config .label {
		color: var(--cm-tag-color);
		font-weight: bold;
	}
</style>
`)

let original_height = plot_obj.layout.height
let original_width = plot_obj.layout.width
// For the height we have to also put a fixed value in case the plot is put on a non-fixed-size container (like the default wrapper)
// We define a variable to check whether we still have to remove the fixed height
let remove_container_size = firstRun
let container_height = original_height ?? PLOT.container_height ?? 400
CONTAINER.style.height = container_height + 'px'

// We create a Promise version of setTimeout
function delay(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

// We import interact for dragging/resizing
const { default: interact } = await import('https://esm.sh/interactjs@1.10.19')


function getImageOptions() {
  const o = plot_obj.config.toImageButtonOptions ?? {};
  return {
    format: o.format ?? "png",
    width: o.width ?? original_width,
    height: o.height ?? original_height,
    scale: o.scale ?? 1,
    filename: o.filename ?? "newplot",
  };
}

const CLIPBOARD_HEADER =
  CONTAINER.querySelector(".plutoplotly-clipboard-header") ??
  CONTAINER.insertAdjacentElement(
    "afterbegin",
    html`<div class="plutoplotly-clipboard-header hidden">
      <span class="clipboard-span format"
        ><span class="label">Format:</span
        ><span class="clipboard-value format"></span
      ></span>
      <span class="clipboard-span width"
        ><span class="label">Width:</span
        ><span class="clipboard-value width"></span>px</span
      >
      <span class="clipboard-span height"
        ><span class="label">Height:</span
        ><span class="clipboard-value height"></span>px</span
      >
      <span class="clipboard-span scale"
        ><span class="label">Scale:</span
        ><span class="clipboard-value scale"></span
      ></span>
      <button class="clipboard-span set">Set</button>
      <button class="clipboard-span unset">Unset</button>
      <span class="clipboard-span filename"
        ><span class="label">Filename:</span
        ><span class="clipboard-value filename"></span
      ></span>
    </div>`
  );

function checkConfigSync(container) {
  const valid_classes = [
    "missing-config",
    "matching-config",
    "different-config",
  ];
  function setClass(cl) {
    for (const name of valid_classes) {
      container.classList.toggle(name, name == cl);
    }
  }
  // We use the custom getters we'll set up in the container
  const { ui_value, config_value, config_span, key } = container;
  if (config_value === undefined) {
    setClass("missing-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> is not present in the config.`;
  } else if (ui_value == config_value) {
    setClass("matching-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has the same value in the config and in the header.`;
  } else {
    setClass("different-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has a different value (<em>${config_value}</em>) in the config.`;
  }
  // Add info about setting and unsetting
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click on the label <em><b>once</b></em> to set the current UI value in the config.`
  );
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click <em><b>twice</b></em> to remove this key from the config.`
  );
}

const valid_formats = ["png", "svg", "webp", "jpeg", "full-json"];
function initializeUIValueSpan(span, key, value) {
  const container = span.closest(".clipboard-span");
  span.contentEditable = key === "format" ? "false" : "true";
  let parse = (x) => x;
  let update = (x) => (span.textContent = x);
  if (key === "width" || key === "height") {
    parse = (x) => Math.round(parseFloat(x));
  } else if (key === "scale") {
    parse = parseFloat;
  } else if (key === "format") {
    // We remove contentEditable
    span.contentEditable = "false";
    // Here we first add the subspans for each option
    const opts_div = span.appendChild(html`<div class="format-options"></div>`);
    for (const fmt of valid_formats) {
      const opt = opts_div.appendChild(
        html`<span class="format-option ${fmt}">${fmt}</span>`
      );
      opt.onclick = (e) => {
        span.value = opt.textContent;
      };
    }
    parse = (x) => {
      return valid_formats.includes(x) ? x : localValue;
    };
    update = (x) => {
      for (const opt of opts_div.children) {
        opt.classList.toggle("selected", opt.textContent === x);
      }
    };
  } else {
    // We only have filename here
  }
  let localValue;
  Object.defineProperty(span, "value", {
    get: () => {
      return localValue;
    },
    set: (val) => {
      if (val !== "") {
        localValue = parse(val);
      }
      update(localValue);
      checkConfigSync(container);
    },
  });
  // We also assign a listener so that the editable is blurred when enter is pressed
  span.onkeydown = (e) => {
    if (e.keyCode === 13) {
      e.preventDefault();
      span.blur();
    }
  };
  span.value = value;
}

function initializeConfigValueSpan(span, key) {
  // Here we mostly want to define the setter and getter
  const container = span.closest(".clipboard-span");
  Object.defineProperty(span, "value", {
    get: () => {
      return plot_obj.config.toImageButtonOptions[key];
    },
    set: (val) => {
      // if undefined is passed, we remove the entry from the options
      if (val === undefined) {
        delete plot_obj.config.toImageButtonOptions[key];
      } else {
        plot_obj.config.toImageButtonOptions[key] = val;
      }
      checkConfigSync(container);
    },
  });
}

const config_spans = {};
for (const [key, value] of Object.entries(getImageOptions())) {
  const container = CLIPBOARD_HEADER.querySelector(`.clipboard-span.${key}`);
  const label = container.querySelector(".label");
  // We give the label a function that on single click will set the current value and with double click will unset it
  label.onclick = DualClick(
    () => {
      container.config_value = container.ui_value;
    },
    (e) => {
      console.log("e", e);
      e.preventDefault();
      container.config_value = undefined;
    }
  );
  const ui_value_span = container.querySelector(".clipboard-value");
  const config_value_span =
    container.querySelector(".config-value") ??
    label.insertAdjacentElement(
      "afterbegin",
      html`<span class="config-value"></span>`
    );
  // Assing the two spans as properties of the containing span
  container.ui_span = ui_value_span;
  container.config_span = config_value_span;
  container.key = key;
  config_spans[key] = container;
  if (firstRun) {
    plot_obj.config.toImageButtonOptions =
      plot_obj.config.toImageButtonOptions ?? {};
    // We do the initialization of the value span
    initializeUIValueSpan(ui_value_span, key, value);
    // Then we initialize the config value
    initializeConfigValueSpan(config_value_span, key);
    // We put some convenience getters/setters
    // ui_value forward
    Object.defineProperty(container, "ui_value", {
      get: () => ui_value_span.value,
      set: (val) => {
        ui_value_span.value = val;
      },
    });
    // config_value forward
    Object.defineProperty(container, "config_value", {
      get: () => config_value_span.value,
      set: (val) => {
        config_value_span.value = val;
      },
    });
  }
}

// These objects will contain the default value

// This code updates the image options in the PLOT config with the provided ones
function setImageOptions(o) {
  for (const [key, container] of Object.entries(config_spans)) {
    container.config_value = o[key];
  }
}
function unsetImageOptions() {
  setImageOptions({});
}

const set_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.set");
const unset_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.unset");
if (firstRun) {
  set_button.onclick = (e) => {
    for (const container of Object.values(config_spans)) {
      container.config_value = container.ui_value;
    }
  };
  unset_button.onclick = unsetImageOptions;
}

// We add a function to check if the clipboard is popped out
CONTAINER.isPoppedOut = () => {
  return CONTAINER.classList.contains("popped-out");
};

CLIPBOARD_HEADER.onmousedown = function (event) {
  if (event.target.matches("span.clipboard-value")) {
    console.log("We don't move!");
    return;
  }
  const start = {
    left: parseFloat(CONTAINER.style.left),
    top: parseFloat(CONTAINER.style.top),
    X: event.pageX,
    Y: event.pageY,
  };
  function moveAt(event, start) {
    const top = event.pageY - start.Y + start.top + "px";
    const left = event.pageX - start.X + start.left + "px";
    CLIPBOARD_HEADER.style.left = left;
    CONTAINER.style.left = left;
    CONTAINER.style.top = top;
  }

  // move our absolutely positioned ball under the pointer
  moveAt(event, start);
  function onMouseMove(event) {
    moveAt(event, start);
  }

  // We use this to remove the mousemove when clicking outside of the container
  const controller = new AbortController();

  // move the container on mousemove
  document.addEventListener("mousemove", onMouseMove, {
    signal: controller.signal,
  });
  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        cleanUp();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );

  function cleanUp() {
    console.log("cleaning up the plot move listener");
    controller.abort();
    CLIPBOARD_HEADER.onmouseup = null;
  }

  // (3) drop the ball, remove unneeded handlers
  CLIPBOARD_HEADER.onmouseup = cleanUp;
};

function sendToClipboard(blob) {
  if (!navigator.clipboard) {
    alert(
      "The Clipboard API does not seem to be available, make sure the Pluto notebook is being used from either localhost or an https source."
    );
  }
  navigator.clipboard
    .write([
      new ClipboardItem({
        // The key is determined dynamically based on the blob's type.
        [blob.type]: blob,
      }),
    ])
    .then(
      function () {
        console.log("Async: Copying to clipboard was successful!");
      },
      function (err) {
        console.error("Async: Could not copy text: ", err);
      }
    );
}

function copyImageToClipboard() {
  // We extract the image options from the provided parameters (if they exist)
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key. We also ignore format because the clipboard only supports png.
    if (val === undefined || key === "format") {
      continue;
    }
    config[key] = val;
  }
  Plotly.toImage(PLOT, config).then(function (dataUrl) {
    fetch(dataUrl)
      .then((res) => res.blob())
      .then((blob) => {
        const paste_receiver = document.querySelector('paste-receiver.plutoplotly')
        if (paste_receiver) {
          paste_receiver.attachImage(dataUrl, CONTAINER)
        }
        sendToClipboard(blob)
      });
  });
}

function saveImageToFile() {
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key.
    if (val === undefined) {
      continue;
    }
    config[key] = val;
  }
  Plotly.downloadImage(PLOT, config);
}

let container_rect = { width: 0, height: 0, top: 0, left: 0 };
function unpop_container(cl) {
  CONTAINER.classList.toggle("popped-out", false);
  CONTAINER.classList.toggle(cl, false);
  // We fix the height back to the value it had before popout, also setting the flag to signal that upon first resize we remove the fixed inline-style
  CONTAINER.style.height = container_rect.height + "px";
  remove_container_size = true;
  // We set the other fixed inline-styles to null
  CONTAINER.style.width = "";
  CONTAINER.style.top = "";
  CONTAINER.style.left = "";
  // We also remove the CLIPBOARD_HEADER
  CLIPBOARD_HEADER.style.width = "";
  CLIPBOARD_HEADER.style.left = "";
  // Finally we remove the hidden class to the header
  CLIPBOARD_HEADER.classList.toggle("hidden", true);
  return;
}
function popout_container(opts) {
  const cl = opts?.cl;
  const target_container_size = opts?.target_container_size ?? {};
  const target_plot_size = opts?.target_plot_size ?? {};
  if (CONTAINER.isPoppedOut()) {
    return unpop_container(cl);
  }
  CONTAINER.classList.toggle(cl, cl === undefined ? false : true);
  // We extract the current size of the container, save them and fix them
  const { width, height, top, left } = CONTAINER.getBoundingClientRect();
  container_rect = { width, height, top, left };
  // We save the current plot size before we pop as it will fill the screen
  const current_plot_size = {
    width: PLOT._fullLayout.width,
    height: PLOT._fullLayout.height,
  };
  // We have to save the pad data before popping so we can resize precisely
  const pad = {};
  pad.unpopped = getSizeData().container_pad;
  CONTAINER.classList.toggle("popped-out", true);
  pad.popped = getSizeData().container_pad;
  // We do top and left based on the current rect
  for (const key of ["top", "left"]) {
    const start_val = target_container_size[key] ?? container_rect[key];
    let offset = 0;
    for (const kind of ["padding", "border"]) {
      offset += pad.popped[kind][key] - pad.unpopped[kind][key];
    }
    CONTAINER.style[key] = start_val - offset + "px";
    if (key === "left") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  // We compute the width and height depending on eventual config data
  const csz = computeContainerSize({
    width:
      target_plot_size.width ??
      config_spans.width.config_value ??
      current_plot_size.width,
    height:
      target_plot_size.height ??
      config_spans.height.config_value ??
      current_plot_size.height,
  });
  for (const key of ["width", "height"]) {
    const val = target_container_size[key] ?? csz[key];
    CONTAINER.style[key] = val + "px";
    if (key === "width") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  CLIPBOARD_HEADER.classList.toggle("hidden", false);
  const controller = new AbortController();

  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        unpop_container();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );
}

CONTAINER.popOut = popout_container;

function DualClick(single_func, dbl_func) {
  let nclicks = 0;
  return function (...args) {
    nclicks += 1;
    if (nclicks > 1) {
      dbl_func(...args);
      nclicks = 0;
    } else {
      delay(300).then(() => {
        if (nclicks == 1) {
          single_func(...args);
        }
        nclicks = 0;
      });
    }
  };
}

// We remove the default download image button
plot_obj.config.modeBarButtonsToRemove = _.union(
  plot_obj.config.modeBarButtonsToRemove,
  ["toImage"]
);
// We add the custom button to the modebar
plot_obj.config.modeBarButtonsToAdd = _.union(
  plot_obj.config.modeBarButtonsToAdd,
  [
    {
      name: "Copy PNG to Clipboard",
      icon: {
        height: 520,
        width: 520,
        path: "M280 64h40c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128C0 92.7 28.7 64 64 64h40 9.6C121 27.5 153.3 0 192 0s71 27.5 78.4 64H280zM64 112c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16H320c8.8 0 16-7.2 16-16V128c0-8.8-7.2-16-16-16H304v24c0 13.3-10.7 24-24 24H192 104c-13.3 0-24-10.7-24-24V112H64zm128-8a24 24 0 1 0 0-48 24 24 0 1 0 0 48z",
      },
      direction: "up",
      click: DualClick(copyImageToClipboard, () => {
        popout_container();
      }),
    },
    {
      name: "Download Image",
      icon: Plotly.Icons.camera,
      direction: "up",
      click: DualClick(saveImageToFile, () => {
        popout_container({ cl: "filesave" });
      }),
    },
  ]
);

function getOffsetData(el) {
  let cs = window.getComputedStyle(el, null);
  const odata = {
    padding: {
      left: parseFloat(cs.paddingLeft),
      right: parseFloat(cs.paddingRight),
      top: parseFloat(cs.paddingTop),
      bottom: parseFloat(cs.paddingBottom),
      width: parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight),
      height: parseFloat(cs.paddingTop) + parseFloat(cs.paddingBottom),
    },
    border: {
      left: parseFloat(cs.borderLeftWidth),
      right: parseFloat(cs.borderRightWidth),
      top: parseFloat(cs.borderTopWidth),
      bottom: parseFloat(cs.borderBottomWidth),
      width: parseFloat(cs.borderLeftWidth) + parseFloat(cs.borderRightWidth),
      height: parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth),
    }
  };
  if (el === PLOT) {
    // For the PLOT we also want to take into account the offset
    odata.offset = {
      top: PLOT.offsetParent == CONTAINER ? PLOT.offsetTop : 0,
      left: PLOT.offsetParent == CONTAINER ? PLOT.offsetLeft : 0,
    }
  }
  return odata;
}
function getSizeData() {
  const data = {
    plot_pad: getOffsetData(PLOT),
    plot_rect: PLOT.getBoundingClientRect(),
    container_pad: getOffsetData(CONTAINER),
    container_rect: CONTAINER.getBoundingClientRect(),
  };
  return data;
}
function computeContainerSize({ width, height }, sizeData = getSizeData()) {
  const computed_size = computePlotSize(sizeData);
  const offsets = computed_size.offsets;

  const plot_data = {
    width: width ?? computed_size.width,
    height: height ?? computed_size.height,
  };

  return {
    width: (width ?? computed_size.width) + offsets.width,
    height: (height ?? computed_size.height) + offsets.height,
    noChange: width == computed_size.width && height == computed_size.height,
  }
}

// This function will change the container size so that the resulting plot will be matching the provided specs
function changeContainerSize({ width, height }, sizeData = getSizeData()) {
  if (!CONTAINER.isPoppedOut()) {
    console.log("Tried to change container size when not popped, ignoring");
    return;
  }

  const csz = computeContainerSize({ width, height }, sizeData);

  if (csz.noChange) {
    console.log("Size is the same as current, ignoring");
    return
  }
  // We are now going to set he width and height of the container
  for (const key of ["width", "height"]) {
    CONTAINER.style[key] = csz[key] + "px";
  }
}
// We now create the function that will update the plot based on the values specified
function updateFromHeader() {
  const header_data = {
    height: config_spans.height.ui_value,
    width: config_spans.width.ui_value,
  };
  changeContainerSize(header_data);
}
// We assign this function to the onblur event of width and height
if (firstRun) {
  for (const container of Object.values(config_spans)) {
    container.ui_span.onblur = (e) => {
      container.ui_value = container.ui_span.textContent;
      updateFromHeader();
    };
  }
}
// This function computes the plot size to use for relayout as a function of the container size
function computePlotSize(data = getSizeData()) {
  // Remove Padding
  const { container_pad, plot_pad, container_rect } = data;
  const offsets = {
    width:
      plot_pad.padding.width +
      plot_pad.border.width +
      plot_pad.offset.left +
      container_pad.padding.width +
      container_pad.border.width,
    height:
      plot_pad.padding.height +
      plot_pad.border.height +
      plot_pad.offset.top +
      container_pad.padding.height +
      container_pad.border.height,
  };
  const sz = {
    width: Math.round(container_rect.width - offsets.width),
    height: Math.round(container_rect.height - offsets.height),
    offsets,
  };
  return sz;
}

// Create the resizeObserver to make the plot even more responsive! :magic:
const resizeObserver = new ResizeObserver((entries) => {
  const sizeData = getSizeData();
  const {container_rect, container_pad} = sizeData;
  let plot_size = computePlotSize(sizeData);
  // We save the height in the PLOT object
  PLOT.container_height = container_rect.height;
  // We deal with some stuff if the container is poppped
  CLIPBOARD_HEADER.style.width = container_rect.width + "px";
  CLIPBOARD_HEADER.style.left = container_rect.left + "px";
  config_spans.height.ui_value = plot_size.height;
  config_spans.width.ui_value = plot_size.width;
  /* 
		The addition of the invalid argument `plutoresize` seems to fix the problem with calling `relayout` simply with `{autosize: true}` as update breaking mouse relayout events tracking. 
		See https://github.com/plotly/plotly.js/issues/6156 for details
		*/
  let config = {
    // If this is popped out, we ignore the original width/height
    width: (CONTAINER.isPoppedOut() ? undefined : original_width) ?? plot_size.width,
    height: (CONTAINER.isPoppedOut() ? undefined : original_height) ?? plot_size.height,
    plutoresize: true,
  };
  Plotly.relayout(PLOT, config).then(() => {
    if (remove_container_size && !CONTAINER.isPoppedOut()) {
      // This is needed to avoid the first resize upon plot creation to already be without a fixed height
      CONTAINER.style.height = "";
      CONTAINER.style.width = "";
      remove_container_size = false;
    }
  });
});

resizeObserver.observe(CONTAINER);


Plotly.react(PLOT, plot_obj).then(() => {
	// Assign the Plotly event listeners
	for (const [key, listener_vec] of Object.entries(plotly_listeners)) {
		for (const listener of listener_vec) {
			PLOT.on(key, listener)
		}
	}
	// Assign the JS event listeners
	for (const [key, listener_vec] of Object.entries(js_listeners)) {
		for (const listener of listener_vec) {
			PLOT.addEventListener(key, listener, {
				signal: controller.signal
			})
		}
	}
}
)


invalidation.then(() => {
	// Remove all plotly listeners
	PLOT.removeAllListeners()
	// Remove all JS listeners
	controller.abort()
	// Remove the resizeObserver
	resizeObserver.disconnect()
})



		return CONTAINER
	</script>
</td><td align="center">	<script id='plot_2'>
		// We start by putting all the variable interpolation here at the beginning
		// We have to convert all typedarrays in the layout to normal arrays. See Issue #25
		// We use lodash for this for compactness
		function removeTypedArray(o) {
			return _.isTypedArray(o) ? Array.from(o) :
			_.isPlainObject(o) ? _.mapValues(o, removeTypedArray) : 
			o
		}

		// Publish the plot object to JS
		let plot_obj = _.update(/* See the documentation for AbstractPlutoDingetjes.Display.published_to_js */ getPublishedObject("c6e0de0c-3901-11f0-234e-bd09c571f662/317eb0286b9488bc"), "layout", removeTypedArray)
		// Get the plotly listeners
		const plotly_listeners = {}
		// Get the JS listeners
		const js_listeners = {}
		// Deal with eventual custom classes
		let custom_classlist = []


		// Load the plotly library
		let Plotly = undefined
		try {
			let _mod = await import("./plotlyjs/plotlyjs-2.26.2.min.js")
			Plotly = _mod.default
		} catch (e) {
			console.log("Local load failed, trying with the web esm.sh version")
			let _mod = await import("https://esm.sh/plotly.js-dist-min@2.26.2/es2022/plotly.js-dist-min.mjs")
			Plotly = _mod.default
		}

		// Check if we have to force local mathjax font cache
		if (false && window?.MathJax?.config?.svg?.fontCache === 'global') {
			window.MathJax.config.svg.fontCache = 'local'
		}

		// Flag to check if this cell was  manually ran or reactively ran
const firstRun = this ? false : true
const CONTAINER = this ?? html`<div class='plutoplotly-container'>`
const PLOT = CONTAINER.querySelector('.js-plotly-plot') ?? CONTAINER.appendChild(html`<div>`)
const parent = CONTAINER.parentElement
// We use a controller to remove event listeners upon invalidation
const controller = new AbortController()
// We have to add this to keep supporting @bind with the old API using PLOT
PLOT.addEventListener('input', (e) => {
	CONTAINER.value = PLOT.value
	if (e.bubbles) {
		return
	}
	CONTAINER.dispatchEvent(new CustomEvent('input'))
}, { signal: controller.signal })

	// This create the style subdiv on first run
	firstRun && CONTAINER.appendChild(html`
	<style>
	.plutoplotly-container {
		width: 100%;
		height: 100%;
		min-height: 0;
		min-width: 0;
	}
	.plutoplotly-container .js-plotly-plot .plotly div {
		margin: 0 auto; // This centers the plot
	}
	.plutoplotly-container.popped-out {
		overflow: auto;
		z-index: 1000;
		position: fixed;
		resize: both;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		border-top-left-radius: 0px;
		border-top-right-radius: 0px;
	}
	.plutoplotly-clipboard-header {
		display: flex;
		flex-flow: row wrap;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-top-left-radius: 12px;
		border-top-right-radius: 12px;
		position: fixed;
		z-index: 1001;
		cursor: move;
		transform: translate(0px, -100%);
		padding: 5px;
	}
	.plutoplotly-clipboard-header span {
		display: inline-block;
		flex: 1
	}
	.plutoplotly-clipboard-header.hidden {
		display: none;
	}
	.clipboard-span {
		position: relative;
	}
	.clipboard-value {
		padding-right: 5px;
		padding-left: 2px;
		cursor: text;
	}
	.clipboard-span.format {
		display: none;
	}
	.clipboard-span.filename {
		flex: 0 0 100%;
		text-align: center;
		border-top: 3px solid var(--kbd-border-color);
		margin-top: 5px;
		display: none;
	}
	.plutoplotly-container.filesave .clipboard-span.filename {
		display: inline-block;
	}
	.clipboard-value.filename {
		margin-left: 3px;
		text-align: left;
		min-width: min(60%, min-content);
	}
	.plutoplotly-container.filesave .clipboard-span.format {
		display: inline-flex;
	}
	.clipboard-span.format .label {
		flex: 0 0 0;
	}
	.clipboard-value.format {
		position: relative;
		flex: 1 0 auto;
		min-width: 30px;
		margin-right: 10px;
	}
	div.format-options {
		display: inline-flex;
		flex-flow: column;
		position: absolute;
		background: var(--main-bg-color);
		border-radius: 12px;
		padding-left: 3px;
		z-index: 2000;
	}
	div.format-options:hover {
		cursor: pointer;
		border: 3px solid var(--kbd-border-color);
		padding: 3px;
		transform: translate(-3px, -6px);
	}
	div.format-options .format-option {
		display: none;
	}
	div.format-options:hover .format-option {
		display: inline-block;
	}
	.format-option:not(.selected) {
		margin-top: 3px;
	}
	div.format-options .format-option.selected {
		order: -1;
		display: inline-block;
	}
	.format-option:hover {
		background-color: var(--kbd-border-color);
	}
	span.config-value {
		font-weight: normal;
		color: var(--pluto-output-color);
		display: none;
		position: absolute;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		transform: translate(0px, calc(-100% - 10px));
		padding: 5px;
	}
	.label {
		user-select: none;
	}
	.label:hover span.config-value {
		display: inline-block;
		min-width: 150px;
	}
	.clipboard-span.matching-config .label {
		color: var(--cm-macro-color);
		font-weight: bold;
	}
	.clipboard-span.different-config .label {
		color: var(--cm-tag-color);
		font-weight: bold;
	}
</style>
`)

let original_height = plot_obj.layout.height
let original_width = plot_obj.layout.width
// For the height we have to also put a fixed value in case the plot is put on a non-fixed-size container (like the default wrapper)
// We define a variable to check whether we still have to remove the fixed height
let remove_container_size = firstRun
let container_height = original_height ?? PLOT.container_height ?? 400
CONTAINER.style.height = container_height + 'px'

// We create a Promise version of setTimeout
function delay(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

// We import interact for dragging/resizing
const { default: interact } = await import('https://esm.sh/interactjs@1.10.19')


function getImageOptions() {
  const o = plot_obj.config.toImageButtonOptions ?? {};
  return {
    format: o.format ?? "png",
    width: o.width ?? original_width,
    height: o.height ?? original_height,
    scale: o.scale ?? 1,
    filename: o.filename ?? "newplot",
  };
}

const CLIPBOARD_HEADER =
  CONTAINER.querySelector(".plutoplotly-clipboard-header") ??
  CONTAINER.insertAdjacentElement(
    "afterbegin",
    html`<div class="plutoplotly-clipboard-header hidden">
      <span class="clipboard-span format"
        ><span class="label">Format:</span
        ><span class="clipboard-value format"></span
      ></span>
      <span class="clipboard-span width"
        ><span class="label">Width:</span
        ><span class="clipboard-value width"></span>px</span
      >
      <span class="clipboard-span height"
        ><span class="label">Height:</span
        ><span class="clipboard-value height"></span>px</span
      >
      <span class="clipboard-span scale"
        ><span class="label">Scale:</span
        ><span class="clipboard-value scale"></span
      ></span>
      <button class="clipboard-span set">Set</button>
      <button class="clipboard-span unset">Unset</button>
      <span class="clipboard-span filename"
        ><span class="label">Filename:</span
        ><span class="clipboard-value filename"></span
      ></span>
    </div>`
  );

function checkConfigSync(container) {
  const valid_classes = [
    "missing-config",
    "matching-config",
    "different-config",
  ];
  function setClass(cl) {
    for (const name of valid_classes) {
      container.classList.toggle(name, name == cl);
    }
  }
  // We use the custom getters we'll set up in the container
  const { ui_value, config_value, config_span, key } = container;
  if (config_value === undefined) {
    setClass("missing-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> is not present in the config.`;
  } else if (ui_value == config_value) {
    setClass("matching-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has the same value in the config and in the header.`;
  } else {
    setClass("different-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has a different value (<em>${config_value}</em>) in the config.`;
  }
  // Add info about setting and unsetting
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click on the label <em><b>once</b></em> to set the current UI value in the config.`
  );
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click <em><b>twice</b></em> to remove this key from the config.`
  );
}

const valid_formats = ["png", "svg", "webp", "jpeg", "full-json"];
function initializeUIValueSpan(span, key, value) {
  const container = span.closest(".clipboard-span");
  span.contentEditable = key === "format" ? "false" : "true";
  let parse = (x) => x;
  let update = (x) => (span.textContent = x);
  if (key === "width" || key === "height") {
    parse = (x) => Math.round(parseFloat(x));
  } else if (key === "scale") {
    parse = parseFloat;
  } else if (key === "format") {
    // We remove contentEditable
    span.contentEditable = "false";
    // Here we first add the subspans for each option
    const opts_div = span.appendChild(html`<div class="format-options"></div>`);
    for (const fmt of valid_formats) {
      const opt = opts_div.appendChild(
        html`<span class="format-option ${fmt}">${fmt}</span>`
      );
      opt.onclick = (e) => {
        span.value = opt.textContent;
      };
    }
    parse = (x) => {
      return valid_formats.includes(x) ? x : localValue;
    };
    update = (x) => {
      for (const opt of opts_div.children) {
        opt.classList.toggle("selected", opt.textContent === x);
      }
    };
  } else {
    // We only have filename here
  }
  let localValue;
  Object.defineProperty(span, "value", {
    get: () => {
      return localValue;
    },
    set: (val) => {
      if (val !== "") {
        localValue = parse(val);
      }
      update(localValue);
      checkConfigSync(container);
    },
  });
  // We also assign a listener so that the editable is blurred when enter is pressed
  span.onkeydown = (e) => {
    if (e.keyCode === 13) {
      e.preventDefault();
      span.blur();
    }
  };
  span.value = value;
}

function initializeConfigValueSpan(span, key) {
  // Here we mostly want to define the setter and getter
  const container = span.closest(".clipboard-span");
  Object.defineProperty(span, "value", {
    get: () => {
      return plot_obj.config.toImageButtonOptions[key];
    },
    set: (val) => {
      // if undefined is passed, we remove the entry from the options
      if (val === undefined) {
        delete plot_obj.config.toImageButtonOptions[key];
      } else {
        plot_obj.config.toImageButtonOptions[key] = val;
      }
      checkConfigSync(container);
    },
  });
}

const config_spans = {};
for (const [key, value] of Object.entries(getImageOptions())) {
  const container = CLIPBOARD_HEADER.querySelector(`.clipboard-span.${key}`);
  const label = container.querySelector(".label");
  // We give the label a function that on single click will set the current value and with double click will unset it
  label.onclick = DualClick(
    () => {
      container.config_value = container.ui_value;
    },
    (e) => {
      console.log("e", e);
      e.preventDefault();
      container.config_value = undefined;
    }
  );
  const ui_value_span = container.querySelector(".clipboard-value");
  const config_value_span =
    container.querySelector(".config-value") ??
    label.insertAdjacentElement(
      "afterbegin",
      html`<span class="config-value"></span>`
    );
  // Assing the two spans as properties of the containing span
  container.ui_span = ui_value_span;
  container.config_span = config_value_span;
  container.key = key;
  config_spans[key] = container;
  if (firstRun) {
    plot_obj.config.toImageButtonOptions =
      plot_obj.config.toImageButtonOptions ?? {};
    // We do the initialization of the value span
    initializeUIValueSpan(ui_value_span, key, value);
    // Then we initialize the config value
    initializeConfigValueSpan(config_value_span, key);
    // We put some convenience getters/setters
    // ui_value forward
    Object.defineProperty(container, "ui_value", {
      get: () => ui_value_span.value,
      set: (val) => {
        ui_value_span.value = val;
      },
    });
    // config_value forward
    Object.defineProperty(container, "config_value", {
      get: () => config_value_span.value,
      set: (val) => {
        config_value_span.value = val;
      },
    });
  }
}

// These objects will contain the default value

// This code updates the image options in the PLOT config with the provided ones
function setImageOptions(o) {
  for (const [key, container] of Object.entries(config_spans)) {
    container.config_value = o[key];
  }
}
function unsetImageOptions() {
  setImageOptions({});
}

const set_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.set");
const unset_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.unset");
if (firstRun) {
  set_button.onclick = (e) => {
    for (const container of Object.values(config_spans)) {
      container.config_value = container.ui_value;
    }
  };
  unset_button.onclick = unsetImageOptions;
}

// We add a function to check if the clipboard is popped out
CONTAINER.isPoppedOut = () => {
  return CONTAINER.classList.contains("popped-out");
};

CLIPBOARD_HEADER.onmousedown = function (event) {
  if (event.target.matches("span.clipboard-value")) {
    console.log("We don't move!");
    return;
  }
  const start = {
    left: parseFloat(CONTAINER.style.left),
    top: parseFloat(CONTAINER.style.top),
    X: event.pageX,
    Y: event.pageY,
  };
  function moveAt(event, start) {
    const top = event.pageY - start.Y + start.top + "px";
    const left = event.pageX - start.X + start.left + "px";
    CLIPBOARD_HEADER.style.left = left;
    CONTAINER.style.left = left;
    CONTAINER.style.top = top;
  }

  // move our absolutely positioned ball under the pointer
  moveAt(event, start);
  function onMouseMove(event) {
    moveAt(event, start);
  }

  // We use this to remove the mousemove when clicking outside of the container
  const controller = new AbortController();

  // move the container on mousemove
  document.addEventListener("mousemove", onMouseMove, {
    signal: controller.signal,
  });
  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        cleanUp();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );

  function cleanUp() {
    console.log("cleaning up the plot move listener");
    controller.abort();
    CLIPBOARD_HEADER.onmouseup = null;
  }

  // (3) drop the ball, remove unneeded handlers
  CLIPBOARD_HEADER.onmouseup = cleanUp;
};

function sendToClipboard(blob) {
  if (!navigator.clipboard) {
    alert(
      "The Clipboard API does not seem to be available, make sure the Pluto notebook is being used from either localhost or an https source."
    );
  }
  navigator.clipboard
    .write([
      new ClipboardItem({
        // The key is determined dynamically based on the blob's type.
        [blob.type]: blob,
      }),
    ])
    .then(
      function () {
        console.log("Async: Copying to clipboard was successful!");
      },
      function (err) {
        console.error("Async: Could not copy text: ", err);
      }
    );
}

function copyImageToClipboard() {
  // We extract the image options from the provided parameters (if they exist)
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key. We also ignore format because the clipboard only supports png.
    if (val === undefined || key === "format") {
      continue;
    }
    config[key] = val;
  }
  Plotly.toImage(PLOT, config).then(function (dataUrl) {
    fetch(dataUrl)
      .then((res) => res.blob())
      .then((blob) => {
        const paste_receiver = document.querySelector('paste-receiver.plutoplotly')
        if (paste_receiver) {
          paste_receiver.attachImage(dataUrl, CONTAINER)
        }
        sendToClipboard(blob)
      });
  });
}

function saveImageToFile() {
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key.
    if (val === undefined) {
      continue;
    }
    config[key] = val;
  }
  Plotly.downloadImage(PLOT, config);
}

let container_rect = { width: 0, height: 0, top: 0, left: 0 };
function unpop_container(cl) {
  CONTAINER.classList.toggle("popped-out", false);
  CONTAINER.classList.toggle(cl, false);
  // We fix the height back to the value it had before popout, also setting the flag to signal that upon first resize we remove the fixed inline-style
  CONTAINER.style.height = container_rect.height + "px";
  remove_container_size = true;
  // We set the other fixed inline-styles to null
  CONTAINER.style.width = "";
  CONTAINER.style.top = "";
  CONTAINER.style.left = "";
  // We also remove the CLIPBOARD_HEADER
  CLIPBOARD_HEADER.style.width = "";
  CLIPBOARD_HEADER.style.left = "";
  // Finally we remove the hidden class to the header
  CLIPBOARD_HEADER.classList.toggle("hidden", true);
  return;
}
function popout_container(opts) {
  const cl = opts?.cl;
  const target_container_size = opts?.target_container_size ?? {};
  const target_plot_size = opts?.target_plot_size ?? {};
  if (CONTAINER.isPoppedOut()) {
    return unpop_container(cl);
  }
  CONTAINER.classList.toggle(cl, cl === undefined ? false : true);
  // We extract the current size of the container, save them and fix them
  const { width, height, top, left } = CONTAINER.getBoundingClientRect();
  container_rect = { width, height, top, left };
  // We save the current plot size before we pop as it will fill the screen
  const current_plot_size = {
    width: PLOT._fullLayout.width,
    height: PLOT._fullLayout.height,
  };
  // We have to save the pad data before popping so we can resize precisely
  const pad = {};
  pad.unpopped = getSizeData().container_pad;
  CONTAINER.classList.toggle("popped-out", true);
  pad.popped = getSizeData().container_pad;
  // We do top and left based on the current rect
  for (const key of ["top", "left"]) {
    const start_val = target_container_size[key] ?? container_rect[key];
    let offset = 0;
    for (const kind of ["padding", "border"]) {
      offset += pad.popped[kind][key] - pad.unpopped[kind][key];
    }
    CONTAINER.style[key] = start_val - offset + "px";
    if (key === "left") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  // We compute the width and height depending on eventual config data
  const csz = computeContainerSize({
    width:
      target_plot_size.width ??
      config_spans.width.config_value ??
      current_plot_size.width,
    height:
      target_plot_size.height ??
      config_spans.height.config_value ??
      current_plot_size.height,
  });
  for (const key of ["width", "height"]) {
    const val = target_container_size[key] ?? csz[key];
    CONTAINER.style[key] = val + "px";
    if (key === "width") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  CLIPBOARD_HEADER.classList.toggle("hidden", false);
  const controller = new AbortController();

  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        unpop_container();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );
}

CONTAINER.popOut = popout_container;

function DualClick(single_func, dbl_func) {
  let nclicks = 0;
  return function (...args) {
    nclicks += 1;
    if (nclicks > 1) {
      dbl_func(...args);
      nclicks = 0;
    } else {
      delay(300).then(() => {
        if (nclicks == 1) {
          single_func(...args);
        }
        nclicks = 0;
      });
    }
  };
}

// We remove the default download image button
plot_obj.config.modeBarButtonsToRemove = _.union(
  plot_obj.config.modeBarButtonsToRemove,
  ["toImage"]
);
// We add the custom button to the modebar
plot_obj.config.modeBarButtonsToAdd = _.union(
  plot_obj.config.modeBarButtonsToAdd,
  [
    {
      name: "Copy PNG to Clipboard",
      icon: {
        height: 520,
        width: 520,
        path: "M280 64h40c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128C0 92.7 28.7 64 64 64h40 9.6C121 27.5 153.3 0 192 0s71 27.5 78.4 64H280zM64 112c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16H320c8.8 0 16-7.2 16-16V128c0-8.8-7.2-16-16-16H304v24c0 13.3-10.7 24-24 24H192 104c-13.3 0-24-10.7-24-24V112H64zm128-8a24 24 0 1 0 0-48 24 24 0 1 0 0 48z",
      },
      direction: "up",
      click: DualClick(copyImageToClipboard, () => {
        popout_container();
      }),
    },
    {
      name: "Download Image",
      icon: Plotly.Icons.camera,
      direction: "up",
      click: DualClick(saveImageToFile, () => {
        popout_container({ cl: "filesave" });
      }),
    },
  ]
);

function getOffsetData(el) {
  let cs = window.getComputedStyle(el, null);
  const odata = {
    padding: {
      left: parseFloat(cs.paddingLeft),
      right: parseFloat(cs.paddingRight),
      top: parseFloat(cs.paddingTop),
      bottom: parseFloat(cs.paddingBottom),
      width: parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight),
      height: parseFloat(cs.paddingTop) + parseFloat(cs.paddingBottom),
    },
    border: {
      left: parseFloat(cs.borderLeftWidth),
      right: parseFloat(cs.borderRightWidth),
      top: parseFloat(cs.borderTopWidth),
      bottom: parseFloat(cs.borderBottomWidth),
      width: parseFloat(cs.borderLeftWidth) + parseFloat(cs.borderRightWidth),
      height: parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth),
    }
  };
  if (el === PLOT) {
    // For the PLOT we also want to take into account the offset
    odata.offset = {
      top: PLOT.offsetParent == CONTAINER ? PLOT.offsetTop : 0,
      left: PLOT.offsetParent == CONTAINER ? PLOT.offsetLeft : 0,
    }
  }
  return odata;
}
function getSizeData() {
  const data = {
    plot_pad: getOffsetData(PLOT),
    plot_rect: PLOT.getBoundingClientRect(),
    container_pad: getOffsetData(CONTAINER),
    container_rect: CONTAINER.getBoundingClientRect(),
  };
  return data;
}
function computeContainerSize({ width, height }, sizeData = getSizeData()) {
  const computed_size = computePlotSize(sizeData);
  const offsets = computed_size.offsets;

  const plot_data = {
    width: width ?? computed_size.width,
    height: height ?? computed_size.height,
  };

  return {
    width: (width ?? computed_size.width) + offsets.width,
    height: (height ?? computed_size.height) + offsets.height,
    noChange: width == computed_size.width && height == computed_size.height,
  }
}

// This function will change the container size so that the resulting plot will be matching the provided specs
function changeContainerSize({ width, height }, sizeData = getSizeData()) {
  if (!CONTAINER.isPoppedOut()) {
    console.log("Tried to change container size when not popped, ignoring");
    return;
  }

  const csz = computeContainerSize({ width, height }, sizeData);

  if (csz.noChange) {
    console.log("Size is the same as current, ignoring");
    return
  }
  // We are now going to set he width and height of the container
  for (const key of ["width", "height"]) {
    CONTAINER.style[key] = csz[key] + "px";
  }
}
// We now create the function that will update the plot based on the values specified
function updateFromHeader() {
  const header_data = {
    height: config_spans.height.ui_value,
    width: config_spans.width.ui_value,
  };
  changeContainerSize(header_data);
}
// We assign this function to the onblur event of width and height
if (firstRun) {
  for (const container of Object.values(config_spans)) {
    container.ui_span.onblur = (e) => {
      container.ui_value = container.ui_span.textContent;
      updateFromHeader();
    };
  }
}
// This function computes the plot size to use for relayout as a function of the container size
function computePlotSize(data = getSizeData()) {
  // Remove Padding
  const { container_pad, plot_pad, container_rect } = data;
  const offsets = {
    width:
      plot_pad.padding.width +
      plot_pad.border.width +
      plot_pad.offset.left +
      container_pad.padding.width +
      container_pad.border.width,
    height:
      plot_pad.padding.height +
      plot_pad.border.height +
      plot_pad.offset.top +
      container_pad.padding.height +
      container_pad.border.height,
  };
  const sz = {
    width: Math.round(container_rect.width - offsets.width),
    height: Math.round(container_rect.height - offsets.height),
    offsets,
  };
  return sz;
}

// Create the resizeObserver to make the plot even more responsive! :magic:
const resizeObserver = new ResizeObserver((entries) => {
  const sizeData = getSizeData();
  const {container_rect, container_pad} = sizeData;
  let plot_size = computePlotSize(sizeData);
  // We save the height in the PLOT object
  PLOT.container_height = container_rect.height;
  // We deal with some stuff if the container is poppped
  CLIPBOARD_HEADER.style.width = container_rect.width + "px";
  CLIPBOARD_HEADER.style.left = container_rect.left + "px";
  config_spans.height.ui_value = plot_size.height;
  config_spans.width.ui_value = plot_size.width;
  /* 
		The addition of the invalid argument `plutoresize` seems to fix the problem with calling `relayout` simply with `{autosize: true}` as update breaking mouse relayout events tracking. 
		See https://github.com/plotly/plotly.js/issues/6156 for details
		*/
  let config = {
    // If this is popped out, we ignore the original width/height
    width: (CONTAINER.isPoppedOut() ? undefined : original_width) ?? plot_size.width,
    height: (CONTAINER.isPoppedOut() ? undefined : original_height) ?? plot_size.height,
    plutoresize: true,
  };
  Plotly.relayout(PLOT, config).then(() => {
    if (remove_container_size && !CONTAINER.isPoppedOut()) {
      // This is needed to avoid the first resize upon plot creation to already be without a fixed height
      CONTAINER.style.height = "";
      CONTAINER.style.width = "";
      remove_container_size = false;
    }
  });
});

resizeObserver.observe(CONTAINER);


Plotly.react(PLOT, plot_obj).then(() => {
	// Assign the Plotly event listeners
	for (const [key, listener_vec] of Object.entries(plotly_listeners)) {
		for (const listener of listener_vec) {
			PLOT.on(key, listener)
		}
	}
	// Assign the JS event listeners
	for (const [key, listener_vec] of Object.entries(js_listeners)) {
		for (const listener of listener_vec) {
			PLOT.addEventListener(key, listener, {
				signal: controller.signal
			})
		}
	}
}
)


invalidation.then(() => {
	// Remove all plotly listeners
	PLOT.removeAllListeners()
	// Remove all JS listeners
	controller.abort()
	// Remove the resizeObserver
	resizeObserver.disconnect()
})



		return CONTAINER
	</script>
</td></tr><tr><td align="right">No usable ace</td><td align="center">	<script id='plot_3'>
		// We start by putting all the variable interpolation here at the beginning
		// We have to convert all typedarrays in the layout to normal arrays. See Issue #25
		// We use lodash for this for compactness
		function removeTypedArray(o) {
			return _.isTypedArray(o) ? Array.from(o) :
			_.isPlainObject(o) ? _.mapValues(o, removeTypedArray) : 
			o
		}

		// Publish the plot object to JS
		let plot_obj = _.update(/* See the documentation for AbstractPlutoDingetjes.Display.published_to_js */ getPublishedObject("c6e0de0c-3901-11f0-234e-bd09c571f662/298eb806dc8714d9"), "layout", removeTypedArray)
		// Get the plotly listeners
		const plotly_listeners = {}
		// Get the JS listeners
		const js_listeners = {}
		// Deal with eventual custom classes
		let custom_classlist = []


		// Load the plotly library
		let Plotly = undefined
		try {
			let _mod = await import("./plotlyjs/plotlyjs-2.26.2.min.js")
			Plotly = _mod.default
		} catch (e) {
			console.log("Local load failed, trying with the web esm.sh version")
			let _mod = await import("https://esm.sh/plotly.js-dist-min@2.26.2/es2022/plotly.js-dist-min.mjs")
			Plotly = _mod.default
		}

		// Check if we have to force local mathjax font cache
		if (false && window?.MathJax?.config?.svg?.fontCache === 'global') {
			window.MathJax.config.svg.fontCache = 'local'
		}

		// Flag to check if this cell was  manually ran or reactively ran
const firstRun = this ? false : true
const CONTAINER = this ?? html`<div class='plutoplotly-container'>`
const PLOT = CONTAINER.querySelector('.js-plotly-plot') ?? CONTAINER.appendChild(html`<div>`)
const parent = CONTAINER.parentElement
// We use a controller to remove event listeners upon invalidation
const controller = new AbortController()
// We have to add this to keep supporting @bind with the old API using PLOT
PLOT.addEventListener('input', (e) => {
	CONTAINER.value = PLOT.value
	if (e.bubbles) {
		return
	}
	CONTAINER.dispatchEvent(new CustomEvent('input'))
}, { signal: controller.signal })

	// This create the style subdiv on first run
	firstRun && CONTAINER.appendChild(html`
	<style>
	.plutoplotly-container {
		width: 100%;
		height: 100%;
		min-height: 0;
		min-width: 0;
	}
	.plutoplotly-container .js-plotly-plot .plotly div {
		margin: 0 auto; // This centers the plot
	}
	.plutoplotly-container.popped-out {
		overflow: auto;
		z-index: 1000;
		position: fixed;
		resize: both;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		border-top-left-radius: 0px;
		border-top-right-radius: 0px;
	}
	.plutoplotly-clipboard-header {
		display: flex;
		flex-flow: row wrap;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-top-left-radius: 12px;
		border-top-right-radius: 12px;
		position: fixed;
		z-index: 1001;
		cursor: move;
		transform: translate(0px, -100%);
		padding: 5px;
	}
	.plutoplotly-clipboard-header span {
		display: inline-block;
		flex: 1
	}
	.plutoplotly-clipboard-header.hidden {
		display: none;
	}
	.clipboard-span {
		position: relative;
	}
	.clipboard-value {
		padding-right: 5px;
		padding-left: 2px;
		cursor: text;
	}
	.clipboard-span.format {
		display: none;
	}
	.clipboard-span.filename {
		flex: 0 0 100%;
		text-align: center;
		border-top: 3px solid var(--kbd-border-color);
		margin-top: 5px;
		display: none;
	}
	.plutoplotly-container.filesave .clipboard-span.filename {
		display: inline-block;
	}
	.clipboard-value.filename {
		margin-left: 3px;
		text-align: left;
		min-width: min(60%, min-content);
	}
	.plutoplotly-container.filesave .clipboard-span.format {
		display: inline-flex;
	}
	.clipboard-span.format .label {
		flex: 0 0 0;
	}
	.clipboard-value.format {
		position: relative;
		flex: 1 0 auto;
		min-width: 30px;
		margin-right: 10px;
	}
	div.format-options {
		display: inline-flex;
		flex-flow: column;
		position: absolute;
		background: var(--main-bg-color);
		border-radius: 12px;
		padding-left: 3px;
		z-index: 2000;
	}
	div.format-options:hover {
		cursor: pointer;
		border: 3px solid var(--kbd-border-color);
		padding: 3px;
		transform: translate(-3px, -6px);
	}
	div.format-options .format-option {
		display: none;
	}
	div.format-options:hover .format-option {
		display: inline-block;
	}
	.format-option:not(.selected) {
		margin-top: 3px;
	}
	div.format-options .format-option.selected {
		order: -1;
		display: inline-block;
	}
	.format-option:hover {
		background-color: var(--kbd-border-color);
	}
	span.config-value {
		font-weight: normal;
		color: var(--pluto-output-color);
		display: none;
		position: absolute;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		transform: translate(0px, calc(-100% - 10px));
		padding: 5px;
	}
	.label {
		user-select: none;
	}
	.label:hover span.config-value {
		display: inline-block;
		min-width: 150px;
	}
	.clipboard-span.matching-config .label {
		color: var(--cm-macro-color);
		font-weight: bold;
	}
	.clipboard-span.different-config .label {
		color: var(--cm-tag-color);
		font-weight: bold;
	}
</style>
`)

let original_height = plot_obj.layout.height
let original_width = plot_obj.layout.width
// For the height we have to also put a fixed value in case the plot is put on a non-fixed-size container (like the default wrapper)
// We define a variable to check whether we still have to remove the fixed height
let remove_container_size = firstRun
let container_height = original_height ?? PLOT.container_height ?? 400
CONTAINER.style.height = container_height + 'px'

// We create a Promise version of setTimeout
function delay(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

// We import interact for dragging/resizing
const { default: interact } = await import('https://esm.sh/interactjs@1.10.19')


function getImageOptions() {
  const o = plot_obj.config.toImageButtonOptions ?? {};
  return {
    format: o.format ?? "png",
    width: o.width ?? original_width,
    height: o.height ?? original_height,
    scale: o.scale ?? 1,
    filename: o.filename ?? "newplot",
  };
}

const CLIPBOARD_HEADER =
  CONTAINER.querySelector(".plutoplotly-clipboard-header") ??
  CONTAINER.insertAdjacentElement(
    "afterbegin",
    html`<div class="plutoplotly-clipboard-header hidden">
      <span class="clipboard-span format"
        ><span class="label">Format:</span
        ><span class="clipboard-value format"></span
      ></span>
      <span class="clipboard-span width"
        ><span class="label">Width:</span
        ><span class="clipboard-value width"></span>px</span
      >
      <span class="clipboard-span height"
        ><span class="label">Height:</span
        ><span class="clipboard-value height"></span>px</span
      >
      <span class="clipboard-span scale"
        ><span class="label">Scale:</span
        ><span class="clipboard-value scale"></span
      ></span>
      <button class="clipboard-span set">Set</button>
      <button class="clipboard-span unset">Unset</button>
      <span class="clipboard-span filename"
        ><span class="label">Filename:</span
        ><span class="clipboard-value filename"></span
      ></span>
    </div>`
  );

function checkConfigSync(container) {
  const valid_classes = [
    "missing-config",
    "matching-config",
    "different-config",
  ];
  function setClass(cl) {
    for (const name of valid_classes) {
      container.classList.toggle(name, name == cl);
    }
  }
  // We use the custom getters we'll set up in the container
  const { ui_value, config_value, config_span, key } = container;
  if (config_value === undefined) {
    setClass("missing-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> is not present in the config.`;
  } else if (ui_value == config_value) {
    setClass("matching-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has the same value in the config and in the header.`;
  } else {
    setClass("different-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has a different value (<em>${config_value}</em>) in the config.`;
  }
  // Add info about setting and unsetting
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click on the label <em><b>once</b></em> to set the current UI value in the config.`
  );
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click <em><b>twice</b></em> to remove this key from the config.`
  );
}

const valid_formats = ["png", "svg", "webp", "jpeg", "full-json"];
function initializeUIValueSpan(span, key, value) {
  const container = span.closest(".clipboard-span");
  span.contentEditable = key === "format" ? "false" : "true";
  let parse = (x) => x;
  let update = (x) => (span.textContent = x);
  if (key === "width" || key === "height") {
    parse = (x) => Math.round(parseFloat(x));
  } else if (key === "scale") {
    parse = parseFloat;
  } else if (key === "format") {
    // We remove contentEditable
    span.contentEditable = "false";
    // Here we first add the subspans for each option
    const opts_div = span.appendChild(html`<div class="format-options"></div>`);
    for (const fmt of valid_formats) {
      const opt = opts_div.appendChild(
        html`<span class="format-option ${fmt}">${fmt}</span>`
      );
      opt.onclick = (e) => {
        span.value = opt.textContent;
      };
    }
    parse = (x) => {
      return valid_formats.includes(x) ? x : localValue;
    };
    update = (x) => {
      for (const opt of opts_div.children) {
        opt.classList.toggle("selected", opt.textContent === x);
      }
    };
  } else {
    // We only have filename here
  }
  let localValue;
  Object.defineProperty(span, "value", {
    get: () => {
      return localValue;
    },
    set: (val) => {
      if (val !== "") {
        localValue = parse(val);
      }
      update(localValue);
      checkConfigSync(container);
    },
  });
  // We also assign a listener so that the editable is blurred when enter is pressed
  span.onkeydown = (e) => {
    if (e.keyCode === 13) {
      e.preventDefault();
      span.blur();
    }
  };
  span.value = value;
}

function initializeConfigValueSpan(span, key) {
  // Here we mostly want to define the setter and getter
  const container = span.closest(".clipboard-span");
  Object.defineProperty(span, "value", {
    get: () => {
      return plot_obj.config.toImageButtonOptions[key];
    },
    set: (val) => {
      // if undefined is passed, we remove the entry from the options
      if (val === undefined) {
        delete plot_obj.config.toImageButtonOptions[key];
      } else {
        plot_obj.config.toImageButtonOptions[key] = val;
      }
      checkConfigSync(container);
    },
  });
}

const config_spans = {};
for (const [key, value] of Object.entries(getImageOptions())) {
  const container = CLIPBOARD_HEADER.querySelector(`.clipboard-span.${key}`);
  const label = container.querySelector(".label");
  // We give the label a function that on single click will set the current value and with double click will unset it
  label.onclick = DualClick(
    () => {
      container.config_value = container.ui_value;
    },
    (e) => {
      console.log("e", e);
      e.preventDefault();
      container.config_value = undefined;
    }
  );
  const ui_value_span = container.querySelector(".clipboard-value");
  const config_value_span =
    container.querySelector(".config-value") ??
    label.insertAdjacentElement(
      "afterbegin",
      html`<span class="config-value"></span>`
    );
  // Assing the two spans as properties of the containing span
  container.ui_span = ui_value_span;
  container.config_span = config_value_span;
  container.key = key;
  config_spans[key] = container;
  if (firstRun) {
    plot_obj.config.toImageButtonOptions =
      plot_obj.config.toImageButtonOptions ?? {};
    // We do the initialization of the value span
    initializeUIValueSpan(ui_value_span, key, value);
    // Then we initialize the config value
    initializeConfigValueSpan(config_value_span, key);
    // We put some convenience getters/setters
    // ui_value forward
    Object.defineProperty(container, "ui_value", {
      get: () => ui_value_span.value,
      set: (val) => {
        ui_value_span.value = val;
      },
    });
    // config_value forward
    Object.defineProperty(container, "config_value", {
      get: () => config_value_span.value,
      set: (val) => {
        config_value_span.value = val;
      },
    });
  }
}

// These objects will contain the default value

// This code updates the image options in the PLOT config with the provided ones
function setImageOptions(o) {
  for (const [key, container] of Object.entries(config_spans)) {
    container.config_value = o[key];
  }
}
function unsetImageOptions() {
  setImageOptions({});
}

const set_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.set");
const unset_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.unset");
if (firstRun) {
  set_button.onclick = (e) => {
    for (const container of Object.values(config_spans)) {
      container.config_value = container.ui_value;
    }
  };
  unset_button.onclick = unsetImageOptions;
}

// We add a function to check if the clipboard is popped out
CONTAINER.isPoppedOut = () => {
  return CONTAINER.classList.contains("popped-out");
};

CLIPBOARD_HEADER.onmousedown = function (event) {
  if (event.target.matches("span.clipboard-value")) {
    console.log("We don't move!");
    return;
  }
  const start = {
    left: parseFloat(CONTAINER.style.left),
    top: parseFloat(CONTAINER.style.top),
    X: event.pageX,
    Y: event.pageY,
  };
  function moveAt(event, start) {
    const top = event.pageY - start.Y + start.top + "px";
    const left = event.pageX - start.X + start.left + "px";
    CLIPBOARD_HEADER.style.left = left;
    CONTAINER.style.left = left;
    CONTAINER.style.top = top;
  }

  // move our absolutely positioned ball under the pointer
  moveAt(event, start);
  function onMouseMove(event) {
    moveAt(event, start);
  }

  // We use this to remove the mousemove when clicking outside of the container
  const controller = new AbortController();

  // move the container on mousemove
  document.addEventListener("mousemove", onMouseMove, {
    signal: controller.signal,
  });
  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        cleanUp();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );

  function cleanUp() {
    console.log("cleaning up the plot move listener");
    controller.abort();
    CLIPBOARD_HEADER.onmouseup = null;
  }

  // (3) drop the ball, remove unneeded handlers
  CLIPBOARD_HEADER.onmouseup = cleanUp;
};

function sendToClipboard(blob) {
  if (!navigator.clipboard) {
    alert(
      "The Clipboard API does not seem to be available, make sure the Pluto notebook is being used from either localhost or an https source."
    );
  }
  navigator.clipboard
    .write([
      new ClipboardItem({
        // The key is determined dynamically based on the blob's type.
        [blob.type]: blob,
      }),
    ])
    .then(
      function () {
        console.log("Async: Copying to clipboard was successful!");
      },
      function (err) {
        console.error("Async: Could not copy text: ", err);
      }
    );
}

function copyImageToClipboard() {
  // We extract the image options from the provided parameters (if they exist)
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key. We also ignore format because the clipboard only supports png.
    if (val === undefined || key === "format") {
      continue;
    }
    config[key] = val;
  }
  Plotly.toImage(PLOT, config).then(function (dataUrl) {
    fetch(dataUrl)
      .then((res) => res.blob())
      .then((blob) => {
        const paste_receiver = document.querySelector('paste-receiver.plutoplotly')
        if (paste_receiver) {
          paste_receiver.attachImage(dataUrl, CONTAINER)
        }
        sendToClipboard(blob)
      });
  });
}

function saveImageToFile() {
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key.
    if (val === undefined) {
      continue;
    }
    config[key] = val;
  }
  Plotly.downloadImage(PLOT, config);
}

let container_rect = { width: 0, height: 0, top: 0, left: 0 };
function unpop_container(cl) {
  CONTAINER.classList.toggle("popped-out", false);
  CONTAINER.classList.toggle(cl, false);
  // We fix the height back to the value it had before popout, also setting the flag to signal that upon first resize we remove the fixed inline-style
  CONTAINER.style.height = container_rect.height + "px";
  remove_container_size = true;
  // We set the other fixed inline-styles to null
  CONTAINER.style.width = "";
  CONTAINER.style.top = "";
  CONTAINER.style.left = "";
  // We also remove the CLIPBOARD_HEADER
  CLIPBOARD_HEADER.style.width = "";
  CLIPBOARD_HEADER.style.left = "";
  // Finally we remove the hidden class to the header
  CLIPBOARD_HEADER.classList.toggle("hidden", true);
  return;
}
function popout_container(opts) {
  const cl = opts?.cl;
  const target_container_size = opts?.target_container_size ?? {};
  const target_plot_size = opts?.target_plot_size ?? {};
  if (CONTAINER.isPoppedOut()) {
    return unpop_container(cl);
  }
  CONTAINER.classList.toggle(cl, cl === undefined ? false : true);
  // We extract the current size of the container, save them and fix them
  const { width, height, top, left } = CONTAINER.getBoundingClientRect();
  container_rect = { width, height, top, left };
  // We save the current plot size before we pop as it will fill the screen
  const current_plot_size = {
    width: PLOT._fullLayout.width,
    height: PLOT._fullLayout.height,
  };
  // We have to save the pad data before popping so we can resize precisely
  const pad = {};
  pad.unpopped = getSizeData().container_pad;
  CONTAINER.classList.toggle("popped-out", true);
  pad.popped = getSizeData().container_pad;
  // We do top and left based on the current rect
  for (const key of ["top", "left"]) {
    const start_val = target_container_size[key] ?? container_rect[key];
    let offset = 0;
    for (const kind of ["padding", "border"]) {
      offset += pad.popped[kind][key] - pad.unpopped[kind][key];
    }
    CONTAINER.style[key] = start_val - offset + "px";
    if (key === "left") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  // We compute the width and height depending on eventual config data
  const csz = computeContainerSize({
    width:
      target_plot_size.width ??
      config_spans.width.config_value ??
      current_plot_size.width,
    height:
      target_plot_size.height ??
      config_spans.height.config_value ??
      current_plot_size.height,
  });
  for (const key of ["width", "height"]) {
    const val = target_container_size[key] ?? csz[key];
    CONTAINER.style[key] = val + "px";
    if (key === "width") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  CLIPBOARD_HEADER.classList.toggle("hidden", false);
  const controller = new AbortController();

  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        unpop_container();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );
}

CONTAINER.popOut = popout_container;

function DualClick(single_func, dbl_func) {
  let nclicks = 0;
  return function (...args) {
    nclicks += 1;
    if (nclicks > 1) {
      dbl_func(...args);
      nclicks = 0;
    } else {
      delay(300).then(() => {
        if (nclicks == 1) {
          single_func(...args);
        }
        nclicks = 0;
      });
    }
  };
}

// We remove the default download image button
plot_obj.config.modeBarButtonsToRemove = _.union(
  plot_obj.config.modeBarButtonsToRemove,
  ["toImage"]
);
// We add the custom button to the modebar
plot_obj.config.modeBarButtonsToAdd = _.union(
  plot_obj.config.modeBarButtonsToAdd,
  [
    {
      name: "Copy PNG to Clipboard",
      icon: {
        height: 520,
        width: 520,
        path: "M280 64h40c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128C0 92.7 28.7 64 64 64h40 9.6C121 27.5 153.3 0 192 0s71 27.5 78.4 64H280zM64 112c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16H320c8.8 0 16-7.2 16-16V128c0-8.8-7.2-16-16-16H304v24c0 13.3-10.7 24-24 24H192 104c-13.3 0-24-10.7-24-24V112H64zm128-8a24 24 0 1 0 0-48 24 24 0 1 0 0 48z",
      },
      direction: "up",
      click: DualClick(copyImageToClipboard, () => {
        popout_container();
      }),
    },
    {
      name: "Download Image",
      icon: Plotly.Icons.camera,
      direction: "up",
      click: DualClick(saveImageToFile, () => {
        popout_container({ cl: "filesave" });
      }),
    },
  ]
);

function getOffsetData(el) {
  let cs = window.getComputedStyle(el, null);
  const odata = {
    padding: {
      left: parseFloat(cs.paddingLeft),
      right: parseFloat(cs.paddingRight),
      top: parseFloat(cs.paddingTop),
      bottom: parseFloat(cs.paddingBottom),
      width: parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight),
      height: parseFloat(cs.paddingTop) + parseFloat(cs.paddingBottom),
    },
    border: {
      left: parseFloat(cs.borderLeftWidth),
      right: parseFloat(cs.borderRightWidth),
      top: parseFloat(cs.borderTopWidth),
      bottom: parseFloat(cs.borderBottomWidth),
      width: parseFloat(cs.borderLeftWidth) + parseFloat(cs.borderRightWidth),
      height: parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth),
    }
  };
  if (el === PLOT) {
    // For the PLOT we also want to take into account the offset
    odata.offset = {
      top: PLOT.offsetParent == CONTAINER ? PLOT.offsetTop : 0,
      left: PLOT.offsetParent == CONTAINER ? PLOT.offsetLeft : 0,
    }
  }
  return odata;
}
function getSizeData() {
  const data = {
    plot_pad: getOffsetData(PLOT),
    plot_rect: PLOT.getBoundingClientRect(),
    container_pad: getOffsetData(CONTAINER),
    container_rect: CONTAINER.getBoundingClientRect(),
  };
  return data;
}
function computeContainerSize({ width, height }, sizeData = getSizeData()) {
  const computed_size = computePlotSize(sizeData);
  const offsets = computed_size.offsets;

  const plot_data = {
    width: width ?? computed_size.width,
    height: height ?? computed_size.height,
  };

  return {
    width: (width ?? computed_size.width) + offsets.width,
    height: (height ?? computed_size.height) + offsets.height,
    noChange: width == computed_size.width && height == computed_size.height,
  }
}

// This function will change the container size so that the resulting plot will be matching the provided specs
function changeContainerSize({ width, height }, sizeData = getSizeData()) {
  if (!CONTAINER.isPoppedOut()) {
    console.log("Tried to change container size when not popped, ignoring");
    return;
  }

  const csz = computeContainerSize({ width, height }, sizeData);

  if (csz.noChange) {
    console.log("Size is the same as current, ignoring");
    return
  }
  // We are now going to set he width and height of the container
  for (const key of ["width", "height"]) {
    CONTAINER.style[key] = csz[key] + "px";
  }
}
// We now create the function that will update the plot based on the values specified
function updateFromHeader() {
  const header_data = {
    height: config_spans.height.ui_value,
    width: config_spans.width.ui_value,
  };
  changeContainerSize(header_data);
}
// We assign this function to the onblur event of width and height
if (firstRun) {
  for (const container of Object.values(config_spans)) {
    container.ui_span.onblur = (e) => {
      container.ui_value = container.ui_span.textContent;
      updateFromHeader();
    };
  }
}
// This function computes the plot size to use for relayout as a function of the container size
function computePlotSize(data = getSizeData()) {
  // Remove Padding
  const { container_pad, plot_pad, container_rect } = data;
  const offsets = {
    width:
      plot_pad.padding.width +
      plot_pad.border.width +
      plot_pad.offset.left +
      container_pad.padding.width +
      container_pad.border.width,
    height:
      plot_pad.padding.height +
      plot_pad.border.height +
      plot_pad.offset.top +
      container_pad.padding.height +
      container_pad.border.height,
  };
  const sz = {
    width: Math.round(container_rect.width - offsets.width),
    height: Math.round(container_rect.height - offsets.height),
    offsets,
  };
  return sz;
}

// Create the resizeObserver to make the plot even more responsive! :magic:
const resizeObserver = new ResizeObserver((entries) => {
  const sizeData = getSizeData();
  const {container_rect, container_pad} = sizeData;
  let plot_size = computePlotSize(sizeData);
  // We save the height in the PLOT object
  PLOT.container_height = container_rect.height;
  // We deal with some stuff if the container is poppped
  CLIPBOARD_HEADER.style.width = container_rect.width + "px";
  CLIPBOARD_HEADER.style.left = container_rect.left + "px";
  config_spans.height.ui_value = plot_size.height;
  config_spans.width.ui_value = plot_size.width;
  /* 
		The addition of the invalid argument `plutoresize` seems to fix the problem with calling `relayout` simply with `{autosize: true}` as update breaking mouse relayout events tracking. 
		See https://github.com/plotly/plotly.js/issues/6156 for details
		*/
  let config = {
    // If this is popped out, we ignore the original width/height
    width: (CONTAINER.isPoppedOut() ? undefined : original_width) ?? plot_size.width,
    height: (CONTAINER.isPoppedOut() ? undefined : original_height) ?? plot_size.height,
    plutoresize: true,
  };
  Plotly.relayout(PLOT, config).then(() => {
    if (remove_container_size && !CONTAINER.isPoppedOut()) {
      // This is needed to avoid the first resize upon plot creation to already be without a fixed height
      CONTAINER.style.height = "";
      CONTAINER.style.width = "";
      remove_container_size = false;
    }
  });
});

resizeObserver.observe(CONTAINER);


Plotly.react(PLOT, plot_obj).then(() => {
	// Assign the Plotly event listeners
	for (const [key, listener_vec] of Object.entries(plotly_listeners)) {
		for (const listener of listener_vec) {
			PLOT.on(key, listener)
		}
	}
	// Assign the JS event listeners
	for (const [key, listener_vec] of Object.entries(js_listeners)) {
		for (const listener of listener_vec) {
			PLOT.addEventListener(key, listener, {
				signal: controller.signal
			})
		}
	}
}
)


invalidation.then(() => {
	// Remove all plotly listeners
	PLOT.removeAllListeners()
	// Remove all JS listeners
	controller.abort()
	// Remove the resizeObserver
	resizeObserver.disconnect()
})



		return CONTAINER
	</script>
</td><td align="center">	<script id='plot_4'>
		// We start by putting all the variable interpolation here at the beginning
		// We have to convert all typedarrays in the layout to normal arrays. See Issue #25
		// We use lodash for this for compactness
		function removeTypedArray(o) {
			return _.isTypedArray(o) ? Array.from(o) :
			_.isPlainObject(o) ? _.mapValues(o, removeTypedArray) : 
			o
		}

		// Publish the plot object to JS
		let plot_obj = _.update(/* See the documentation for AbstractPlutoDingetjes.Display.published_to_js */ getPublishedObject("c6e0de0c-3901-11f0-234e-bd09c571f662/dd4bace5c1b653a4"), "layout", removeTypedArray)
		// Get the plotly listeners
		const plotly_listeners = {}
		// Get the JS listeners
		const js_listeners = {}
		// Deal with eventual custom classes
		let custom_classlist = []


		// Load the plotly library
		let Plotly = undefined
		try {
			let _mod = await import("./plotlyjs/plotlyjs-2.26.2.min.js")
			Plotly = _mod.default
		} catch (e) {
			console.log("Local load failed, trying with the web esm.sh version")
			let _mod = await import("https://esm.sh/plotly.js-dist-min@2.26.2/es2022/plotly.js-dist-min.mjs")
			Plotly = _mod.default
		}

		// Check if we have to force local mathjax font cache
		if (false && window?.MathJax?.config?.svg?.fontCache === 'global') {
			window.MathJax.config.svg.fontCache = 'local'
		}

		// Flag to check if this cell was  manually ran or reactively ran
const firstRun = this ? false : true
const CONTAINER = this ?? html`<div class='plutoplotly-container'>`
const PLOT = CONTAINER.querySelector('.js-plotly-plot') ?? CONTAINER.appendChild(html`<div>`)
const parent = CONTAINER.parentElement
// We use a controller to remove event listeners upon invalidation
const controller = new AbortController()
// We have to add this to keep supporting @bind with the old API using PLOT
PLOT.addEventListener('input', (e) => {
	CONTAINER.value = PLOT.value
	if (e.bubbles) {
		return
	}
	CONTAINER.dispatchEvent(new CustomEvent('input'))
}, { signal: controller.signal })

	// This create the style subdiv on first run
	firstRun && CONTAINER.appendChild(html`
	<style>
	.plutoplotly-container {
		width: 100%;
		height: 100%;
		min-height: 0;
		min-width: 0;
	}
	.plutoplotly-container .js-plotly-plot .plotly div {
		margin: 0 auto; // This centers the plot
	}
	.plutoplotly-container.popped-out {
		overflow: auto;
		z-index: 1000;
		position: fixed;
		resize: both;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		border-top-left-radius: 0px;
		border-top-right-radius: 0px;
	}
	.plutoplotly-clipboard-header {
		display: flex;
		flex-flow: row wrap;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-top-left-radius: 12px;
		border-top-right-radius: 12px;
		position: fixed;
		z-index: 1001;
		cursor: move;
		transform: translate(0px, -100%);
		padding: 5px;
	}
	.plutoplotly-clipboard-header span {
		display: inline-block;
		flex: 1
	}
	.plutoplotly-clipboard-header.hidden {
		display: none;
	}
	.clipboard-span {
		position: relative;
	}
	.clipboard-value {
		padding-right: 5px;
		padding-left: 2px;
		cursor: text;
	}
	.clipboard-span.format {
		display: none;
	}
	.clipboard-span.filename {
		flex: 0 0 100%;
		text-align: center;
		border-top: 3px solid var(--kbd-border-color);
		margin-top: 5px;
		display: none;
	}
	.plutoplotly-container.filesave .clipboard-span.filename {
		display: inline-block;
	}
	.clipboard-value.filename {
		margin-left: 3px;
		text-align: left;
		min-width: min(60%, min-content);
	}
	.plutoplotly-container.filesave .clipboard-span.format {
		display: inline-flex;
	}
	.clipboard-span.format .label {
		flex: 0 0 0;
	}
	.clipboard-value.format {
		position: relative;
		flex: 1 0 auto;
		min-width: 30px;
		margin-right: 10px;
	}
	div.format-options {
		display: inline-flex;
		flex-flow: column;
		position: absolute;
		background: var(--main-bg-color);
		border-radius: 12px;
		padding-left: 3px;
		z-index: 2000;
	}
	div.format-options:hover {
		cursor: pointer;
		border: 3px solid var(--kbd-border-color);
		padding: 3px;
		transform: translate(-3px, -6px);
	}
	div.format-options .format-option {
		display: none;
	}
	div.format-options:hover .format-option {
		display: inline-block;
	}
	.format-option:not(.selected) {
		margin-top: 3px;
	}
	div.format-options .format-option.selected {
		order: -1;
		display: inline-block;
	}
	.format-option:hover {
		background-color: var(--kbd-border-color);
	}
	span.config-value {
		font-weight: normal;
		color: var(--pluto-output-color);
		display: none;
		position: absolute;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		transform: translate(0px, calc(-100% - 10px));
		padding: 5px;
	}
	.label {
		user-select: none;
	}
	.label:hover span.config-value {
		display: inline-block;
		min-width: 150px;
	}
	.clipboard-span.matching-config .label {
		color: var(--cm-macro-color);
		font-weight: bold;
	}
	.clipboard-span.different-config .label {
		color: var(--cm-tag-color);
		font-weight: bold;
	}
</style>
`)

let original_height = plot_obj.layout.height
let original_width = plot_obj.layout.width
// For the height we have to also put a fixed value in case the plot is put on a non-fixed-size container (like the default wrapper)
// We define a variable to check whether we still have to remove the fixed height
let remove_container_size = firstRun
let container_height = original_height ?? PLOT.container_height ?? 400
CONTAINER.style.height = container_height + 'px'

// We create a Promise version of setTimeout
function delay(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

// We import interact for dragging/resizing
const { default: interact } = await import('https://esm.sh/interactjs@1.10.19')


function getImageOptions() {
  const o = plot_obj.config.toImageButtonOptions ?? {};
  return {
    format: o.format ?? "png",
    width: o.width ?? original_width,
    height: o.height ?? original_height,
    scale: o.scale ?? 1,
    filename: o.filename ?? "newplot",
  };
}

const CLIPBOARD_HEADER =
  CONTAINER.querySelector(".plutoplotly-clipboard-header") ??
  CONTAINER.insertAdjacentElement(
    "afterbegin",
    html`<div class="plutoplotly-clipboard-header hidden">
      <span class="clipboard-span format"
        ><span class="label">Format:</span
        ><span class="clipboard-value format"></span
      ></span>
      <span class="clipboard-span width"
        ><span class="label">Width:</span
        ><span class="clipboard-value width"></span>px</span
      >
      <span class="clipboard-span height"
        ><span class="label">Height:</span
        ><span class="clipboard-value height"></span>px</span
      >
      <span class="clipboard-span scale"
        ><span class="label">Scale:</span
        ><span class="clipboard-value scale"></span
      ></span>
      <button class="clipboard-span set">Set</button>
      <button class="clipboard-span unset">Unset</button>
      <span class="clipboard-span filename"
        ><span class="label">Filename:</span
        ><span class="clipboard-value filename"></span
      ></span>
    </div>`
  );

function checkConfigSync(container) {
  const valid_classes = [
    "missing-config",
    "matching-config",
    "different-config",
  ];
  function setClass(cl) {
    for (const name of valid_classes) {
      container.classList.toggle(name, name == cl);
    }
  }
  // We use the custom getters we'll set up in the container
  const { ui_value, config_value, config_span, key } = container;
  if (config_value === undefined) {
    setClass("missing-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> is not present in the config.`;
  } else if (ui_value == config_value) {
    setClass("matching-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has the same value in the config and in the header.`;
  } else {
    setClass("different-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has a different value (<em>${config_value}</em>) in the config.`;
  }
  // Add info about setting and unsetting
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click on the label <em><b>once</b></em> to set the current UI value in the config.`
  );
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click <em><b>twice</b></em> to remove this key from the config.`
  );
}

const valid_formats = ["png", "svg", "webp", "jpeg", "full-json"];
function initializeUIValueSpan(span, key, value) {
  const container = span.closest(".clipboard-span");
  span.contentEditable = key === "format" ? "false" : "true";
  let parse = (x) => x;
  let update = (x) => (span.textContent = x);
  if (key === "width" || key === "height") {
    parse = (x) => Math.round(parseFloat(x));
  } else if (key === "scale") {
    parse = parseFloat;
  } else if (key === "format") {
    // We remove contentEditable
    span.contentEditable = "false";
    // Here we first add the subspans for each option
    const opts_div = span.appendChild(html`<div class="format-options"></div>`);
    for (const fmt of valid_formats) {
      const opt = opts_div.appendChild(
        html`<span class="format-option ${fmt}">${fmt}</span>`
      );
      opt.onclick = (e) => {
        span.value = opt.textContent;
      };
    }
    parse = (x) => {
      return valid_formats.includes(x) ? x : localValue;
    };
    update = (x) => {
      for (const opt of opts_div.children) {
        opt.classList.toggle("selected", opt.textContent === x);
      }
    };
  } else {
    // We only have filename here
  }
  let localValue;
  Object.defineProperty(span, "value", {
    get: () => {
      return localValue;
    },
    set: (val) => {
      if (val !== "") {
        localValue = parse(val);
      }
      update(localValue);
      checkConfigSync(container);
    },
  });
  // We also assign a listener so that the editable is blurred when enter is pressed
  span.onkeydown = (e) => {
    if (e.keyCode === 13) {
      e.preventDefault();
      span.blur();
    }
  };
  span.value = value;
}

function initializeConfigValueSpan(span, key) {
  // Here we mostly want to define the setter and getter
  const container = span.closest(".clipboard-span");
  Object.defineProperty(span, "value", {
    get: () => {
      return plot_obj.config.toImageButtonOptions[key];
    },
    set: (val) => {
      // if undefined is passed, we remove the entry from the options
      if (val === undefined) {
        delete plot_obj.config.toImageButtonOptions[key];
      } else {
        plot_obj.config.toImageButtonOptions[key] = val;
      }
      checkConfigSync(container);
    },
  });
}

const config_spans = {};
for (const [key, value] of Object.entries(getImageOptions())) {
  const container = CLIPBOARD_HEADER.querySelector(`.clipboard-span.${key}`);
  const label = container.querySelector(".label");
  // We give the label a function that on single click will set the current value and with double click will unset it
  label.onclick = DualClick(
    () => {
      container.config_value = container.ui_value;
    },
    (e) => {
      console.log("e", e);
      e.preventDefault();
      container.config_value = undefined;
    }
  );
  const ui_value_span = container.querySelector(".clipboard-value");
  const config_value_span =
    container.querySelector(".config-value") ??
    label.insertAdjacentElement(
      "afterbegin",
      html`<span class="config-value"></span>`
    );
  // Assing the two spans as properties of the containing span
  container.ui_span = ui_value_span;
  container.config_span = config_value_span;
  container.key = key;
  config_spans[key] = container;
  if (firstRun) {
    plot_obj.config.toImageButtonOptions =
      plot_obj.config.toImageButtonOptions ?? {};
    // We do the initialization of the value span
    initializeUIValueSpan(ui_value_span, key, value);
    // Then we initialize the config value
    initializeConfigValueSpan(config_value_span, key);
    // We put some convenience getters/setters
    // ui_value forward
    Object.defineProperty(container, "ui_value", {
      get: () => ui_value_span.value,
      set: (val) => {
        ui_value_span.value = val;
      },
    });
    // config_value forward
    Object.defineProperty(container, "config_value", {
      get: () => config_value_span.value,
      set: (val) => {
        config_value_span.value = val;
      },
    });
  }
}

// These objects will contain the default value

// This code updates the image options in the PLOT config with the provided ones
function setImageOptions(o) {
  for (const [key, container] of Object.entries(config_spans)) {
    container.config_value = o[key];
  }
}
function unsetImageOptions() {
  setImageOptions({});
}

const set_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.set");
const unset_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.unset");
if (firstRun) {
  set_button.onclick = (e) => {
    for (const container of Object.values(config_spans)) {
      container.config_value = container.ui_value;
    }
  };
  unset_button.onclick = unsetImageOptions;
}

// We add a function to check if the clipboard is popped out
CONTAINER.isPoppedOut = () => {
  return CONTAINER.classList.contains("popped-out");
};

CLIPBOARD_HEADER.onmousedown = function (event) {
  if (event.target.matches("span.clipboard-value")) {
    console.log("We don't move!");
    return;
  }
  const start = {
    left: parseFloat(CONTAINER.style.left),
    top: parseFloat(CONTAINER.style.top),
    X: event.pageX,
    Y: event.pageY,
  };
  function moveAt(event, start) {
    const top = event.pageY - start.Y + start.top + "px";
    const left = event.pageX - start.X + start.left + "px";
    CLIPBOARD_HEADER.style.left = left;
    CONTAINER.style.left = left;
    CONTAINER.style.top = top;
  }

  // move our absolutely positioned ball under the pointer
  moveAt(event, start);
  function onMouseMove(event) {
    moveAt(event, start);
  }

  // We use this to remove the mousemove when clicking outside of the container
  const controller = new AbortController();

  // move the container on mousemove
  document.addEventListener("mousemove", onMouseMove, {
    signal: controller.signal,
  });
  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        cleanUp();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );

  function cleanUp() {
    console.log("cleaning up the plot move listener");
    controller.abort();
    CLIPBOARD_HEADER.onmouseup = null;
  }

  // (3) drop the ball, remove unneeded handlers
  CLIPBOARD_HEADER.onmouseup = cleanUp;
};

function sendToClipboard(blob) {
  if (!navigator.clipboard) {
    alert(
      "The Clipboard API does not seem to be available, make sure the Pluto notebook is being used from either localhost or an https source."
    );
  }
  navigator.clipboard
    .write([
      new ClipboardItem({
        // The key is determined dynamically based on the blob's type.
        [blob.type]: blob,
      }),
    ])
    .then(
      function () {
        console.log("Async: Copying to clipboard was successful!");
      },
      function (err) {
        console.error("Async: Could not copy text: ", err);
      }
    );
}

function copyImageToClipboard() {
  // We extract the image options from the provided parameters (if they exist)
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key. We also ignore format because the clipboard only supports png.
    if (val === undefined || key === "format") {
      continue;
    }
    config[key] = val;
  }
  Plotly.toImage(PLOT, config).then(function (dataUrl) {
    fetch(dataUrl)
      .then((res) => res.blob())
      .then((blob) => {
        const paste_receiver = document.querySelector('paste-receiver.plutoplotly')
        if (paste_receiver) {
          paste_receiver.attachImage(dataUrl, CONTAINER)
        }
        sendToClipboard(blob)
      });
  });
}

function saveImageToFile() {
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key.
    if (val === undefined) {
      continue;
    }
    config[key] = val;
  }
  Plotly.downloadImage(PLOT, config);
}

let container_rect = { width: 0, height: 0, top: 0, left: 0 };
function unpop_container(cl) {
  CONTAINER.classList.toggle("popped-out", false);
  CONTAINER.classList.toggle(cl, false);
  // We fix the height back to the value it had before popout, also setting the flag to signal that upon first resize we remove the fixed inline-style
  CONTAINER.style.height = container_rect.height + "px";
  remove_container_size = true;
  // We set the other fixed inline-styles to null
  CONTAINER.style.width = "";
  CONTAINER.style.top = "";
  CONTAINER.style.left = "";
  // We also remove the CLIPBOARD_HEADER
  CLIPBOARD_HEADER.style.width = "";
  CLIPBOARD_HEADER.style.left = "";
  // Finally we remove the hidden class to the header
  CLIPBOARD_HEADER.classList.toggle("hidden", true);
  return;
}
function popout_container(opts) {
  const cl = opts?.cl;
  const target_container_size = opts?.target_container_size ?? {};
  const target_plot_size = opts?.target_plot_size ?? {};
  if (CONTAINER.isPoppedOut()) {
    return unpop_container(cl);
  }
  CONTAINER.classList.toggle(cl, cl === undefined ? false : true);
  // We extract the current size of the container, save them and fix them
  const { width, height, top, left } = CONTAINER.getBoundingClientRect();
  container_rect = { width, height, top, left };
  // We save the current plot size before we pop as it will fill the screen
  const current_plot_size = {
    width: PLOT._fullLayout.width,
    height: PLOT._fullLayout.height,
  };
  // We have to save the pad data before popping so we can resize precisely
  const pad = {};
  pad.unpopped = getSizeData().container_pad;
  CONTAINER.classList.toggle("popped-out", true);
  pad.popped = getSizeData().container_pad;
  // We do top and left based on the current rect
  for (const key of ["top", "left"]) {
    const start_val = target_container_size[key] ?? container_rect[key];
    let offset = 0;
    for (const kind of ["padding", "border"]) {
      offset += pad.popped[kind][key] - pad.unpopped[kind][key];
    }
    CONTAINER.style[key] = start_val - offset + "px";
    if (key === "left") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  // We compute the width and height depending on eventual config data
  const csz = computeContainerSize({
    width:
      target_plot_size.width ??
      config_spans.width.config_value ??
      current_plot_size.width,
    height:
      target_plot_size.height ??
      config_spans.height.config_value ??
      current_plot_size.height,
  });
  for (const key of ["width", "height"]) {
    const val = target_container_size[key] ?? csz[key];
    CONTAINER.style[key] = val + "px";
    if (key === "width") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  CLIPBOARD_HEADER.classList.toggle("hidden", false);
  const controller = new AbortController();

  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        unpop_container();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );
}

CONTAINER.popOut = popout_container;

function DualClick(single_func, dbl_func) {
  let nclicks = 0;
  return function (...args) {
    nclicks += 1;
    if (nclicks > 1) {
      dbl_func(...args);
      nclicks = 0;
    } else {
      delay(300).then(() => {
        if (nclicks == 1) {
          single_func(...args);
        }
        nclicks = 0;
      });
    }
  };
}

// We remove the default download image button
plot_obj.config.modeBarButtonsToRemove = _.union(
  plot_obj.config.modeBarButtonsToRemove,
  ["toImage"]
);
// We add the custom button to the modebar
plot_obj.config.modeBarButtonsToAdd = _.union(
  plot_obj.config.modeBarButtonsToAdd,
  [
    {
      name: "Copy PNG to Clipboard",
      icon: {
        height: 520,
        width: 520,
        path: "M280 64h40c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128C0 92.7 28.7 64 64 64h40 9.6C121 27.5 153.3 0 192 0s71 27.5 78.4 64H280zM64 112c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16H320c8.8 0 16-7.2 16-16V128c0-8.8-7.2-16-16-16H304v24c0 13.3-10.7 24-24 24H192 104c-13.3 0-24-10.7-24-24V112H64zm128-8a24 24 0 1 0 0-48 24 24 0 1 0 0 48z",
      },
      direction: "up",
      click: DualClick(copyImageToClipboard, () => {
        popout_container();
      }),
    },
    {
      name: "Download Image",
      icon: Plotly.Icons.camera,
      direction: "up",
      click: DualClick(saveImageToFile, () => {
        popout_container({ cl: "filesave" });
      }),
    },
  ]
);

function getOffsetData(el) {
  let cs = window.getComputedStyle(el, null);
  const odata = {
    padding: {
      left: parseFloat(cs.paddingLeft),
      right: parseFloat(cs.paddingRight),
      top: parseFloat(cs.paddingTop),
      bottom: parseFloat(cs.paddingBottom),
      width: parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight),
      height: parseFloat(cs.paddingTop) + parseFloat(cs.paddingBottom),
    },
    border: {
      left: parseFloat(cs.borderLeftWidth),
      right: parseFloat(cs.borderRightWidth),
      top: parseFloat(cs.borderTopWidth),
      bottom: parseFloat(cs.borderBottomWidth),
      width: parseFloat(cs.borderLeftWidth) + parseFloat(cs.borderRightWidth),
      height: parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth),
    }
  };
  if (el === PLOT) {
    // For the PLOT we also want to take into account the offset
    odata.offset = {
      top: PLOT.offsetParent == CONTAINER ? PLOT.offsetTop : 0,
      left: PLOT.offsetParent == CONTAINER ? PLOT.offsetLeft : 0,
    }
  }
  return odata;
}
function getSizeData() {
  const data = {
    plot_pad: getOffsetData(PLOT),
    plot_rect: PLOT.getBoundingClientRect(),
    container_pad: getOffsetData(CONTAINER),
    container_rect: CONTAINER.getBoundingClientRect(),
  };
  return data;
}
function computeContainerSize({ width, height }, sizeData = getSizeData()) {
  const computed_size = computePlotSize(sizeData);
  const offsets = computed_size.offsets;

  const plot_data = {
    width: width ?? computed_size.width,
    height: height ?? computed_size.height,
  };

  return {
    width: (width ?? computed_size.width) + offsets.width,
    height: (height ?? computed_size.height) + offsets.height,
    noChange: width == computed_size.width && height == computed_size.height,
  }
}

// This function will change the container size so that the resulting plot will be matching the provided specs
function changeContainerSize({ width, height }, sizeData = getSizeData()) {
  if (!CONTAINER.isPoppedOut()) {
    console.log("Tried to change container size when not popped, ignoring");
    return;
  }

  const csz = computeContainerSize({ width, height }, sizeData);

  if (csz.noChange) {
    console.log("Size is the same as current, ignoring");
    return
  }
  // We are now going to set he width and height of the container
  for (const key of ["width", "height"]) {
    CONTAINER.style[key] = csz[key] + "px";
  }
}
// We now create the function that will update the plot based on the values specified
function updateFromHeader() {
  const header_data = {
    height: config_spans.height.ui_value,
    width: config_spans.width.ui_value,
  };
  changeContainerSize(header_data);
}
// We assign this function to the onblur event of width and height
if (firstRun) {
  for (const container of Object.values(config_spans)) {
    container.ui_span.onblur = (e) => {
      container.ui_value = container.ui_span.textContent;
      updateFromHeader();
    };
  }
}
// This function computes the plot size to use for relayout as a function of the container size
function computePlotSize(data = getSizeData()) {
  // Remove Padding
  const { container_pad, plot_pad, container_rect } = data;
  const offsets = {
    width:
      plot_pad.padding.width +
      plot_pad.border.width +
      plot_pad.offset.left +
      container_pad.padding.width +
      container_pad.border.width,
    height:
      plot_pad.padding.height +
      plot_pad.border.height +
      plot_pad.offset.top +
      container_pad.padding.height +
      container_pad.border.height,
  };
  const sz = {
    width: Math.round(container_rect.width - offsets.width),
    height: Math.round(container_rect.height - offsets.height),
    offsets,
  };
  return sz;
}

// Create the resizeObserver to make the plot even more responsive! :magic:
const resizeObserver = new ResizeObserver((entries) => {
  const sizeData = getSizeData();
  const {container_rect, container_pad} = sizeData;
  let plot_size = computePlotSize(sizeData);
  // We save the height in the PLOT object
  PLOT.container_height = container_rect.height;
  // We deal with some stuff if the container is poppped
  CLIPBOARD_HEADER.style.width = container_rect.width + "px";
  CLIPBOARD_HEADER.style.left = container_rect.left + "px";
  config_spans.height.ui_value = plot_size.height;
  config_spans.width.ui_value = plot_size.width;
  /* 
		The addition of the invalid argument `plutoresize` seems to fix the problem with calling `relayout` simply with `{autosize: true}` as update breaking mouse relayout events tracking. 
		See https://github.com/plotly/plotly.js/issues/6156 for details
		*/
  let config = {
    // If this is popped out, we ignore the original width/height
    width: (CONTAINER.isPoppedOut() ? undefined : original_width) ?? plot_size.width,
    height: (CONTAINER.isPoppedOut() ? undefined : original_height) ?? plot_size.height,
    plutoresize: true,
  };
  Plotly.relayout(PLOT, config).then(() => {
    if (remove_container_size && !CONTAINER.isPoppedOut()) {
      // This is needed to avoid the first resize upon plot creation to already be without a fixed height
      CONTAINER.style.height = "";
      CONTAINER.style.width = "";
      remove_container_size = false;
    }
  });
});

resizeObserver.observe(CONTAINER);


Plotly.react(PLOT, plot_obj).then(() => {
	// Assign the Plotly event listeners
	for (const [key, listener_vec] of Object.entries(plotly_listeners)) {
		for (const listener of listener_vec) {
			PLOT.on(key, listener)
		}
	}
	// Assign the JS event listeners
	for (const [key, listener_vec] of Object.entries(js_listeners)) {
		for (const listener of listener_vec) {
			PLOT.addEventListener(key, listener, {
				signal: controller.signal
			})
		}
	}
}
)


invalidation.then(() => {
	// Remove all plotly listeners
	PLOT.removeAllListeners()
	// Remove all JS listeners
	controller.abort()
	// Remove the resizeObserver
	resizeObserver.disconnect()
})



		return CONTAINER
	</script>
</td></tr></table>
</div>mimetext/htmlrootassigneelast_run_timestampA/	/persist_js_state·has_pluto_hook_features§cell_id$418c045d-90c7-42d8-9126-90185f7e197bdepends_on_disabled_cells§runtime &published_object_keys5c6e0de0c-3901-11f0-234e-bd09c571f662/317eb0286b9488bc5c6e0de0c-3901-11f0-234e-bd09c571f662/298eb806dc8714d95c6e0de0c-3901-11f0-234e-bd09c571f662/dd4bace5c1b653a45c6e0de0c-3901-11f0-234e-bd09c571f662/e97923405a5e6801depends_on_skipped_cells§errored$6979db32-670d-466a-9a6e-97c2d8527f3dqueued¤logsrunning¦outputbodyp<div class="markdown"><blockquote>
<h3><em>Exercise 5.7</em></h3>
<p>In learning curves such as those shown in Figure 5.3 error generally decreases with training, as indeed happened for the ordinary importance-sampling method.  But for the weighted importance-sampling method error first increased and then decreased.  Why do you think this happened?</p>
</blockquote>
<p>In figure 5.3, the true value is about -.277 and we initialized the value function at zero.  For any given episode it is likely that the observed return will be -1.0 or 1.0 for a win or a loss.  Weighted importance sampling won&#39;t update the state value for trajectories which cannot occur in the target policy, so for some of the runs at this early state the state value is unchanged at the 0 initial value.  It is only after a certain number of episodes have occured that all of the values will be updated and produce an estimate which is worse than the initial value.  Once many samples with non zero weight are collected for each run, then the estimate starts to approach the true value again.  If instead we initialized the state value far away from the true value, then you would not see the initial increase in estimate error.  See below for an example using an initial value of 1.  In this case, no update from weighted importance sampling would produce an error larger than the initial value.</p>
<h3>Blackjack State Estimate with Bad Initialization</h3>
<p>Weighted importance sampling produces lower error estimates of the value of a single blackjack state from off-policy episodes</p>
	<script id='plot_1'>
		// We start by putting all the variable interpolation here at the beginning
		// We have to convert all typedarrays in the layout to normal arrays. See Issue #25
		// We use lodash for this for compactness
		function removeTypedArray(o) {
			return _.isTypedArray(o) ? Array.from(o) :
			_.isPlainObject(o) ? _.mapValues(o, removeTypedArray) : 
			o
		}

		// Publish the plot object to JS
		let plot_obj = _.update(/* See the documentation for AbstractPlutoDingetjes.Display.published_to_js */ getPublishedObject("c6e0de0c-3901-11f0-234e-bd09c571f662/8998d22fe9cbcd7d"), "layout", removeTypedArray)
		// Get the plotly listeners
		const plotly_listeners = {}
		// Get the JS listeners
		const js_listeners = {}
		// Deal with eventual custom classes
		let custom_classlist = []


		// Load the plotly library
		let Plotly = undefined
		try {
			let _mod = await import("./plotlyjs/plotlyjs-2.26.2.min.js")
			Plotly = _mod.default
		} catch (e) {
			console.log("Local load failed, trying with the web esm.sh version")
			let _mod = await import("https://esm.sh/plotly.js-dist-min@2.26.2/es2022/plotly.js-dist-min.mjs")
			Plotly = _mod.default
		}

		// Check if we have to force local mathjax font cache
		if (false && window?.MathJax?.config?.svg?.fontCache === 'global') {
			window.MathJax.config.svg.fontCache = 'local'
		}

		// Flag to check if this cell was  manually ran or reactively ran
const firstRun = this ? false : true
const CONTAINER = this ?? html`<div class='plutoplotly-container'>`
const PLOT = CONTAINER.querySelector('.js-plotly-plot') ?? CONTAINER.appendChild(html`<div>`)
const parent = CONTAINER.parentElement
// We use a controller to remove event listeners upon invalidation
const controller = new AbortController()
// We have to add this to keep supporting @bind with the old API using PLOT
PLOT.addEventListener('input', (e) => {
	CONTAINER.value = PLOT.value
	if (e.bubbles) {
		return
	}
	CONTAINER.dispatchEvent(new CustomEvent('input'))
}, { signal: controller.signal })

	// This create the style subdiv on first run
	firstRun && CONTAINER.appendChild(html`
	<style>
	.plutoplotly-container {
		width: 100%;
		height: 100%;
		min-height: 0;
		min-width: 0;
	}
	.plutoplotly-container .js-plotly-plot .plotly div {
		margin: 0 auto; // This centers the plot
	}
	.plutoplotly-container.popped-out {
		overflow: auto;
		z-index: 1000;
		position: fixed;
		resize: both;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		border-top-left-radius: 0px;
		border-top-right-radius: 0px;
	}
	.plutoplotly-clipboard-header {
		display: flex;
		flex-flow: row wrap;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-top-left-radius: 12px;
		border-top-right-radius: 12px;
		position: fixed;
		z-index: 1001;
		cursor: move;
		transform: translate(0px, -100%);
		padding: 5px;
	}
	.plutoplotly-clipboard-header span {
		display: inline-block;
		flex: 1
	}
	.plutoplotly-clipboard-header.hidden {
		display: none;
	}
	.clipboard-span {
		position: relative;
	}
	.clipboard-value {
		padding-right: 5px;
		padding-left: 2px;
		cursor: text;
	}
	.clipboard-span.format {
		display: none;
	}
	.clipboard-span.filename {
		flex: 0 0 100%;
		text-align: center;
		border-top: 3px solid var(--kbd-border-color);
		margin-top: 5px;
		display: none;
	}
	.plutoplotly-container.filesave .clipboard-span.filename {
		display: inline-block;
	}
	.clipboard-value.filename {
		margin-left: 3px;
		text-align: left;
		min-width: min(60%, min-content);
	}
	.plutoplotly-container.filesave .clipboard-span.format {
		display: inline-flex;
	}
	.clipboard-span.format .label {
		flex: 0 0 0;
	}
	.clipboard-value.format {
		position: relative;
		flex: 1 0 auto;
		min-width: 30px;
		margin-right: 10px;
	}
	div.format-options {
		display: inline-flex;
		flex-flow: column;
		position: absolute;
		background: var(--main-bg-color);
		border-radius: 12px;
		padding-left: 3px;
		z-index: 2000;
	}
	div.format-options:hover {
		cursor: pointer;
		border: 3px solid var(--kbd-border-color);
		padding: 3px;
		transform: translate(-3px, -6px);
	}
	div.format-options .format-option {
		display: none;
	}
	div.format-options:hover .format-option {
		display: inline-block;
	}
	.format-option:not(.selected) {
		margin-top: 3px;
	}
	div.format-options .format-option.selected {
		order: -1;
		display: inline-block;
	}
	.format-option:hover {
		background-color: var(--kbd-border-color);
	}
	span.config-value {
		font-weight: normal;
		color: var(--pluto-output-color);
		display: none;
		position: absolute;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		transform: translate(0px, calc(-100% - 10px));
		padding: 5px;
	}
	.label {
		user-select: none;
	}
	.label:hover span.config-value {
		display: inline-block;
		min-width: 150px;
	}
	.clipboard-span.matching-config .label {
		color: var(--cm-macro-color);
		font-weight: bold;
	}
	.clipboard-span.different-config .label {
		color: var(--cm-tag-color);
		font-weight: bold;
	}
</style>
`)

let original_height = plot_obj.layout.height
let original_width = plot_obj.layout.width
// For the height we have to also put a fixed value in case the plot is put on a non-fixed-size container (like the default wrapper)
// We define a variable to check whether we still have to remove the fixed height
let remove_container_size = firstRun
let container_height = original_height ?? PLOT.container_height ?? 400
CONTAINER.style.height = container_height + 'px'

// We create a Promise version of setTimeout
function delay(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

// We import interact for dragging/resizing
const { default: interact } = await import('https://esm.sh/interactjs@1.10.19')


function getImageOptions() {
  const o = plot_obj.config.toImageButtonOptions ?? {};
  return {
    format: o.format ?? "png",
    width: o.width ?? original_width,
    height: o.height ?? original_height,
    scale: o.scale ?? 1,
    filename: o.filename ?? "newplot",
  };
}

const CLIPBOARD_HEADER =
  CONTAINER.querySelector(".plutoplotly-clipboard-header") ??
  CONTAINER.insertAdjacentElement(
    "afterbegin",
    html`<div class="plutoplotly-clipboard-header hidden">
      <span class="clipboard-span format"
        ><span class="label">Format:</span
        ><span class="clipboard-value format"></span
      ></span>
      <span class="clipboard-span width"
        ><span class="label">Width:</span
        ><span class="clipboard-value width"></span>px</span
      >
      <span class="clipboard-span height"
        ><span class="label">Height:</span
        ><span class="clipboard-value height"></span>px</span
      >
      <span class="clipboard-span scale"
        ><span class="label">Scale:</span
        ><span class="clipboard-value scale"></span
      ></span>
      <button class="clipboard-span set">Set</button>
      <button class="clipboard-span unset">Unset</button>
      <span class="clipboard-span filename"
        ><span class="label">Filename:</span
        ><span class="clipboard-value filename"></span
      ></span>
    </div>`
  );

function checkConfigSync(container) {
  const valid_classes = [
    "missing-config",
    "matching-config",
    "different-config",
  ];
  function setClass(cl) {
    for (const name of valid_classes) {
      container.classList.toggle(name, name == cl);
    }
  }
  // We use the custom getters we'll set up in the container
  const { ui_value, config_value, config_span, key } = container;
  if (config_value === undefined) {
    setClass("missing-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> is not present in the config.`;
  } else if (ui_value == config_value) {
    setClass("matching-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has the same value in the config and in the header.`;
  } else {
    setClass("different-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has a different value (<em>${config_value}</em>) in the config.`;
  }
  // Add info about setting and unsetting
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click on the label <em><b>once</b></em> to set the current UI value in the config.`
  );
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click <em><b>twice</b></em> to remove this key from the config.`
  );
}

const valid_formats = ["png", "svg", "webp", "jpeg", "full-json"];
function initializeUIValueSpan(span, key, value) {
  const container = span.closest(".clipboard-span");
  span.contentEditable = key === "format" ? "false" : "true";
  let parse = (x) => x;
  let update = (x) => (span.textContent = x);
  if (key === "width" || key === "height") {
    parse = (x) => Math.round(parseFloat(x));
  } else if (key === "scale") {
    parse = parseFloat;
  } else if (key === "format") {
    // We remove contentEditable
    span.contentEditable = "false";
    // Here we first add the subspans for each option
    const opts_div = span.appendChild(html`<div class="format-options"></div>`);
    for (const fmt of valid_formats) {
      const opt = opts_div.appendChild(
        html`<span class="format-option ${fmt}">${fmt}</span>`
      );
      opt.onclick = (e) => {
        span.value = opt.textContent;
      };
    }
    parse = (x) => {
      return valid_formats.includes(x) ? x : localValue;
    };
    update = (x) => {
      for (const opt of opts_div.children) {
        opt.classList.toggle("selected", opt.textContent === x);
      }
    };
  } else {
    // We only have filename here
  }
  let localValue;
  Object.defineProperty(span, "value", {
    get: () => {
      return localValue;
    },
    set: (val) => {
      if (val !== "") {
        localValue = parse(val);
      }
      update(localValue);
      checkConfigSync(container);
    },
  });
  // We also assign a listener so that the editable is blurred when enter is pressed
  span.onkeydown = (e) => {
    if (e.keyCode === 13) {
      e.preventDefault();
      span.blur();
    }
  };
  span.value = value;
}

function initializeConfigValueSpan(span, key) {
  // Here we mostly want to define the setter and getter
  const container = span.closest(".clipboard-span");
  Object.defineProperty(span, "value", {
    get: () => {
      return plot_obj.config.toImageButtonOptions[key];
    },
    set: (val) => {
      // if undefined is passed, we remove the entry from the options
      if (val === undefined) {
        delete plot_obj.config.toImageButtonOptions[key];
      } else {
        plot_obj.config.toImageButtonOptions[key] = val;
      }
      checkConfigSync(container);
    },
  });
}

const config_spans = {};
for (const [key, value] of Object.entries(getImageOptions())) {
  const container = CLIPBOARD_HEADER.querySelector(`.clipboard-span.${key}`);
  const label = container.querySelector(".label");
  // We give the label a function that on single click will set the current value and with double click will unset it
  label.onclick = DualClick(
    () => {
      container.config_value = container.ui_value;
    },
    (e) => {
      console.log("e", e);
      e.preventDefault();
      container.config_value = undefined;
    }
  );
  const ui_value_span = container.querySelector(".clipboard-value");
  const config_value_span =
    container.querySelector(".config-value") ??
    label.insertAdjacentElement(
      "afterbegin",
      html`<span class="config-value"></span>`
    );
  // Assing the two spans as properties of the containing span
  container.ui_span = ui_value_span;
  container.config_span = config_value_span;
  container.key = key;
  config_spans[key] = container;
  if (firstRun) {
    plot_obj.config.toImageButtonOptions =
      plot_obj.config.toImageButtonOptions ?? {};
    // We do the initialization of the value span
    initializeUIValueSpan(ui_value_span, key, value);
    // Then we initialize the config value
    initializeConfigValueSpan(config_value_span, key);
    // We put some convenience getters/setters
    // ui_value forward
    Object.defineProperty(container, "ui_value", {
      get: () => ui_value_span.value,
      set: (val) => {
        ui_value_span.value = val;
      },
    });
    // config_value forward
    Object.defineProperty(container, "config_value", {
      get: () => config_value_span.value,
      set: (val) => {
        config_value_span.value = val;
      },
    });
  }
}

// These objects will contain the default value

// This code updates the image options in the PLOT config with the provided ones
function setImageOptions(o) {
  for (const [key, container] of Object.entries(config_spans)) {
    container.config_value = o[key];
  }
}
function unsetImageOptions() {
  setImageOptions({});
}

const set_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.set");
const unset_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.unset");
if (firstRun) {
  set_button.onclick = (e) => {
    for (const container of Object.values(config_spans)) {
      container.config_value = container.ui_value;
    }
  };
  unset_button.onclick = unsetImageOptions;
}

// We add a function to check if the clipboard is popped out
CONTAINER.isPoppedOut = () => {
  return CONTAINER.classList.contains("popped-out");
};

CLIPBOARD_HEADER.onmousedown = function (event) {
  if (event.target.matches("span.clipboard-value")) {
    console.log("We don't move!");
    return;
  }
  const start = {
    left: parseFloat(CONTAINER.style.left),
    top: parseFloat(CONTAINER.style.top),
    X: event.pageX,
    Y: event.pageY,
  };
  function moveAt(event, start) {
    const top = event.pageY - start.Y + start.top + "px";
    const left = event.pageX - start.X + start.left + "px";
    CLIPBOARD_HEADER.style.left = left;
    CONTAINER.style.left = left;
    CONTAINER.style.top = top;
  }

  // move our absolutely positioned ball under the pointer
  moveAt(event, start);
  function onMouseMove(event) {
    moveAt(event, start);
  }

  // We use this to remove the mousemove when clicking outside of the container
  const controller = new AbortController();

  // move the container on mousemove
  document.addEventListener("mousemove", onMouseMove, {
    signal: controller.signal,
  });
  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        cleanUp();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );

  function cleanUp() {
    console.log("cleaning up the plot move listener");
    controller.abort();
    CLIPBOARD_HEADER.onmouseup = null;
  }

  // (3) drop the ball, remove unneeded handlers
  CLIPBOARD_HEADER.onmouseup = cleanUp;
};

function sendToClipboard(blob) {
  if (!navigator.clipboard) {
    alert(
      "The Clipboard API does not seem to be available, make sure the Pluto notebook is being used from either localhost or an https source."
    );
  }
  navigator.clipboard
    .write([
      new ClipboardItem({
        // The key is determined dynamically based on the blob's type.
        [blob.type]: blob,
      }),
    ])
    .then(
      function () {
        console.log("Async: Copying to clipboard was successful!");
      },
      function (err) {
        console.error("Async: Could not copy text: ", err);
      }
    );
}

function copyImageToClipboard() {
  // We extract the image options from the provided parameters (if they exist)
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key. We also ignore format because the clipboard only supports png.
    if (val === undefined || key === "format") {
      continue;
    }
    config[key] = val;
  }
  Plotly.toImage(PLOT, config).then(function (dataUrl) {
    fetch(dataUrl)
      .then((res) => res.blob())
      .then((blob) => {
        const paste_receiver = document.querySelector('paste-receiver.plutoplotly')
        if (paste_receiver) {
          paste_receiver.attachImage(dataUrl, CONTAINER)
        }
        sendToClipboard(blob)
      });
  });
}

function saveImageToFile() {
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key.
    if (val === undefined) {
      continue;
    }
    config[key] = val;
  }
  Plotly.downloadImage(PLOT, config);
}

let container_rect = { width: 0, height: 0, top: 0, left: 0 };
function unpop_container(cl) {
  CONTAINER.classList.toggle("popped-out", false);
  CONTAINER.classList.toggle(cl, false);
  // We fix the height back to the value it had before popout, also setting the flag to signal that upon first resize we remove the fixed inline-style
  CONTAINER.style.height = container_rect.height + "px";
  remove_container_size = true;
  // We set the other fixed inline-styles to null
  CONTAINER.style.width = "";
  CONTAINER.style.top = "";
  CONTAINER.style.left = "";
  // We also remove the CLIPBOARD_HEADER
  CLIPBOARD_HEADER.style.width = "";
  CLIPBOARD_HEADER.style.left = "";
  // Finally we remove the hidden class to the header
  CLIPBOARD_HEADER.classList.toggle("hidden", true);
  return;
}
function popout_container(opts) {
  const cl = opts?.cl;
  const target_container_size = opts?.target_container_size ?? {};
  const target_plot_size = opts?.target_plot_size ?? {};
  if (CONTAINER.isPoppedOut()) {
    return unpop_container(cl);
  }
  CONTAINER.classList.toggle(cl, cl === undefined ? false : true);
  // We extract the current size of the container, save them and fix them
  const { width, height, top, left } = CONTAINER.getBoundingClientRect();
  container_rect = { width, height, top, left };
  // We save the current plot size before we pop as it will fill the screen
  const current_plot_size = {
    width: PLOT._fullLayout.width,
    height: PLOT._fullLayout.height,
  };
  // We have to save the pad data before popping so we can resize precisely
  const pad = {};
  pad.unpopped = getSizeData().container_pad;
  CONTAINER.classList.toggle("popped-out", true);
  pad.popped = getSizeData().container_pad;
  // We do top and left based on the current rect
  for (const key of ["top", "left"]) {
    const start_val = target_container_size[key] ?? container_rect[key];
    let offset = 0;
    for (const kind of ["padding", "border"]) {
      offset += pad.popped[kind][key] - pad.unpopped[kind][key];
    }
    CONTAINER.style[key] = start_val - offset + "px";
    if (key === "left") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  // We compute the width and height depending on eventual config data
  const csz = computeContainerSize({
    width:
      target_plot_size.width ??
      config_spans.width.config_value ??
      current_plot_size.width,
    height:
      target_plot_size.height ??
      config_spans.height.config_value ??
      current_plot_size.height,
  });
  for (const key of ["width", "height"]) {
    const val = target_container_size[key] ?? csz[key];
    CONTAINER.style[key] = val + "px";
    if (key === "width") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  CLIPBOARD_HEADER.classList.toggle("hidden", false);
  const controller = new AbortController();

  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        unpop_container();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );
}

CONTAINER.popOut = popout_container;

function DualClick(single_func, dbl_func) {
  let nclicks = 0;
  return function (...args) {
    nclicks += 1;
    if (nclicks > 1) {
      dbl_func(...args);
      nclicks = 0;
    } else {
      delay(300).then(() => {
        if (nclicks == 1) {
          single_func(...args);
        }
        nclicks = 0;
      });
    }
  };
}

// We remove the default download image button
plot_obj.config.modeBarButtonsToRemove = _.union(
  plot_obj.config.modeBarButtonsToRemove,
  ["toImage"]
);
// We add the custom button to the modebar
plot_obj.config.modeBarButtonsToAdd = _.union(
  plot_obj.config.modeBarButtonsToAdd,
  [
    {
      name: "Copy PNG to Clipboard",
      icon: {
        height: 520,
        width: 520,
        path: "M280 64h40c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128C0 92.7 28.7 64 64 64h40 9.6C121 27.5 153.3 0 192 0s71 27.5 78.4 64H280zM64 112c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16H320c8.8 0 16-7.2 16-16V128c0-8.8-7.2-16-16-16H304v24c0 13.3-10.7 24-24 24H192 104c-13.3 0-24-10.7-24-24V112H64zm128-8a24 24 0 1 0 0-48 24 24 0 1 0 0 48z",
      },
      direction: "up",
      click: DualClick(copyImageToClipboard, () => {
        popout_container();
      }),
    },
    {
      name: "Download Image",
      icon: Plotly.Icons.camera,
      direction: "up",
      click: DualClick(saveImageToFile, () => {
        popout_container({ cl: "filesave" });
      }),
    },
  ]
);

function getOffsetData(el) {
  let cs = window.getComputedStyle(el, null);
  const odata = {
    padding: {
      left: parseFloat(cs.paddingLeft),
      right: parseFloat(cs.paddingRight),
      top: parseFloat(cs.paddingTop),
      bottom: parseFloat(cs.paddingBottom),
      width: parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight),
      height: parseFloat(cs.paddingTop) + parseFloat(cs.paddingBottom),
    },
    border: {
      left: parseFloat(cs.borderLeftWidth),
      right: parseFloat(cs.borderRightWidth),
      top: parseFloat(cs.borderTopWidth),
      bottom: parseFloat(cs.borderBottomWidth),
      width: parseFloat(cs.borderLeftWidth) + parseFloat(cs.borderRightWidth),
      height: parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth),
    }
  };
  if (el === PLOT) {
    // For the PLOT we also want to take into account the offset
    odata.offset = {
      top: PLOT.offsetParent == CONTAINER ? PLOT.offsetTop : 0,
      left: PLOT.offsetParent == CONTAINER ? PLOT.offsetLeft : 0,
    }
  }
  return odata;
}
function getSizeData() {
  const data = {
    plot_pad: getOffsetData(PLOT),
    plot_rect: PLOT.getBoundingClientRect(),
    container_pad: getOffsetData(CONTAINER),
    container_rect: CONTAINER.getBoundingClientRect(),
  };
  return data;
}
function computeContainerSize({ width, height }, sizeData = getSizeData()) {
  const computed_size = computePlotSize(sizeData);
  const offsets = computed_size.offsets;

  const plot_data = {
    width: width ?? computed_size.width,
    height: height ?? computed_size.height,
  };

  return {
    width: (width ?? computed_size.width) + offsets.width,
    height: (height ?? computed_size.height) + offsets.height,
    noChange: width == computed_size.width && height == computed_size.height,
  }
}

// This function will change the container size so that the resulting plot will be matching the provided specs
function changeContainerSize({ width, height }, sizeData = getSizeData()) {
  if (!CONTAINER.isPoppedOut()) {
    console.log("Tried to change container size when not popped, ignoring");
    return;
  }

  const csz = computeContainerSize({ width, height }, sizeData);

  if (csz.noChange) {
    console.log("Size is the same as current, ignoring");
    return
  }
  // We are now going to set he width and height of the container
  for (const key of ["width", "height"]) {
    CONTAINER.style[key] = csz[key] + "px";
  }
}
// We now create the function that will update the plot based on the values specified
function updateFromHeader() {
  const header_data = {
    height: config_spans.height.ui_value,
    width: config_spans.width.ui_value,
  };
  changeContainerSize(header_data);
}
// We assign this function to the onblur event of width and height
if (firstRun) {
  for (const container of Object.values(config_spans)) {
    container.ui_span.onblur = (e) => {
      container.ui_value = container.ui_span.textContent;
      updateFromHeader();
    };
  }
}
// This function computes the plot size to use for relayout as a function of the container size
function computePlotSize(data = getSizeData()) {
  // Remove Padding
  const { container_pad, plot_pad, container_rect } = data;
  const offsets = {
    width:
      plot_pad.padding.width +
      plot_pad.border.width +
      plot_pad.offset.left +
      container_pad.padding.width +
      container_pad.border.width,
    height:
      plot_pad.padding.height +
      plot_pad.border.height +
      plot_pad.offset.top +
      container_pad.padding.height +
      container_pad.border.height,
  };
  const sz = {
    width: Math.round(container_rect.width - offsets.width),
    height: Math.round(container_rect.height - offsets.height),
    offsets,
  };
  return sz;
}

// Create the resizeObserver to make the plot even more responsive! :magic:
const resizeObserver = new ResizeObserver((entries) => {
  const sizeData = getSizeData();
  const {container_rect, container_pad} = sizeData;
  let plot_size = computePlotSize(sizeData);
  // We save the height in the PLOT object
  PLOT.container_height = container_rect.height;
  // We deal with some stuff if the container is poppped
  CLIPBOARD_HEADER.style.width = container_rect.width + "px";
  CLIPBOARD_HEADER.style.left = container_rect.left + "px";
  config_spans.height.ui_value = plot_size.height;
  config_spans.width.ui_value = plot_size.width;
  /* 
		The addition of the invalid argument `plutoresize` seems to fix the problem with calling `relayout` simply with `{autosize: true}` as update breaking mouse relayout events tracking. 
		See https://github.com/plotly/plotly.js/issues/6156 for details
		*/
  let config = {
    // If this is popped out, we ignore the original width/height
    width: (CONTAINER.isPoppedOut() ? undefined : original_width) ?? plot_size.width,
    height: (CONTAINER.isPoppedOut() ? undefined : original_height) ?? plot_size.height,
    plutoresize: true,
  };
  Plotly.relayout(PLOT, config).then(() => {
    if (remove_container_size && !CONTAINER.isPoppedOut()) {
      // This is needed to avoid the first resize upon plot creation to already be without a fixed height
      CONTAINER.style.height = "";
      CONTAINER.style.width = "";
      remove_container_size = false;
    }
  });
});

resizeObserver.observe(CONTAINER);


Plotly.react(PLOT, plot_obj).then(() => {
	// Assign the Plotly event listeners
	for (const [key, listener_vec] of Object.entries(plotly_listeners)) {
		for (const listener of listener_vec) {
			PLOT.on(key, listener)
		}
	}
	// Assign the JS event listeners
	for (const [key, listener_vec] of Object.entries(js_listeners)) {
		for (const listener of listener_vec) {
			PLOT.addEventListener(key, listener, {
				signal: controller.signal
			})
		}
	}
}
)


invalidation.then(() => {
	// Remove all plotly listeners
	PLOT.removeAllListeners()
	// Remove all JS listeners
	controller.abort()
	// Remove the resizeObserver
	resizeObserver.disconnect()
})



		return CONTAINER
	</script>


</div>mimetext/htmlrootassigneelast_run_timestampA-Fgpersist_js_state·has_pluto_hook_features§cell_id$6979db32-670d-466a-9a6e-97c2d8527f3ddepends_on_disabled_cells§runtime?m"published_object_keys5c6e0de0c-3901-11f0-234e-bd09c571f662/8998d22fe9cbcd7ddepends_on_skipped_cells§errored$cd928f87-2832-4595-8ce5-79b69cc56bd9queued¤logsrunning¦outputbodyg<div class="markdown"><h4>Figure 5.5</h4>
<p>A couple of right turns for the racetrack task.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA"*&gpersist_js_state·has_pluto_hook_features§cell_id$cd928f87-2832-4595-8ce5-79b69cc56bd9depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$ba044e4f-e2a6-4f96-8756-5b24b1bb5ca2queued¤logsrunning¦outputbody *<div style = "display: flex; align-items: flex-end;">
<div>
Race finished in 10643 steps
<div style="background-color: white; color: black;">
	<div style="display:flex; align-items: flex-start">
	<div class = "track">
		<div class = "start" vx = "0" vy = "0" dvx = "0" dvy = "1" style="grid-column-start: 4; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "0" dvy = "0" style="grid-column-start: 8; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "-1" dvy = "1" style="grid-column-start: 9; grid-row-start: 1;"></div><div class = "start" vx = "1" vy = "0" dvx = "0" dvy = "-1" style="grid-column-start: 6; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "-1" dvy = "1" style="grid-column-start: 7; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "1" dvy = "-1" style="grid-column-start: 5; grid-row-start: 1;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 5;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "0" style="grid-column-start: 6; grid-row-start: 27;"></div><div class = "" vx = "1" vy = "3" dvx = "1" dvy = "1" style="grid-column-start: 9; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 23;"></div><div class = "" vx = "0" vy = "3" dvx = "1" dvy = "1" style="grid-column-start: 4; grid-row-start: 18;"></div><div class = "" vx = "2" vy = "3" dvx = "-1" dvy = "1" style="grid-column-start: 10; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 22;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "1" style="grid-column-start: 8; grid-row-start: 24;"></div><div class = "" vx = "0" vy = "4" dvx = "0" dvy = "0" style="grid-column-start: 7; grid-row-start: 14;"></div><div class = "" vx = "1" vy = "1" dvx = "-1" dvy = "-1" style="grid-column-start: 10; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 27;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "1" style="grid-column-start: 5; grid-row-start: 11;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 7; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 31;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "-1" style="grid-column-start: 11; grid-row-start: 29;"></div><div class = "" vx = "1" vy = "3" dvx = "1" dvy = "1" style="grid-column-start: 6; grid-row-start: 30;"></div><div class = "" vx = "0" vy = "3" dvx = "1" dvy = "0" style="grid-column-start: 6; grid-row-start: 13;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "-1" style="grid-column-start: 8; grid-row-start: 15;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "-1" style="grid-column-start: 9; grid-row-start: 11;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "0" style="grid-column-start: 4; grid-row-start: 24;"></div><div class = "" vx = "1" vy = "0" dvx = "-1" dvy = "1" style="grid-column-start: 7; grid-row-start: 7;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "1" style="grid-column-start: 8; grid-row-start: 17;"></div><div class = "" vx = "0" vy = "4" dvx = "0" dvy = "1" style="grid-column-start: 6; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 30;"></div><div class = "" vx = "1" vy = "4" dvx = "0" dvy = "-1" style="grid-column-start: 5; grid-row-start: 22;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "-1" style="grid-column-start: 6; grid-row-start: 20;"></div><div class = "" vx = "1" vy = "3" dvx = "0" dvy = "-1" style="grid-column-start: 5; grid-row-start: 12;"></div><div class = "" vx = "2" vy = "0" dvx = "0" dvy = "-1" style="grid-column-start: 13; grid-row-start: 32;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "-1" style="grid-column-start: 8; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 26;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "0" style="grid-column-start: 9; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 23;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "0" style="grid-column-start: 4; grid-row-start: 15;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "-1" style="grid-column-start: 9; grid-row-start: 12;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 12; grid-row-start: 32;"></div><div class = "" vx = "1" vy = "3" dvx = "-1" dvy = "-1" style="grid-column-start: 7; grid-row-start: 16;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "1" style="grid-column-start: 4; grid-row-start: 17;"></div><div class = "" vx = "0" vy = "3" dvx = "1" dvy = "0" style="grid-column-start: 6; grid-row-start: 19;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "1" style="grid-column-start: 6; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 25;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "-1" style="grid-column-start: 5; grid-row-start: 5;"></div><div class = "" vx = "1" vy = "3" dvx = "1" dvy = "-1" style="grid-column-start: 6; grid-row-start: 26;"></div><div class = "" vx = "1" vy = "2" dvx = "0" dvy = "0" style="grid-column-start: 6; grid-row-start: 8;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "-1" style="grid-column-start: 8; grid-row-start: 29;"></div><div class = "" vx = "0" vy = "3" dvx = "1" dvy = "0" style="grid-column-start: 5; grid-row-start: 23;"></div><div class = "" vx = "1" vy = "2" dvx = "1" dvy = "1" style="grid-column-start: 9; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 29;"></div><div class = "" vx = "1" vy = "2" dvx = "-1" dvy = "0" style="grid-column-start: 7; grid-row-start: 18;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "-1" style="grid-column-start: 9; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 30;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "0" style="grid-column-start: 6; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 29;"></div><div class = "" vx = "1" vy = "0" dvx = "-1" dvy = "0" style="grid-column-start: 10; grid-row-start: 28;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "0" style="grid-column-start: 5; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 13;"></div><div class = "" vx = "1" vy = "4" dvx = "-1" dvy = "0" style="grid-column-start: 8; grid-row-start: 11;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "0" style="grid-column-start: 6; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 24;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 9; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 20;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "0" style="grid-column-start: 6; grid-row-start: 21;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "0" style="grid-column-start: 7; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 27;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "1" style="grid-column-start: 6; grid-row-start: 28;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "0" style="grid-column-start: 6; grid-row-start: 3;"></div><div class = "" vx = "1" vy = "3" dvx = "-1" dvy = "0" style="grid-column-start: 8; grid-row-start: 22;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "0" style="grid-column-start: 4; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 9;"></div><div class = "" vx = "0" vy = "4" dvx = "0" dvy = "-1" style="grid-column-start: 8; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 28;"></div><div class = "" vx = "3" vy = "3" dvx = "0" dvy = "0" style="grid-column-start: 11; grid-row-start: 31;"></div><div class = "" vx = "1" vy = "3" dvx = "1" dvy = "0" style="grid-column-start: 7; grid-row-start: 15;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "-1" style="grid-column-start: 7; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 26;"></div><div class = "" vx = "0" vy = "3" dvx = "1" dvy = "0" style="grid-column-start: 5; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 25;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "-1" style="grid-column-start: 6; grid-row-start: 6;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "0" style="grid-column-start: 4; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 13;"></div><div class = "" vx = "0" vy = "4" dvx = "0" dvy = "1" style="grid-column-start: 7; grid-row-start: 25;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "0" style="grid-column-start: 4; grid-row-start: 12;"></div><div class = "" vx = "0" vy = "4" dvx = "0" dvy = "1" style="grid-column-start: 9; grid-row-start: 27;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "1" style="grid-column-start: 8; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 20;"></div><div class = "" vx = "1" vy = "1" dvx = "0" dvy = "0" style="grid-column-start: 8; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 10;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "0" style="grid-column-start: 6; grid-row-start: 14;"></div><div class = "" vx = "0" vy = "4" dvx = "-1" dvy = "-1" style="grid-column-start: 5; grid-row-start: 30;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "-1" style="grid-column-start: 5; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 19;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 4; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 27;"></div><div class = "" vx = "0" vy = "4" dvx = "-1" dvy = "0" style="grid-column-start: 7; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 32;"></div><div class = "" vx = "1" vy = "1" dvx = "0" dvy = "1" style="grid-column-start: 6; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 21;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "-1" style="grid-column-start: 8; grid-row-start: 31;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "-1" style="grid-column-start: 9; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 23;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "1" style="grid-column-start: 5; grid-row-start: 20;"></div><div class = "" vx = "1" vy = "3" dvx = "1" dvy = "1" style="grid-column-start: 9; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 31;"></div><div class = "" vx = "0" vy = "3" dvx = "1" dvy = "0" style="grid-column-start: 9; grid-row-start: 32;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "1" style="grid-column-start: 6; grid-row-start: 7;"></div><div class = "" vx = "1" vy = "3" dvx = "-1" dvy = "0" style="grid-column-start: 9; grid-row-start: 20;"></div><div class = "" vx = "1" vy = "0" dvx = "-1" dvy = "1" style="grid-column-start: 14; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 29;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "1" style="grid-column-start: 5; grid-row-start: 19;"></div><div class = "" vx = "1" vy = "3" dvx = "1" dvy = "1" style="grid-column-start: 5; grid-row-start: 9;"></div><div class = "" vx = "0" vy = "4" dvx = "0" dvy = "1" style="grid-column-start: 4; grid-row-start: 31;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 11; grid-row-start: 30;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "-1" style="grid-column-start: 7; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 6;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "0" style="grid-column-start: 6; grid-row-start: 16;"></div><div class = "" vx = "2" vy = "1" dvx = "-1" dvy = "-1" style="grid-column-start: 9; grid-row-start: 9;"></div><div class = "" vx = "1" vy = "4" dvx = "-1" dvy = "1" style="grid-column-start: 9; grid-row-start: 19;"></div><div class = "" vx = "1" vy = "0" dvx = "1" dvy = "0" style="grid-column-start: 11; grid-row-start: 32;"></div><div class = "" vx = "0" vy = "4" dvx = "0" dvy = "1" style="grid-column-start: 5; grid-row-start: 26;"></div><div class = "" vx = "1" vy = "2" dvx = "1" dvy = "-1" style="grid-column-start: 5; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 22;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "0" style="grid-column-start: 7; grid-row-start: 22;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "-1" style="grid-column-start: 8; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 21;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "1" style="grid-column-start: 9; grid-row-start: 26;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "-1" style="grid-column-start: 9; grid-row-start: 8;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 7; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 14;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "-1" style="grid-column-start: 5; grid-row-start: 10;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "1" style="grid-column-start: 6; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 27;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "1" style="grid-column-start: 4; grid-row-start: 27;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "1" style="grid-column-start: 5; grid-row-start: 4;"></div><div class = "" vx = "1" vy = "2" dvx = "-1" dvy = "-1" style="grid-column-start: 9; grid-row-start: 10;"></div><div class = "" vx = "0" vy = "4" dvx = "0" dvy = "-1" style="grid-column-start: 5; grid-row-start: 21;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "-1" style="grid-column-start: 7; grid-row-start: 5;"></div><div class = "" vx = "0" vy = "4" dvx = "1" dvy = "0" style="grid-column-start: 8; grid-row-start: 30;"></div><div class = "" vx = "1" vy = "3" dvx = "0" dvy = "1" style="grid-column-start: 8; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 7;"></div><div class = "" vx = "1" vy = "2" dvx = "0" dvy = "0" style="grid-column-start: 9; grid-row-start: 4;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "1" style="grid-column-start: 8; grid-row-start: 32;"></div><div class = "" vx = "1" vy = "3" dvx = "0" dvy = "1" style="grid-column-start: 7; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 30;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "0" style="grid-column-start: 5; grid-row-start: 28;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "0" style="grid-column-start: 5; grid-row-start: 3;"></div><div class = "" vx = "0" vy = "3" dvx = "1" dvy = "-1" style="grid-column-start: 9; grid-row-start: 21;"></div><div class = "" vx = "0" vy = "4" dvx = "1" dvy = "-1" style="grid-column-start: 8; grid-row-start: 20;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "0" style="grid-column-start: 6; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 30;"></div><div class = "" vx = "2" vy = "0" dvx = "1" dvy = "-1" style="grid-column-start: 15; grid-row-start: 32;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "0" style="grid-column-start: 9; grid-row-start: 28;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "0" style="grid-column-start: 9; grid-row-start: 3;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "-1" style="grid-column-start: 4; grid-row-start: 30;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "-1" style="grid-column-start: 14; grid-row-start: 32;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "1" style="grid-column-start: 4; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 16;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "0" style="grid-column-start: 7; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 14;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "0" style="grid-column-start: 4; grid-row-start: 32;"></div><div class = "" vx = "1" vy = "1" dvx = "1" dvy = "1" style="grid-column-start: 5; grid-row-start: 6;"></div><div class = "" vx = "0" vy = "4" dvx = "1" dvy = "1" style="grid-column-start: 8; grid-row-start: 19;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "1" style="grid-column-start: 8; grid-row-start: 9;"></div><div class = "" vx = "1" vy = "2" dvx = "1" dvy = "-1" style="grid-column-start: 6; grid-row-start: 15;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "-1" style="grid-column-start: 4; grid-row-start: 20;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "0" style="grid-column-start: 6; grid-row-start: 17;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "0" style="grid-column-start: 9; grid-row-start: 6;"></div><div class = "" vx = "1" vy = "0" dvx = "-1" dvy = "1" style="grid-column-start: 11; grid-row-start: 28;"></div><div class = "" vx = "0" vy = "4" dvx = "0" dvy = "0" style="grid-column-start: 8; grid-row-start: 26;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "1" style="grid-column-start: 8; grid-row-start: 8;"></div><div class = "" vx = "0" vy = "3" dvx = "1" dvy = "0" style="grid-column-start: 6; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 31;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "1" style="grid-column-start: 4; grid-row-start: 19;"></div><div class = "" vx = "0" vy = "3" dvx = "1" dvy = "0" style="grid-column-start: 4; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 18;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "1" style="grid-column-start: 10; grid-row-start: 29;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "0" style="grid-column-start: 5; grid-row-start: 14;"></div><div class = "" vx = "1" vy = "0" dvx = "1" dvy = "1" style="grid-column-start: 5; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 27;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 4; grid-row-start: 8;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "0" style="grid-column-start: 8; grid-row-start: 10;"></div><div class = "" vx = "1" vy = "2" dvx = "0" dvy = "0" style="grid-column-start: 9; grid-row-start: 14;"></div><div class = "" vx = "1" vy = "4" dvx = "0" dvy = "1" style="grid-column-start: 7; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 16;"></div><div class = "" vx = "2" vy = "1" dvx = "0" dvy = "0" style="grid-column-start: 9; grid-row-start: 2;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "0" style="grid-column-start: 6; grid-row-start: 29;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "1" style="grid-column-start: 5; grid-row-start: 7;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "-1" style="grid-column-start: 8; grid-row-start: 4;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "0" style="grid-column-start: 8; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 29;"></div><div class = "" vx = "2" vy = "3" dvx = "1" dvy = "0" style="grid-column-start: 9; grid-row-start: 7;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "1" style="grid-column-start: 4; grid-row-start: 10;"></div><div class = "" vx = "2" vy = "2" dvx = "1" dvy = "1" style="grid-column-start: 8; grid-row-start: 28;"></div><div class = "" vx = "1" vy = "1" dvx = "-1" dvy = "1" style="grid-column-start: 8; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 18;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "1" style="grid-column-start: 7; grid-row-start: 30;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "1" style="grid-column-start: 5; grid-row-start: 16;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "-1" style="grid-column-start: 4; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 15;"></div><div class = "" vx = "2" vy = "4" dvx = "0" dvy = "-1" style="grid-column-start: 7; grid-row-start: 13;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "1" style="grid-column-start: 4; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 17;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "0" style="grid-column-start: 6; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 28;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "0" style="grid-column-start: 7; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 20;"></div><div class = "" vx = "1" vy = "0" dvx = "-1" dvy = "1" style="grid-column-start: 9; grid-row-start: 16;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "0" style="grid-column-start: 7; grid-row-start: 20;"></div><div class = "" vx = "1" vy = "2" dvx = "-1" dvy = "1" style="grid-column-start: 8; grid-row-start: 6;"></div><div class = "" vx = "0" vy = "4" dvx = "1" dvy = "-1" style="grid-column-start: 4; grid-row-start: 28;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "0" style="grid-column-start: 4; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 25;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "1" style="grid-column-start: 6; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 19;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "0" style="grid-column-start: 5; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 24;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "-1" style="grid-column-start: 6; grid-row-start: 12;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "1" style="grid-column-start: 7; grid-row-start: 19;"></div><div class = "" vx = "1" vy = "3" dvx = "-1" dvy = "-1" style="grid-column-start: 7; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 32;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "1" style="grid-column-start: 4; grid-row-start: 6;"></div><div class = "" vx = "2" vy = "3" dvx = "-1" dvy = "-1" style="grid-column-start: 9; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 26;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "0" style="grid-column-start: 8; grid-row-start: 14;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "0" style="grid-column-start: 7; grid-row-start: 26;"></div><div class = "" vx = "2" vy = "2" dvx = "0" dvy = "-1" style="grid-column-start: 7; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 29;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "0" style="grid-column-start: 8; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 17;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "0" style="grid-column-start: 6; grid-row-start: 5;"></div><div class = "" vx = "0" vy = "3" dvx = "1" dvy = "0" style="grid-column-start: 5; grid-row-start: 24;"></div><div class = "" vx = "2" vy = "4" dvx = "0" dvy = "0" style="grid-column-start: 10; grid-row-start: 31;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "-1" style="grid-column-start: 8; grid-row-start: 7;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "-1" style="grid-column-start: 4; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 25;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "-1" style="grid-column-start: 6; grid-row-start: 23;"></div><div class = "" vx = "0" vy = "4" dvx = "1" dvy = "0" style="grid-column-start: 9; grid-row-start: 24;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "1" style="grid-column-start: 7; grid-row-start: 10;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "1" style="grid-column-start: 4; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 11;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "0" style="grid-column-start: 5; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 21;"></div><div class = "" vx = "1" vy = "2" dvx = "1" dvy = "1" style="grid-column-start: 7; grid-row-start: 4;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "1" style="grid-column-start: 5; grid-row-start: 17;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "1" style="grid-column-start: 7; grid-row-start: 21;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "1" style="grid-column-start: 6; grid-row-start: 31;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "1" style="grid-column-start: 4; grid-row-start: 7;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "-1" style="grid-column-start: 8; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 28;"></div><div class = "" vx = "1" vy = "3" dvx = "1" dvy = "-1" style="grid-column-start: 9; grid-row-start: 15;"></div><div class = "" vx = "0" vy = "4" dvx = "-1" dvy = "-1" style="grid-column-start: 5; grid-row-start: 25;"></div><div class = "" vx = "1" vy = "4" dvx = "-1" dvy = "0" style="grid-column-start: 9; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 29;"></div><div class = "" vx = "1" vy = "0" dvx = "-1" dvy = "0" style="grid-column-start: 13; grid-row-start: 31;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "0" style="grid-column-start: 7; grid-row-start: 28;"></div><div class = "" vx = "2" vy = "1" dvx = "-1" dvy = "-1" style="grid-column-start: 7; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 12;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "-1" style="grid-column-start: 9; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 27;"></div><div class = "" vx = "1" vy = "1" dvx = "0" dvy = "-1" style="grid-column-start: 12; grid-row-start: 31;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "-1" style="grid-column-start: 4; grid-row-start: 16;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "1" style="grid-column-start: 8; grid-row-start: 18;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 7; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 28;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 28;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 29;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 31;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 30;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 27;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 32;"></div>
	</div>
	Finish <br> line
	</div>
	<div>Starting line</div>
</div>
</div>

<div>
Race finished in 582 steps
<div style="background-color: white; color: black;">
	<div style="display:flex; align-items: flex-start">
	<div class = "track">
		<div class = "start" vx = "0" vy = "0" dvx = "-1" dvy = "1" style="grid-column-start: 8; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "0" dvy = "-1" style="grid-column-start: 5; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "1" dvy = "-1" style="grid-column-start: 14; grid-row-start: 1;"></div><div class = "start" vx = "1" vy = "0" dvx = "0" dvy = "-1" style="grid-column-start: 16; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "-1" dvy = "-1" style="grid-column-start: 3; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "0" dvy = "0" style="grid-column-start: 11; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "1" dvy = "0" style="grid-column-start: 19; grid-row-start: 1;"></div><div class = "start" vx = "1" vy = "0" dvx = "1" dvy = "1" style="grid-column-start: 22; grid-row-start: 1;"></div><div class = "start" vx = "1" vy = "0" dvx = "-1" dvy = "0" style="grid-column-start: 6; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "1" dvy = "-1" style="grid-column-start: 17; grid-row-start: 1;"></div><div class = "start" vx = "1" vy = "0" dvx = "-1" dvy = "1" style="grid-column-start: 21; grid-row-start: 1;"></div><div class = "start" vx = "1" vy = "0" dvx = "1" dvy = "1" style="grid-column-start: 13; grid-row-start: 1;"></div><div class = "start" vx = "1" vy = "0" dvx = "1" dvy = "1" style="grid-column-start: 9; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "1" dvy = "1" style="grid-column-start: 18; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "-1" dvy = "-1" style="grid-column-start: 2; grid-row-start: 1;"></div><div class = "start" vx = "1" vy = "0" dvx = "0" dvy = "0" style="grid-column-start: 20; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "-1" dvy = "-1" style="grid-column-start: 1; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "0" dvy = "1" style="grid-column-start: 23; grid-row-start: 1;"></div><div class = "start" vx = "1" vy = "0" dvx = "0" dvy = "0" style="grid-column-start: 7; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "0" dvy = "0" style="grid-column-start: 12; grid-row-start: 1;"></div><div class = "start" vx = "1" vy = "0" dvx = "-1" dvy = "-1" style="grid-column-start: 10; grid-row-start: 1;"></div><div class = "start" vx = "1" vy = "0" dvx = "0" dvy = "-1" style="grid-column-start: 15; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "1" dvy = "0" style="grid-column-start: 4; grid-row-start: 1;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 29;"></div><div class = "" vx = "1" vy = "0" dvx = "0" dvy = "1" style="grid-column-start: 18; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 17;"></div><div class = "" vx = "1" vy = "1" dvx = "-1" dvy = "-1" style="grid-column-start: 20; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 25;"></div><div class = "" vx = "1" vy = "2" dvx = "-1" dvy = "0" style="grid-column-start: 23; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 19;"></div><div class = "" vx = "1" vy = "0" dvx = "0" dvy = "1" style="grid-column-start: 19; grid-row-start: 9;"></div><div class = "" vx = "2" vy = "2" dvx = "-1" dvy = "0" style="grid-column-start: 27; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 26;"></div><div class = "" vx = "2" vy = "3" dvx = "-1" dvy = "1" style="grid-column-start: 21; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 9;"></div><div class = "" vx = "1" vy = "3" dvx = "1" dvy = "0" style="grid-column-start: 22; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 19;"></div><div class = "" vx = "1" vy = "2" dvx = "-1" dvy = "0" style="grid-column-start: 20; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 22;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "0" style="grid-column-start: 2; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 26;"></div><div class = "" vx = "1" vy = "2" dvx = "0" dvy = "0" style="grid-column-start: 23; grid-row-start: 4;"></div><div class = "" vx = "1" vy = "2" dvx = "1" dvy = "0" style="grid-column-start: 8; grid-row-start: 8;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "0" style="grid-column-start: 18; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 21;"></div><div class = "" vx = "3" vy = "2" dvx = "0" dvy = "-1" style="grid-column-start: 13; grid-row-start: 6;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "1" style="grid-column-start: 22; grid-row-start: 2;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "-1" style="grid-column-start: 4; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 24;"></div><div class = "" vx = "1" vy = "3" dvx = "-1" dvy = "0" style="grid-column-start: 13; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 26;"></div><div class = "" vx = "3" vy = "1" dvx = "0" dvy = "-1" style="grid-column-start: 17; grid-row-start: 8;"></div><div class = "" vx = "0" vy = "4" dvx = "1" dvy = "1" style="grid-column-start: 14; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 27;"></div><div class = "" vx = "2" vy = "3" dvx = "-1" dvy = "0" style="grid-column-start: 20; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 19;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "-1" style="grid-column-start: 18; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 29;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "-1" style="grid-column-start: 23; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 3;"></div><div class = "" vx = "1" vy = "1" dvx = "1" dvy = "-1" style="grid-column-start: 4; grid-row-start: 2;"></div><div class = "" vx = "2" vy = "0" dvx = "0" dvy = "-1" style="grid-column-start: 23; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 25;"></div><div class = "" vx = "0" vy = "4" dvx = "0" dvy = "-1" style="grid-column-start: 23; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 13;"></div><div class = "" vx = "4" vy = "1" dvx = "0" dvy = "1" style="grid-column-start: 22; grid-row-start: 7;"></div><div class = "" vx = "2" vy = "4" dvx = "0" dvy = "0" style="grid-column-start: 26; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 24;"></div><div class = "" vx = "1" vy = "2" dvx = "0" dvy = "0" style="grid-column-start: 28; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 19;"></div><div class = "" vx = "2" vy = "3" dvx = "1" dvy = "-1" style="grid-column-start: 16; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 26;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "-1" style="grid-column-start: 18; grid-row-start: 8;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "1" style="grid-column-start: 6; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 29;"></div><div class = "" vx = "1" vy = "1" dvx = "0" dvy = "1" style="grid-column-start: 21; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 9;"></div><div class = "" vx = "1" vy = "0" dvx = "-1" dvy = "-1" style="grid-column-start: 19; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 14;"></div><div class = "" vx = "0" vy = "4" dvx = "1" dvy = "-1" style="grid-column-start: 23; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 26;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "0" style="grid-column-start: 16; grid-row-start: 8;"></div><div class = "" vx = "1" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 20; grid-row-start: 10;"></div><div class = "" vx = "1" vy = "0" dvx = "1" dvy = "0" style="grid-column-start: 8; grid-row-start: 4;"></div><div class = "" vx = "1" vy = "0" dvx = "-1" dvy = "0" style="grid-column-start: 23; grid-row-start: 6;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "1" style="grid-column-start: 14; grid-row-start: 9;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "-1" style="grid-column-start: 23; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 16;"></div><div class = "" vx = "3" vy = "0" dvx = "0" dvy = "0" style="grid-column-start: 13; grid-row-start: 2;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "-1" style="grid-column-start: 19; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 8;"></div><div class = "" vx = "2" vy = "0" dvx = "1" dvy = "-1" style="grid-column-start: 17; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 15;"></div><div class = "" vx = "0" vy = "3" dvx = "1" dvy = "0" style="grid-column-start: 12; grid-row-start: 9;"></div><div class = "" vx = "3" vy = "0" dvx = "-1" dvy = "0" style="grid-column-start: 20; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 25;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "-1" style="grid-column-start: 21; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 21;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 8; grid-row-start: 3;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "-1" style="grid-column-start: 18; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 29;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 19; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 21;"></div><div class = "" vx = "1" vy = "0" dvx = "-1" dvy = "1" style="grid-column-start: 19; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 20;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "1" style="grid-column-start: 21; grid-row-start: 19;"></div><div class = "" vx = "1" vy = "0" dvx = "0" dvy = "0" style="grid-column-start: 21; grid-row-start: 9;"></div><div class = "" vx = "3" vy = "0" dvx = "1" dvy = "-1" style="grid-column-start: 17; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 28;"></div><div class = "" vx = "2" vy = "1" dvx = "-1" dvy = "1" style="grid-column-start: 17; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 26;"></div><div class = "" vx = "1" vy = "1" dvx = "0" dvy = "-1" style="grid-column-start: 12; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 20;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "1" style="grid-column-start: 20; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 22;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "-1" style="grid-column-start: 20; grid-row-start: 3;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "-1" style="grid-column-start: 18; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 5;"></div><div class = "" vx = "1" vy = "3" dvx = "0" dvy = "-1" style="grid-column-start: 23; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 26;"></div><div class = "" vx = "1" vy = "2" dvx = "0" dvy = "0" style="grid-column-start: 21; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 23;"></div><div class = "" vx = "2" vy = "1" dvx = "-1" dvy = "-1" style="grid-column-start: 8; grid-row-start: 6;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "1" style="grid-column-start: 2; grid-row-start: 2;"></div><div class = "" vx = "2" vy = "0" dvx = "0" dvy = "0" style="grid-column-start: 23; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 22;"></div><div class = "" vx = "1" vy = "1" dvx = "0" dvy = "0" style="grid-column-start: 14; grid-row-start: 10;"></div><div class = "" vx = "1" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 6; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 8;"></div><div class = "" vx = "3" vy = "1" dvx = "-1" dvy = "1" style="grid-column-start: 18; grid-row-start: 11;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "-1" style="grid-column-start: 18; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 9;"></div><div class = "" vx = "2" vy = "0" dvx = "-1" dvy = "-1" style="grid-column-start: 7; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 25;"></div><div class = "" vx = "1" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 17; grid-row-start: 6;"></div><div class = "" vx = "1" vy = "0" dvx = "-1" dvy = "1" style="grid-column-start: 17; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 22;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "1" style="grid-column-start: 20; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 11;"></div><div class = "" vx = "1" vy = "1" dvx = "0" dvy = "0" style="grid-column-start: 20; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 28;"></div><div class = "" vx = "1" vy = "0" dvx = "1" dvy = "0" style="grid-column-start: 6; grid-row-start: 2;"></div><div class = "" vx = "2" vy = "1" dvx = "-1" dvy = "1" style="grid-column-start: 16; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 29;"></div><div class = "" vx = "1" vy = "0" dvx = "1" dvy = "-1" style="grid-column-start: 5; grid-row-start: 4;"></div><div class = "" vx = "4" vy = "0" dvx = "-1" dvy = "1" style="grid-column-start: 14; grid-row-start: 4;"></div><div class = "" vx = "1" vy = "0" dvx = "-1" dvy = "0" style="grid-column-start: 23; grid-row-start: 7;"></div><div class = "" vx = "1" vy = "2" dvx = "1" dvy = "0" style="grid-column-start: 25; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 22;"></div><div class = "" vx = "2" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 7; grid-row-start: 3;"></div><div class = "" vx = "1" vy = "1" dvx = "1" dvy = "1" style="grid-column-start: 12; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 7;"></div><div class = "" vx = "4" vy = "2" dvx = "0" dvy = "-1" style="grid-column-start: 18; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 30;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "1" style="grid-column-start: 8; grid-row-start: 5;"></div><div class = "" vx = "2" vy = "3" dvx = "-1" dvy = "0" style="grid-column-start: 18; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 10;"></div><div class = "" vx = "3" vy = "0" dvx = "0" dvy = "0" style="grid-column-start: 14; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 28;"></div><div class = "" vx = "1" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 5; grid-row-start: 3;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "-1" style="grid-column-start: 14; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 23;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "1" style="grid-column-start: 22; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 4;"></div><div class = "" vx = "1" vy = "0" dvx = "1" dvy = "0" style="grid-column-start: 11; grid-row-start: 4;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "1" style="grid-column-start: 19; grid-row-start: 5;"></div><div class = "" vx = "1" vy = "1" dvx = "0" dvy = "0" style="grid-column-start: 19; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 29;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "0" style="grid-column-start: 21; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 21;"></div><div class = "" vx = "3" vy = "1" dvx = "-1" dvy = "1" style="grid-column-start: 17; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 22;"></div><div class = "" vx = "1" vy = "0" dvx = "1" dvy = "-1" style="grid-column-start: 16; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 11;"></div><div class = "" vx = "1" vy = "1" dvx = "-1" dvy = "-1" style="grid-column-start: 16; grid-row-start: 12;"></div><div class = "" vx = "2" vy = "1" dvx = "0" dvy = "0" style="grid-column-start: 12; grid-row-start: 3;"></div><div class = "" vx = "2" vy = "0" dvx = "0" dvy = "1" style="grid-column-start: 8; grid-row-start: 2;"></div><div class = "" vx = "2" vy = "0" dvx = "1" dvy = "0" style="grid-column-start: 23; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 21;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "-1" style="grid-column-start: 20; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 29;"></div><div class = "" vx = "2" vy = "0" dvx = "-1" dvy = "-1" style="grid-column-start: 10; grid-row-start: 4;"></div><div class = "" vx = "1" vy = "2" dvx = "1" dvy = "-1" style="grid-column-start: 9; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 23;"></div><div class = "" vx = "1" vy = "0" dvx = "1" dvy = "1" style="grid-column-start: 19; grid-row-start: 2;"></div><div class = "" vx = "2" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 7; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 23;"></div><div class = "" vx = "3" vy = "2" dvx = "0" dvy = "1" style="grid-column-start: 27; grid-row-start: 27;"></div><div class = "" vx = "2" vy = "0" dvx = "1" dvy = "1" style="grid-column-start: 15; grid-row-start: 10;"></div><div class = "" vx = "2" vy = "1" dvx = "1" dvy = "-1" style="grid-column-start: 11; grid-row-start: 11;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "-1" style="grid-column-start: 17; grid-row-start: 2;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 3; grid-row-start: 3;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 11; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 23;"></div><div class = "" vx = "1" vy = "2" dvx = "1" dvy = "0" style="grid-column-start: 22; grid-row-start: 15;"></div><div class = "" vx = "1" vy = "3" dvx = "1" dvy = "0" style="grid-column-start: 21; grid-row-start: 11;"></div><div class = "" vx = "1" vy = "0" dvx = "-1" dvy = "-1" style="grid-column-start: 20; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 28;"></div><div class = "" vx = "2" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 21; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 7;"></div><div class = "" vx = "0" vy = "4" dvx = "1" dvy = "-1" style="grid-column-start: 22; grid-row-start: 17;"></div><div class = "" vx = "1" vy = "2" dvx = "-1" dvy = "0" style="grid-column-start: 5; grid-row-start: 6;"></div><div class = "" vx = "2" vy = "2" dvx = "0" dvy = "1" style="grid-column-start: 14; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 23;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "1" style="grid-column-start: 1; grid-row-start: 3;"></div><div class = "" vx = "1" vy = "1" dvx = "0" dvy = "1" style="grid-column-start: 9; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 11;"></div><div class = "" vx = "1" vy = "2" dvx = "1" dvy = "1" style="grid-column-start: 18; grid-row-start: 5;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "1" style="grid-column-start: 18; grid-row-start: 14;"></div><div class = "" vx = "2" vy = "1" dvx = "1" dvy = "-1" style="grid-column-start: 10; grid-row-start: 3;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "0" style="grid-column-start: 19; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 21;"></div><div class = "" vx = "2" vy = "0" dvx = "-1" dvy = "1" style="grid-column-start: 15; grid-row-start: 4;"></div><div class = "" vx = "2" vy = "0" dvx = "-1" dvy = "0" style="grid-column-start: 17; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 19;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 22; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 21;"></div><div class = "" vx = "2" vy = "0" dvx = "0" dvy = "0" style="grid-column-start: 12; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 12;"></div><div class = "" vx = "4" vy = "0" dvx = "0" dvy = "0" style="grid-column-start: 20; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 24;"></div><div class = "" vx = "2" vy = "1" dvx = "-1" dvy = "0" style="grid-column-start: 16; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 14;"></div><div class = "" vx = "1" vy = "0" dvx = "-1" dvy = "-1" style="grid-column-start: 18; grid-row-start: 2;"></div><div class = "" vx = "2" vy = "3" dvx = "-1" dvy = "-1" style="grid-column-start: 24; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 11;"></div><div class = "" vx = "2" vy = "2" dvx = "-1" dvy = "-1" style="grid-column-start: 23; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 12;"></div><div class = "" vx = "1" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 15; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 28;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "1" style="grid-column-start: 15; grid-row-start: 3;"></div><div class = "" vx = "1" vy = "2" dvx = "1" dvy = "-1" style="grid-column-start: 7; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 23;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "0" style="grid-column-start: 21; grid-row-start: 6;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "-1" style="grid-column-start: 21; grid-row-start: 12;"></div><div class = "" vx = "3" vy = "0" dvx = "-1" dvy = "0" style="grid-column-start: 16; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 26;"></div><div class = "" vx = "1" vy = "2" dvx = "-1" dvy = "1" style="grid-column-start: 22; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 30;"></div><div class = "" vx = "1" vy = "0" dvx = "-1" dvy = "1" style="grid-column-start: 18; grid-row-start: 7;"></div><div class = "" vx = "1" vy = "2" dvx = "0" dvy = "-1" style="grid-column-start: 10; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 12;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "1" style="grid-column-start: 5; grid-row-start: 5;"></div><div class = "" vx = "3" vy = "2" dvx = "0" dvy = "0" style="grid-column-start: 14; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 14;"></div><div class = "" vx = "1" vy = "0" dvx = "-1" dvy = "1" style="grid-column-start: 19; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 20;"></div><div class = "" vx = "1" vy = "0" dvx = "-1" dvy = "0" style="grid-column-start: 7; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 22;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "0" style="grid-column-start: 13; grid-row-start: 15;"></div><div class = "" vx = "1" vy = "0" dvx = "1" dvy = "1" style="grid-column-start: 20; grid-row-start: 16;"></div><div class = "" vx = "3" vy = "1" dvx = "1" dvy = "-1" style="grid-column-start: 16; grid-row-start: 7;"></div><div class = "" vx = "1" vy = "2" dvx = "-1" dvy = "0" style="grid-column-start: 12; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 22;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "-1" style="grid-column-start: 5; grid-row-start: 2;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "-1" style="grid-column-start: 14; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 20;"></div><div class = "" vx = "1" vy = "0" dvx = "-1" dvy = "0" style="grid-column-start: 9; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 29;"></div><div class = "" vx = "1" vy = "0" dvx = "0" dvy = "0" style="grid-column-start: 15; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 27;"></div><div class = "" vx = "0" vy = "4" dvx = "-1" dvy = "0" style="grid-column-start: 23; grid-row-start: 24;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 13; grid-row-start: 9;"></div><div class = "" vx = "2" vy = "0" dvx = "-1" dvy = "-1" style="grid-column-start: 12; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 25;"></div><div class = "" vx = "1" vy = "2" dvx = "-1" dvy = "1" style="grid-column-start: 22; grid-row-start: 10;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "0" style="grid-column-start: 21; grid-row-start: 5;"></div><div class = "" vx = "1" vy = "3" dvx = "-1" dvy = "-1" style="grid-column-start: 21; grid-row-start: 14;"></div><div class = "" vx = "2" vy = "3" dvx = "1" dvy = "-1" style="grid-column-start: 24; grid-row-start: 25;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "-1" style="grid-column-start: 18; grid-row-start: 16;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "1" style="grid-column-start: 23; grid-row-start: 13;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "1" style="grid-column-start: 5; grid-row-start: 7;"></div><div class = "" vx = "2" vy = "0" dvx = "1" dvy = "1" style="grid-column-start: 14; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 23;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "0" style="grid-column-start: 3; grid-row-start: 2;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "-1" style="grid-column-start: 11; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 23;"></div><div class = "" vx = "2" vy = "0" dvx = "-1" dvy = "-1" style="grid-column-start: 21; grid-row-start: 2;"></div><div class = "" vx = "2" vy = "0" dvx = "0" dvy = "0" style="grid-column-start: 22; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 16;"></div><div class = "" vx = "2" vy = "0" dvx = "1" dvy = "0" style="grid-column-start: 12; grid-row-start: 7;"></div><div class = "" vx = "1" vy = "0" dvx = "-1" dvy = "-1" style="grid-column-start: 13; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 26;"></div><div class = "" vx = "1" vy = "3" dvx = "-1" dvy = "1" style="grid-column-start: 23; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 26;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "-1" style="grid-column-start: 1; grid-row-start: 2;"></div><div class = "" vx = "1" vy = "2" dvx = "1" dvy = "1" style="grid-column-start: 22; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 27;"></div><div class = "" vx = "2" vy = "0" dvx = "1" dvy = "0" style="grid-column-start: 10; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 27;"></div><div class = "" vx = "1" vy = "1" dvx = "0" dvy = "1" style="grid-column-start: 11; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 15;"></div><div class = "" vx = "1" vy = "1" dvx = "0" dvy = "-1" style="grid-column-start: 4; grid-row-start: 4;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "-1" style="grid-column-start: 15; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 26;"></div><div class = "" vx = "2" vy = "0" dvx = "-1" dvy = "-1" style="grid-column-start: 21; grid-row-start: 7;"></div><div class = "" vx = "0" vy = "3" dvx = "1" dvy = "0" style="grid-column-start: 22; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 24;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "-1" style="grid-column-start: 9; grid-row-start: 2;"></div><div class = "" vx = "3" vy = "1" dvx = "-1" dvy = "-1" style="grid-column-start: 10; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 19;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "1" style="grid-column-start: 23; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 29;"></div><div class = "" vx = "2" vy = "1" dvx = "0" dvy = "0" style="grid-column-start: 15; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 30;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "0" style="grid-column-start: 4; grid-row-start: 3;"></div><div class = "" vx = "1" vy = "1" dvx = "1" dvy = "-1" style="grid-column-start: 13; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 29;"></div><div class = "" vx = "1" vy = "4" dvx = "1" dvy = "-1" style="grid-column-start: 22; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 26;"></div><div class = "" vx = "3" vy = "0" dvx = "-1" dvy = "-1" style="grid-column-start: 15; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 24;"></div><div class = "" vx = "2" vy = "2" dvx = "0" dvy = "1" style="grid-column-start: 23; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 30;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "-1" style="grid-column-start: 17; grid-row-start: 13;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "-1" style="grid-column-start: 21; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 24;"></div><div class = "" vx = "2" vy = "0" dvx = "0" dvy = "-1" style="grid-column-start: 13; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 30;"></div><div class = "" vx = "1" vy = "0" dvx = "1" dvy = "-1" style="grid-column-start: 22; grid-row-start: 6;"></div><div class = "" vx = "3" vy = "3" dvx = "0" dvy = "-1" style="grid-column-start: 22; grid-row-start: 12;"></div><div class = "" vx = "2" vy = "2" dvx = "1" dvy = "-1" style="grid-column-start: 20; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 24;"></div><div class = "" vx = "3" vy = "3" dvx = "0" dvy = "0" style="grid-column-start: 30; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 8;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "0" style="grid-column-start: 4; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 24;"></div><div class = "" vx = "1" vy = "3" dvx = "1" dvy = "0" style="grid-column-start: 19; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 28;"></div><div class = "" vx = "3" vy = "0" dvx = "-1" dvy = "1" style="grid-column-start: 13; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 27;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 30;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 27;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 23;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 28;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 29;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 26;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 25;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 24;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 22;"></div>
	</div>
	Finish <br> line
	</div>
	<div>Starting line</div>
</div>
</div>

</div>
mimetext/htmlrootassigneelast_run_timestampA0m`persist_js_state·has_pluto_hook_features§cell_id$ba044e4f-e2a6-4f96-8756-5b24b1bb5ca2depends_on_disabled_cells§runtimeUpublished_object_keysdepends_on_skipped_cells§errored$6d6e8916-9b36-4af1-b77d-86cb6a416f88queued¤logsrunning¦outputbody-<div class="markdown"><h5>Track 1</h5>
</div>mimetext/htmlrootassigneelast_run_timestampA"+rpersist_js_state·has_pluto_hook_features§cell_id$6d6e8916-9b36-4af1-b77d-86cb6a416f88depends_on_disabled_cells§runtime =published_object_keysdepends_on_skipped_cells§errored$cede8090-5b1a-436b-a184-fca5c4d3de48queued¤logsrunning¦outputbody<div class="markdown"><blockquote>
<h3><em>Exercise 5.5</em></h3>
<p>Consider an MDP with a single nonterminal state and a single action that transitions back to the nonterminal state with probability <span class="tex">$p$</span> and transitions to the terminal state with probability <span class="tex">$1-p$</span>.  Let the reward be &#43;1 on all transitions, and let <span class="tex">$\gamma&#61;1$</span>.  Suppose you observe one episode that lasts 10 steps, with a return of 10.  What are the first-visit and every-visit estimators of the value of the nonterminal state?</p>
</blockquote>
<p>For the first-visit estimator, we only consider the single future reward from the starting state which would be 10.  There is nothing to average since we just have the single value of 10 for the episode.</p>
<p>For the every-visit estimator, we need to average together all 10 visits to the non-terminal state.  For the first visit, the future reward is 10.  For the second visit it is 9, third 8, and so forth.  The final visit has a reward of 1, so the value estimate is the average of 10, 9, ..., 1 which is <span class="tex">$\frac&#123;&#40;1&#43;10&#41; \times 5&#125;&#123;10&#125;&#61;\frac&#123;55&#125;&#123;10&#125; &#61; 5.5$</span></p>
</div>mimetext/htmlrootassigneelast_run_timestampA"(persist_js_state·has_pluto_hook_features§cell_id$cede8090-5b1a-436b-a184-fca5c4d3de48depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$8668ffc3-6c8c-4c25-8d47-9977bef929d2queued¤logsrunning¦outputbody<div class="markdown"><p>Number of Episodes: <bond def="opmc2" unique_id="u06jnj9Gk500"><span style='display: contents;'>
	<input type='number' min='1' step='1' max='10000000' value='1000'>
	<input type=submit id='gitupofvxw'>
	<script id='gitupofvxw'>

let key = "gitupofvxw"

let div = currentScript.parentElement
let button = currentScript.previousElementSibling
let input = div.firstElementChild
if(input === button) {
	return
}


let set_input_value = (() => {
	let result = null
	try {
	result = setBoundElementValueLikePluto
} catch (e) {
	result = ((input, new_value) => {
	// fallback in case https://github.com/fonsp/Pluto.jl/pull/1755 is not available
    if (new_value == null) {
        //@ts-ignore
        input.value = new_value
        return
    }
    if (input instanceof HTMLInputElement) {
        switch (input.type) {
            case "range":
            case "number": {
                if (input.valueAsNumber !== new_value) {
                    input.valueAsNumber = new_value
                }
                return
            }
            case "date": {
                if (input.valueAsDate == null || Number(input.valueAsDate) !== Number(new_value)) {
                    input.valueAsDate = new_value
                }
                return
            }
            case "checkbox": {
                if (input.checked !== new_value) {
                    input.checked = new_value
                }
                return
            }
            case "file": {
                // Can't set files :(
                return
            }
        }
    } else if (input instanceof HTMLSelectElement && input.multiple) {
        for (let option of Array.from(input.options)) {
            option.selected = new_value.includes(option.value)
        }
        return
    }
    //@ts-ignore
    if (input.value !== new_value) {
        //@ts-ignore
        input.value = new_value
    }
})
}
return result
})()



let private_value = null
let public_value = null




private_value = public_value = div.value
if(private_value != null) {
	set_input_value(input, private_value)
} else {

	// private_value = public_value = input.value
}

input.oninput = (e) => {
	e.stopPropagation()
}
const gen = Generators.input(input)

// If the child does not have an initial value, the `gen.next().value` promise will never resolve. If it does, then it resolves instantly.
let first_value = await Promise.any([
	gen.next().value,
	Promise.resolve(undefined)
])
private_value = public_value = first_value

;(async () => {
	while(true) {
		private_value = await gen.next().value
		// div.dispatchEvent(new CustomEvent("input", {}))
	}
})()

button.addEventListener("click", () => {
	public_value = private_value
	div.dispatchEvent(new CustomEvent("input", {}))
})


Object.defineProperty(div, 'value', {
	get: () => public_value,
	set: (newval) => {
		private_value = newval
		public_value = newval
		
		set_input_value(input, newval)
	},
	configurable: true,
});

</script></span></bond></p>
</div>mimetext/htmlrootassigneelast_run_timestampA2j@̰persist_js_state·has_pluto_hook_features§cell_id$8668ffc3-6c8c-4c25-8d47-9977bef929d2depends_on_disabled_cells§runtime Wpublished_object_keysdepends_on_skipped_cells§errored$5834c5e0-8a04-47ea-aab8-881c73d8fd4fqueued¤logsrunning¦outputbody-<div class="markdown"><h5>Track 1</h5>
</div>mimetext/htmlrootassigneelast_run_timestampA"+persist_js_state·has_pluto_hook_features§cell_id$5834c5e0-8a04-47ea-aab8-881c73d8fd4fdepends_on_disabled_cells§runtime ɐpublished_object_keysdepends_on_skipped_cells§errored$14536b70-35f0-46ba-93fc-3365a1e8c15cqueued¤logsrunning¦outputbody"<div class="markdown"><h5>Results Summary</h5>
<p>Off policy MC control training is slow because the random behavior policy takes a very long time to complete a race &#40;~2500 or ~300 steps&#41;.  Even after 1000 episodes performance is indistinguishable from the random policy.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA"*-persist_js_state·has_pluto_hook_features§cell_id$14536b70-35f0-46ba-93fc-3365a1e8c15cdepends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$39da4cf9-5265-41bc-83d4-311e86675db7queued¤logsrunning¦outputbodyelementsٿ2×200 Matrix{Float32}:
 1.0  1.0  1.0  1.0  1.0  1.0  1.0  0.0  …  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  1.0     1.0  1.0  1.0  1.0  1.0  1.0  1.0  1.0text/plainٴ2×200 Matrix{Float32}:
 -0.316785  -0.557123   0.0869449  -0.245725  …  -1.0       0.399294  -1.0
 -0.763317  -0.76558   -0.294025   -0.286185      0.945092  0.889636   0.827852text/plaintypeTupleobjectide5040a83b7785ebemime!application/vnd.pluto.tree+objectrootassigneelast_run_timestampA/뷰persist_js_state·has_pluto_hook_features§cell_id$39da4cf9-5265-41bc-83d4-311e86675db7depends_on_disabled_cells§runtimepgqӵpublished_object_keysdepends_on_skipped_cells§errored$d97f693d-27f2-49be-a549-07a290c95b53queued¤logsrunning¦outputbodymimetext/plainrootassigneelast_run_timestampA)T(persist_js_state·has_pluto_hook_features§cell_id$d97f693d-27f2-49be-a549-07a290c95b53depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$f9bc84ff-c2f9-4ac2-b2ce-34dfcf837a73queued¤logsrunning¦outputbody <div class="markdown"><table><tr><th align="right"></th><th align="center"><span class="tex">$\pi_*$</span> &#40;Black &#61; Stick, White &#61; Hit&#41;</th><th align="center"><span class="tex">$v_*$</span></th></tr><tr><td align="right">Usable ace</td><td align="center">	<script id='plot_1'>
		// We start by putting all the variable interpolation here at the beginning
		// We have to convert all typedarrays in the layout to normal arrays. See Issue #25
		// We use lodash for this for compactness
		function removeTypedArray(o) {
			return _.isTypedArray(o) ? Array.from(o) :
			_.isPlainObject(o) ? _.mapValues(o, removeTypedArray) : 
			o
		}

		// Publish the plot object to JS
		let plot_obj = _.update(/* See the documentation for AbstractPlutoDingetjes.Display.published_to_js */ getPublishedObject("c6e0de0c-3901-11f0-234e-bd09c571f662/7b3f5adc32cbaebf"), "layout", removeTypedArray)
		// Get the plotly listeners
		const plotly_listeners = {}
		// Get the JS listeners
		const js_listeners = {}
		// Deal with eventual custom classes
		let custom_classlist = []


		// Load the plotly library
		let Plotly = undefined
		try {
			let _mod = await import("./plotlyjs/plotlyjs-2.26.2.min.js")
			Plotly = _mod.default
		} catch (e) {
			console.log("Local load failed, trying with the web esm.sh version")
			let _mod = await import("https://esm.sh/plotly.js-dist-min@2.26.2/es2022/plotly.js-dist-min.mjs")
			Plotly = _mod.default
		}

		// Check if we have to force local mathjax font cache
		if (false && window?.MathJax?.config?.svg?.fontCache === 'global') {
			window.MathJax.config.svg.fontCache = 'local'
		}

		// Flag to check if this cell was  manually ran or reactively ran
const firstRun = this ? false : true
const CONTAINER = this ?? html`<div class='plutoplotly-container'>`
const PLOT = CONTAINER.querySelector('.js-plotly-plot') ?? CONTAINER.appendChild(html`<div>`)
const parent = CONTAINER.parentElement
// We use a controller to remove event listeners upon invalidation
const controller = new AbortController()
// We have to add this to keep supporting @bind with the old API using PLOT
PLOT.addEventListener('input', (e) => {
	CONTAINER.value = PLOT.value
	if (e.bubbles) {
		return
	}
	CONTAINER.dispatchEvent(new CustomEvent('input'))
}, { signal: controller.signal })

	// This create the style subdiv on first run
	firstRun && CONTAINER.appendChild(html`
	<style>
	.plutoplotly-container {
		width: 100%;
		height: 100%;
		min-height: 0;
		min-width: 0;
	}
	.plutoplotly-container .js-plotly-plot .plotly div {
		margin: 0 auto; // This centers the plot
	}
	.plutoplotly-container.popped-out {
		overflow: auto;
		z-index: 1000;
		position: fixed;
		resize: both;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		border-top-left-radius: 0px;
		border-top-right-radius: 0px;
	}
	.plutoplotly-clipboard-header {
		display: flex;
		flex-flow: row wrap;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-top-left-radius: 12px;
		border-top-right-radius: 12px;
		position: fixed;
		z-index: 1001;
		cursor: move;
		transform: translate(0px, -100%);
		padding: 5px;
	}
	.plutoplotly-clipboard-header span {
		display: inline-block;
		flex: 1
	}
	.plutoplotly-clipboard-header.hidden {
		display: none;
	}
	.clipboard-span {
		position: relative;
	}
	.clipboard-value {
		padding-right: 5px;
		padding-left: 2px;
		cursor: text;
	}
	.clipboard-span.format {
		display: none;
	}
	.clipboard-span.filename {
		flex: 0 0 100%;
		text-align: center;
		border-top: 3px solid var(--kbd-border-color);
		margin-top: 5px;
		display: none;
	}
	.plutoplotly-container.filesave .clipboard-span.filename {
		display: inline-block;
	}
	.clipboard-value.filename {
		margin-left: 3px;
		text-align: left;
		min-width: min(60%, min-content);
	}
	.plutoplotly-container.filesave .clipboard-span.format {
		display: inline-flex;
	}
	.clipboard-span.format .label {
		flex: 0 0 0;
	}
	.clipboard-value.format {
		position: relative;
		flex: 1 0 auto;
		min-width: 30px;
		margin-right: 10px;
	}
	div.format-options {
		display: inline-flex;
		flex-flow: column;
		position: absolute;
		background: var(--main-bg-color);
		border-radius: 12px;
		padding-left: 3px;
		z-index: 2000;
	}
	div.format-options:hover {
		cursor: pointer;
		border: 3px solid var(--kbd-border-color);
		padding: 3px;
		transform: translate(-3px, -6px);
	}
	div.format-options .format-option {
		display: none;
	}
	div.format-options:hover .format-option {
		display: inline-block;
	}
	.format-option:not(.selected) {
		margin-top: 3px;
	}
	div.format-options .format-option.selected {
		order: -1;
		display: inline-block;
	}
	.format-option:hover {
		background-color: var(--kbd-border-color);
	}
	span.config-value {
		font-weight: normal;
		color: var(--pluto-output-color);
		display: none;
		position: absolute;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		transform: translate(0px, calc(-100% - 10px));
		padding: 5px;
	}
	.label {
		user-select: none;
	}
	.label:hover span.config-value {
		display: inline-block;
		min-width: 150px;
	}
	.clipboard-span.matching-config .label {
		color: var(--cm-macro-color);
		font-weight: bold;
	}
	.clipboard-span.different-config .label {
		color: var(--cm-tag-color);
		font-weight: bold;
	}
</style>
`)

let original_height = plot_obj.layout.height
let original_width = plot_obj.layout.width
// For the height we have to also put a fixed value in case the plot is put on a non-fixed-size container (like the default wrapper)
// We define a variable to check whether we still have to remove the fixed height
let remove_container_size = firstRun
let container_height = original_height ?? PLOT.container_height ?? 400
CONTAINER.style.height = container_height + 'px'

// We create a Promise version of setTimeout
function delay(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

// We import interact for dragging/resizing
const { default: interact } = await import('https://esm.sh/interactjs@1.10.19')


function getImageOptions() {
  const o = plot_obj.config.toImageButtonOptions ?? {};
  return {
    format: o.format ?? "png",
    width: o.width ?? original_width,
    height: o.height ?? original_height,
    scale: o.scale ?? 1,
    filename: o.filename ?? "newplot",
  };
}

const CLIPBOARD_HEADER =
  CONTAINER.querySelector(".plutoplotly-clipboard-header") ??
  CONTAINER.insertAdjacentElement(
    "afterbegin",
    html`<div class="plutoplotly-clipboard-header hidden">
      <span class="clipboard-span format"
        ><span class="label">Format:</span
        ><span class="clipboard-value format"></span
      ></span>
      <span class="clipboard-span width"
        ><span class="label">Width:</span
        ><span class="clipboard-value width"></span>px</span
      >
      <span class="clipboard-span height"
        ><span class="label">Height:</span
        ><span class="clipboard-value height"></span>px</span
      >
      <span class="clipboard-span scale"
        ><span class="label">Scale:</span
        ><span class="clipboard-value scale"></span
      ></span>
      <button class="clipboard-span set">Set</button>
      <button class="clipboard-span unset">Unset</button>
      <span class="clipboard-span filename"
        ><span class="label">Filename:</span
        ><span class="clipboard-value filename"></span
      ></span>
    </div>`
  );

function checkConfigSync(container) {
  const valid_classes = [
    "missing-config",
    "matching-config",
    "different-config",
  ];
  function setClass(cl) {
    for (const name of valid_classes) {
      container.classList.toggle(name, name == cl);
    }
  }
  // We use the custom getters we'll set up in the container
  const { ui_value, config_value, config_span, key } = container;
  if (config_value === undefined) {
    setClass("missing-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> is not present in the config.`;
  } else if (ui_value == config_value) {
    setClass("matching-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has the same value in the config and in the header.`;
  } else {
    setClass("different-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has a different value (<em>${config_value}</em>) in the config.`;
  }
  // Add info about setting and unsetting
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click on the label <em><b>once</b></em> to set the current UI value in the config.`
  );
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click <em><b>twice</b></em> to remove this key from the config.`
  );
}

const valid_formats = ["png", "svg", "webp", "jpeg", "full-json"];
function initializeUIValueSpan(span, key, value) {
  const container = span.closest(".clipboard-span");
  span.contentEditable = key === "format" ? "false" : "true";
  let parse = (x) => x;
  let update = (x) => (span.textContent = x);
  if (key === "width" || key === "height") {
    parse = (x) => Math.round(parseFloat(x));
  } else if (key === "scale") {
    parse = parseFloat;
  } else if (key === "format") {
    // We remove contentEditable
    span.contentEditable = "false";
    // Here we first add the subspans for each option
    const opts_div = span.appendChild(html`<div class="format-options"></div>`);
    for (const fmt of valid_formats) {
      const opt = opts_div.appendChild(
        html`<span class="format-option ${fmt}">${fmt}</span>`
      );
      opt.onclick = (e) => {
        span.value = opt.textContent;
      };
    }
    parse = (x) => {
      return valid_formats.includes(x) ? x : localValue;
    };
    update = (x) => {
      for (const opt of opts_div.children) {
        opt.classList.toggle("selected", opt.textContent === x);
      }
    };
  } else {
    // We only have filename here
  }
  let localValue;
  Object.defineProperty(span, "value", {
    get: () => {
      return localValue;
    },
    set: (val) => {
      if (val !== "") {
        localValue = parse(val);
      }
      update(localValue);
      checkConfigSync(container);
    },
  });
  // We also assign a listener so that the editable is blurred when enter is pressed
  span.onkeydown = (e) => {
    if (e.keyCode === 13) {
      e.preventDefault();
      span.blur();
    }
  };
  span.value = value;
}

function initializeConfigValueSpan(span, key) {
  // Here we mostly want to define the setter and getter
  const container = span.closest(".clipboard-span");
  Object.defineProperty(span, "value", {
    get: () => {
      return plot_obj.config.toImageButtonOptions[key];
    },
    set: (val) => {
      // if undefined is passed, we remove the entry from the options
      if (val === undefined) {
        delete plot_obj.config.toImageButtonOptions[key];
      } else {
        plot_obj.config.toImageButtonOptions[key] = val;
      }
      checkConfigSync(container);
    },
  });
}

const config_spans = {};
for (const [key, value] of Object.entries(getImageOptions())) {
  const container = CLIPBOARD_HEADER.querySelector(`.clipboard-span.${key}`);
  const label = container.querySelector(".label");
  // We give the label a function that on single click will set the current value and with double click will unset it
  label.onclick = DualClick(
    () => {
      container.config_value = container.ui_value;
    },
    (e) => {
      console.log("e", e);
      e.preventDefault();
      container.config_value = undefined;
    }
  );
  const ui_value_span = container.querySelector(".clipboard-value");
  const config_value_span =
    container.querySelector(".config-value") ??
    label.insertAdjacentElement(
      "afterbegin",
      html`<span class="config-value"></span>`
    );
  // Assing the two spans as properties of the containing span
  container.ui_span = ui_value_span;
  container.config_span = config_value_span;
  container.key = key;
  config_spans[key] = container;
  if (firstRun) {
    plot_obj.config.toImageButtonOptions =
      plot_obj.config.toImageButtonOptions ?? {};
    // We do the initialization of the value span
    initializeUIValueSpan(ui_value_span, key, value);
    // Then we initialize the config value
    initializeConfigValueSpan(config_value_span, key);
    // We put some convenience getters/setters
    // ui_value forward
    Object.defineProperty(container, "ui_value", {
      get: () => ui_value_span.value,
      set: (val) => {
        ui_value_span.value = val;
      },
    });
    // config_value forward
    Object.defineProperty(container, "config_value", {
      get: () => config_value_span.value,
      set: (val) => {
        config_value_span.value = val;
      },
    });
  }
}

// These objects will contain the default value

// This code updates the image options in the PLOT config with the provided ones
function setImageOptions(o) {
  for (const [key, container] of Object.entries(config_spans)) {
    container.config_value = o[key];
  }
}
function unsetImageOptions() {
  setImageOptions({});
}

const set_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.set");
const unset_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.unset");
if (firstRun) {
  set_button.onclick = (e) => {
    for (const container of Object.values(config_spans)) {
      container.config_value = container.ui_value;
    }
  };
  unset_button.onclick = unsetImageOptions;
}

// We add a function to check if the clipboard is popped out
CONTAINER.isPoppedOut = () => {
  return CONTAINER.classList.contains("popped-out");
};

CLIPBOARD_HEADER.onmousedown = function (event) {
  if (event.target.matches("span.clipboard-value")) {
    console.log("We don't move!");
    return;
  }
  const start = {
    left: parseFloat(CONTAINER.style.left),
    top: parseFloat(CONTAINER.style.top),
    X: event.pageX,
    Y: event.pageY,
  };
  function moveAt(event, start) {
    const top = event.pageY - start.Y + start.top + "px";
    const left = event.pageX - start.X + start.left + "px";
    CLIPBOARD_HEADER.style.left = left;
    CONTAINER.style.left = left;
    CONTAINER.style.top = top;
  }

  // move our absolutely positioned ball under the pointer
  moveAt(event, start);
  function onMouseMove(event) {
    moveAt(event, start);
  }

  // We use this to remove the mousemove when clicking outside of the container
  const controller = new AbortController();

  // move the container on mousemove
  document.addEventListener("mousemove", onMouseMove, {
    signal: controller.signal,
  });
  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        cleanUp();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );

  function cleanUp() {
    console.log("cleaning up the plot move listener");
    controller.abort();
    CLIPBOARD_HEADER.onmouseup = null;
  }

  // (3) drop the ball, remove unneeded handlers
  CLIPBOARD_HEADER.onmouseup = cleanUp;
};

function sendToClipboard(blob) {
  if (!navigator.clipboard) {
    alert(
      "The Clipboard API does not seem to be available, make sure the Pluto notebook is being used from either localhost or an https source."
    );
  }
  navigator.clipboard
    .write([
      new ClipboardItem({
        // The key is determined dynamically based on the blob's type.
        [blob.type]: blob,
      }),
    ])
    .then(
      function () {
        console.log("Async: Copying to clipboard was successful!");
      },
      function (err) {
        console.error("Async: Could not copy text: ", err);
      }
    );
}

function copyImageToClipboard() {
  // We extract the image options from the provided parameters (if they exist)
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key. We also ignore format because the clipboard only supports png.
    if (val === undefined || key === "format") {
      continue;
    }
    config[key] = val;
  }
  Plotly.toImage(PLOT, config).then(function (dataUrl) {
    fetch(dataUrl)
      .then((res) => res.blob())
      .then((blob) => {
        const paste_receiver = document.querySelector('paste-receiver.plutoplotly')
        if (paste_receiver) {
          paste_receiver.attachImage(dataUrl, CONTAINER)
        }
        sendToClipboard(blob)
      });
  });
}

function saveImageToFile() {
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key.
    if (val === undefined) {
      continue;
    }
    config[key] = val;
  }
  Plotly.downloadImage(PLOT, config);
}

let container_rect = { width: 0, height: 0, top: 0, left: 0 };
function unpop_container(cl) {
  CONTAINER.classList.toggle("popped-out", false);
  CONTAINER.classList.toggle(cl, false);
  // We fix the height back to the value it had before popout, also setting the flag to signal that upon first resize we remove the fixed inline-style
  CONTAINER.style.height = container_rect.height + "px";
  remove_container_size = true;
  // We set the other fixed inline-styles to null
  CONTAINER.style.width = "";
  CONTAINER.style.top = "";
  CONTAINER.style.left = "";
  // We also remove the CLIPBOARD_HEADER
  CLIPBOARD_HEADER.style.width = "";
  CLIPBOARD_HEADER.style.left = "";
  // Finally we remove the hidden class to the header
  CLIPBOARD_HEADER.classList.toggle("hidden", true);
  return;
}
function popout_container(opts) {
  const cl = opts?.cl;
  const target_container_size = opts?.target_container_size ?? {};
  const target_plot_size = opts?.target_plot_size ?? {};
  if (CONTAINER.isPoppedOut()) {
    return unpop_container(cl);
  }
  CONTAINER.classList.toggle(cl, cl === undefined ? false : true);
  // We extract the current size of the container, save them and fix them
  const { width, height, top, left } = CONTAINER.getBoundingClientRect();
  container_rect = { width, height, top, left };
  // We save the current plot size before we pop as it will fill the screen
  const current_plot_size = {
    width: PLOT._fullLayout.width,
    height: PLOT._fullLayout.height,
  };
  // We have to save the pad data before popping so we can resize precisely
  const pad = {};
  pad.unpopped = getSizeData().container_pad;
  CONTAINER.classList.toggle("popped-out", true);
  pad.popped = getSizeData().container_pad;
  // We do top and left based on the current rect
  for (const key of ["top", "left"]) {
    const start_val = target_container_size[key] ?? container_rect[key];
    let offset = 0;
    for (const kind of ["padding", "border"]) {
      offset += pad.popped[kind][key] - pad.unpopped[kind][key];
    }
    CONTAINER.style[key] = start_val - offset + "px";
    if (key === "left") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  // We compute the width and height depending on eventual config data
  const csz = computeContainerSize({
    width:
      target_plot_size.width ??
      config_spans.width.config_value ??
      current_plot_size.width,
    height:
      target_plot_size.height ??
      config_spans.height.config_value ??
      current_plot_size.height,
  });
  for (const key of ["width", "height"]) {
    const val = target_container_size[key] ?? csz[key];
    CONTAINER.style[key] = val + "px";
    if (key === "width") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  CLIPBOARD_HEADER.classList.toggle("hidden", false);
  const controller = new AbortController();

  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        unpop_container();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );
}

CONTAINER.popOut = popout_container;

function DualClick(single_func, dbl_func) {
  let nclicks = 0;
  return function (...args) {
    nclicks += 1;
    if (nclicks > 1) {
      dbl_func(...args);
      nclicks = 0;
    } else {
      delay(300).then(() => {
        if (nclicks == 1) {
          single_func(...args);
        }
        nclicks = 0;
      });
    }
  };
}

// We remove the default download image button
plot_obj.config.modeBarButtonsToRemove = _.union(
  plot_obj.config.modeBarButtonsToRemove,
  ["toImage"]
);
// We add the custom button to the modebar
plot_obj.config.modeBarButtonsToAdd = _.union(
  plot_obj.config.modeBarButtonsToAdd,
  [
    {
      name: "Copy PNG to Clipboard",
      icon: {
        height: 520,
        width: 520,
        path: "M280 64h40c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128C0 92.7 28.7 64 64 64h40 9.6C121 27.5 153.3 0 192 0s71 27.5 78.4 64H280zM64 112c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16H320c8.8 0 16-7.2 16-16V128c0-8.8-7.2-16-16-16H304v24c0 13.3-10.7 24-24 24H192 104c-13.3 0-24-10.7-24-24V112H64zm128-8a24 24 0 1 0 0-48 24 24 0 1 0 0 48z",
      },
      direction: "up",
      click: DualClick(copyImageToClipboard, () => {
        popout_container();
      }),
    },
    {
      name: "Download Image",
      icon: Plotly.Icons.camera,
      direction: "up",
      click: DualClick(saveImageToFile, () => {
        popout_container({ cl: "filesave" });
      }),
    },
  ]
);

function getOffsetData(el) {
  let cs = window.getComputedStyle(el, null);
  const odata = {
    padding: {
      left: parseFloat(cs.paddingLeft),
      right: parseFloat(cs.paddingRight),
      top: parseFloat(cs.paddingTop),
      bottom: parseFloat(cs.paddingBottom),
      width: parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight),
      height: parseFloat(cs.paddingTop) + parseFloat(cs.paddingBottom),
    },
    border: {
      left: parseFloat(cs.borderLeftWidth),
      right: parseFloat(cs.borderRightWidth),
      top: parseFloat(cs.borderTopWidth),
      bottom: parseFloat(cs.borderBottomWidth),
      width: parseFloat(cs.borderLeftWidth) + parseFloat(cs.borderRightWidth),
      height: parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth),
    }
  };
  if (el === PLOT) {
    // For the PLOT we also want to take into account the offset
    odata.offset = {
      top: PLOT.offsetParent == CONTAINER ? PLOT.offsetTop : 0,
      left: PLOT.offsetParent == CONTAINER ? PLOT.offsetLeft : 0,
    }
  }
  return odata;
}
function getSizeData() {
  const data = {
    plot_pad: getOffsetData(PLOT),
    plot_rect: PLOT.getBoundingClientRect(),
    container_pad: getOffsetData(CONTAINER),
    container_rect: CONTAINER.getBoundingClientRect(),
  };
  return data;
}
function computeContainerSize({ width, height }, sizeData = getSizeData()) {
  const computed_size = computePlotSize(sizeData);
  const offsets = computed_size.offsets;

  const plot_data = {
    width: width ?? computed_size.width,
    height: height ?? computed_size.height,
  };

  return {
    width: (width ?? computed_size.width) + offsets.width,
    height: (height ?? computed_size.height) + offsets.height,
    noChange: width == computed_size.width && height == computed_size.height,
  }
}

// This function will change the container size so that the resulting plot will be matching the provided specs
function changeContainerSize({ width, height }, sizeData = getSizeData()) {
  if (!CONTAINER.isPoppedOut()) {
    console.log("Tried to change container size when not popped, ignoring");
    return;
  }

  const csz = computeContainerSize({ width, height }, sizeData);

  if (csz.noChange) {
    console.log("Size is the same as current, ignoring");
    return
  }
  // We are now going to set he width and height of the container
  for (const key of ["width", "height"]) {
    CONTAINER.style[key] = csz[key] + "px";
  }
}
// We now create the function that will update the plot based on the values specified
function updateFromHeader() {
  const header_data = {
    height: config_spans.height.ui_value,
    width: config_spans.width.ui_value,
  };
  changeContainerSize(header_data);
}
// We assign this function to the onblur event of width and height
if (firstRun) {
  for (const container of Object.values(config_spans)) {
    container.ui_span.onblur = (e) => {
      container.ui_value = container.ui_span.textContent;
      updateFromHeader();
    };
  }
}
// This function computes the plot size to use for relayout as a function of the container size
function computePlotSize(data = getSizeData()) {
  // Remove Padding
  const { container_pad, plot_pad, container_rect } = data;
  const offsets = {
    width:
      plot_pad.padding.width +
      plot_pad.border.width +
      plot_pad.offset.left +
      container_pad.padding.width +
      container_pad.border.width,
    height:
      plot_pad.padding.height +
      plot_pad.border.height +
      plot_pad.offset.top +
      container_pad.padding.height +
      container_pad.border.height,
  };
  const sz = {
    width: Math.round(container_rect.width - offsets.width),
    height: Math.round(container_rect.height - offsets.height),
    offsets,
  };
  return sz;
}

// Create the resizeObserver to make the plot even more responsive! :magic:
const resizeObserver = new ResizeObserver((entries) => {
  const sizeData = getSizeData();
  const {container_rect, container_pad} = sizeData;
  let plot_size = computePlotSize(sizeData);
  // We save the height in the PLOT object
  PLOT.container_height = container_rect.height;
  // We deal with some stuff if the container is poppped
  CLIPBOARD_HEADER.style.width = container_rect.width + "px";
  CLIPBOARD_HEADER.style.left = container_rect.left + "px";
  config_spans.height.ui_value = plot_size.height;
  config_spans.width.ui_value = plot_size.width;
  /* 
		The addition of the invalid argument `plutoresize` seems to fix the problem with calling `relayout` simply with `{autosize: true}` as update breaking mouse relayout events tracking. 
		See https://github.com/plotly/plotly.js/issues/6156 for details
		*/
  let config = {
    // If this is popped out, we ignore the original width/height
    width: (CONTAINER.isPoppedOut() ? undefined : original_width) ?? plot_size.width,
    height: (CONTAINER.isPoppedOut() ? undefined : original_height) ?? plot_size.height,
    plutoresize: true,
  };
  Plotly.relayout(PLOT, config).then(() => {
    if (remove_container_size && !CONTAINER.isPoppedOut()) {
      // This is needed to avoid the first resize upon plot creation to already be without a fixed height
      CONTAINER.style.height = "";
      CONTAINER.style.width = "";
      remove_container_size = false;
    }
  });
});

resizeObserver.observe(CONTAINER);


Plotly.react(PLOT, plot_obj).then(() => {
	// Assign the Plotly event listeners
	for (const [key, listener_vec] of Object.entries(plotly_listeners)) {
		for (const listener of listener_vec) {
			PLOT.on(key, listener)
		}
	}
	// Assign the JS event listeners
	for (const [key, listener_vec] of Object.entries(js_listeners)) {
		for (const listener of listener_vec) {
			PLOT.addEventListener(key, listener, {
				signal: controller.signal
			})
		}
	}
}
)


invalidation.then(() => {
	// Remove all plotly listeners
	PLOT.removeAllListeners()
	// Remove all JS listeners
	controller.abort()
	// Remove the resizeObserver
	resizeObserver.disconnect()
})



		return CONTAINER
	</script>
</td><td align="center">	<script id='plot_2'>
		// We start by putting all the variable interpolation here at the beginning
		// We have to convert all typedarrays in the layout to normal arrays. See Issue #25
		// We use lodash for this for compactness
		function removeTypedArray(o) {
			return _.isTypedArray(o) ? Array.from(o) :
			_.isPlainObject(o) ? _.mapValues(o, removeTypedArray) : 
			o
		}

		// Publish the plot object to JS
		let plot_obj = _.update(/* See the documentation for AbstractPlutoDingetjes.Display.published_to_js */ getPublishedObject("c6e0de0c-3901-11f0-234e-bd09c571f662/acf9294267fab534"), "layout", removeTypedArray)
		// Get the plotly listeners
		const plotly_listeners = {}
		// Get the JS listeners
		const js_listeners = {}
		// Deal with eventual custom classes
		let custom_classlist = []


		// Load the plotly library
		let Plotly = undefined
		try {
			let _mod = await import("./plotlyjs/plotlyjs-2.26.2.min.js")
			Plotly = _mod.default
		} catch (e) {
			console.log("Local load failed, trying with the web esm.sh version")
			let _mod = await import("https://esm.sh/plotly.js-dist-min@2.26.2/es2022/plotly.js-dist-min.mjs")
			Plotly = _mod.default
		}

		// Check if we have to force local mathjax font cache
		if (false && window?.MathJax?.config?.svg?.fontCache === 'global') {
			window.MathJax.config.svg.fontCache = 'local'
		}

		// Flag to check if this cell was  manually ran or reactively ran
const firstRun = this ? false : true
const CONTAINER = this ?? html`<div class='plutoplotly-container'>`
const PLOT = CONTAINER.querySelector('.js-plotly-plot') ?? CONTAINER.appendChild(html`<div>`)
const parent = CONTAINER.parentElement
// We use a controller to remove event listeners upon invalidation
const controller = new AbortController()
// We have to add this to keep supporting @bind with the old API using PLOT
PLOT.addEventListener('input', (e) => {
	CONTAINER.value = PLOT.value
	if (e.bubbles) {
		return
	}
	CONTAINER.dispatchEvent(new CustomEvent('input'))
}, { signal: controller.signal })

	// This create the style subdiv on first run
	firstRun && CONTAINER.appendChild(html`
	<style>
	.plutoplotly-container {
		width: 100%;
		height: 100%;
		min-height: 0;
		min-width: 0;
	}
	.plutoplotly-container .js-plotly-plot .plotly div {
		margin: 0 auto; // This centers the plot
	}
	.plutoplotly-container.popped-out {
		overflow: auto;
		z-index: 1000;
		position: fixed;
		resize: both;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		border-top-left-radius: 0px;
		border-top-right-radius: 0px;
	}
	.plutoplotly-clipboard-header {
		display: flex;
		flex-flow: row wrap;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-top-left-radius: 12px;
		border-top-right-radius: 12px;
		position: fixed;
		z-index: 1001;
		cursor: move;
		transform: translate(0px, -100%);
		padding: 5px;
	}
	.plutoplotly-clipboard-header span {
		display: inline-block;
		flex: 1
	}
	.plutoplotly-clipboard-header.hidden {
		display: none;
	}
	.clipboard-span {
		position: relative;
	}
	.clipboard-value {
		padding-right: 5px;
		padding-left: 2px;
		cursor: text;
	}
	.clipboard-span.format {
		display: none;
	}
	.clipboard-span.filename {
		flex: 0 0 100%;
		text-align: center;
		border-top: 3px solid var(--kbd-border-color);
		margin-top: 5px;
		display: none;
	}
	.plutoplotly-container.filesave .clipboard-span.filename {
		display: inline-block;
	}
	.clipboard-value.filename {
		margin-left: 3px;
		text-align: left;
		min-width: min(60%, min-content);
	}
	.plutoplotly-container.filesave .clipboard-span.format {
		display: inline-flex;
	}
	.clipboard-span.format .label {
		flex: 0 0 0;
	}
	.clipboard-value.format {
		position: relative;
		flex: 1 0 auto;
		min-width: 30px;
		margin-right: 10px;
	}
	div.format-options {
		display: inline-flex;
		flex-flow: column;
		position: absolute;
		background: var(--main-bg-color);
		border-radius: 12px;
		padding-left: 3px;
		z-index: 2000;
	}
	div.format-options:hover {
		cursor: pointer;
		border: 3px solid var(--kbd-border-color);
		padding: 3px;
		transform: translate(-3px, -6px);
	}
	div.format-options .format-option {
		display: none;
	}
	div.format-options:hover .format-option {
		display: inline-block;
	}
	.format-option:not(.selected) {
		margin-top: 3px;
	}
	div.format-options .format-option.selected {
		order: -1;
		display: inline-block;
	}
	.format-option:hover {
		background-color: var(--kbd-border-color);
	}
	span.config-value {
		font-weight: normal;
		color: var(--pluto-output-color);
		display: none;
		position: absolute;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		transform: translate(0px, calc(-100% - 10px));
		padding: 5px;
	}
	.label {
		user-select: none;
	}
	.label:hover span.config-value {
		display: inline-block;
		min-width: 150px;
	}
	.clipboard-span.matching-config .label {
		color: var(--cm-macro-color);
		font-weight: bold;
	}
	.clipboard-span.different-config .label {
		color: var(--cm-tag-color);
		font-weight: bold;
	}
</style>
`)

let original_height = plot_obj.layout.height
let original_width = plot_obj.layout.width
// For the height we have to also put a fixed value in case the plot is put on a non-fixed-size container (like the default wrapper)
// We define a variable to check whether we still have to remove the fixed height
let remove_container_size = firstRun
let container_height = original_height ?? PLOT.container_height ?? 400
CONTAINER.style.height = container_height + 'px'

// We create a Promise version of setTimeout
function delay(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

// We import interact for dragging/resizing
const { default: interact } = await import('https://esm.sh/interactjs@1.10.19')


function getImageOptions() {
  const o = plot_obj.config.toImageButtonOptions ?? {};
  return {
    format: o.format ?? "png",
    width: o.width ?? original_width,
    height: o.height ?? original_height,
    scale: o.scale ?? 1,
    filename: o.filename ?? "newplot",
  };
}

const CLIPBOARD_HEADER =
  CONTAINER.querySelector(".plutoplotly-clipboard-header") ??
  CONTAINER.insertAdjacentElement(
    "afterbegin",
    html`<div class="plutoplotly-clipboard-header hidden">
      <span class="clipboard-span format"
        ><span class="label">Format:</span
        ><span class="clipboard-value format"></span
      ></span>
      <span class="clipboard-span width"
        ><span class="label">Width:</span
        ><span class="clipboard-value width"></span>px</span
      >
      <span class="clipboard-span height"
        ><span class="label">Height:</span
        ><span class="clipboard-value height"></span>px</span
      >
      <span class="clipboard-span scale"
        ><span class="label">Scale:</span
        ><span class="clipboard-value scale"></span
      ></span>
      <button class="clipboard-span set">Set</button>
      <button class="clipboard-span unset">Unset</button>
      <span class="clipboard-span filename"
        ><span class="label">Filename:</span
        ><span class="clipboard-value filename"></span
      ></span>
    </div>`
  );

function checkConfigSync(container) {
  const valid_classes = [
    "missing-config",
    "matching-config",
    "different-config",
  ];
  function setClass(cl) {
    for (const name of valid_classes) {
      container.classList.toggle(name, name == cl);
    }
  }
  // We use the custom getters we'll set up in the container
  const { ui_value, config_value, config_span, key } = container;
  if (config_value === undefined) {
    setClass("missing-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> is not present in the config.`;
  } else if (ui_value == config_value) {
    setClass("matching-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has the same value in the config and in the header.`;
  } else {
    setClass("different-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has a different value (<em>${config_value}</em>) in the config.`;
  }
  // Add info about setting and unsetting
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click on the label <em><b>once</b></em> to set the current UI value in the config.`
  );
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click <em><b>twice</b></em> to remove this key from the config.`
  );
}

const valid_formats = ["png", "svg", "webp", "jpeg", "full-json"];
function initializeUIValueSpan(span, key, value) {
  const container = span.closest(".clipboard-span");
  span.contentEditable = key === "format" ? "false" : "true";
  let parse = (x) => x;
  let update = (x) => (span.textContent = x);
  if (key === "width" || key === "height") {
    parse = (x) => Math.round(parseFloat(x));
  } else if (key === "scale") {
    parse = parseFloat;
  } else if (key === "format") {
    // We remove contentEditable
    span.contentEditable = "false";
    // Here we first add the subspans for each option
    const opts_div = span.appendChild(html`<div class="format-options"></div>`);
    for (const fmt of valid_formats) {
      const opt = opts_div.appendChild(
        html`<span class="format-option ${fmt}">${fmt}</span>`
      );
      opt.onclick = (e) => {
        span.value = opt.textContent;
      };
    }
    parse = (x) => {
      return valid_formats.includes(x) ? x : localValue;
    };
    update = (x) => {
      for (const opt of opts_div.children) {
        opt.classList.toggle("selected", opt.textContent === x);
      }
    };
  } else {
    // We only have filename here
  }
  let localValue;
  Object.defineProperty(span, "value", {
    get: () => {
      return localValue;
    },
    set: (val) => {
      if (val !== "") {
        localValue = parse(val);
      }
      update(localValue);
      checkConfigSync(container);
    },
  });
  // We also assign a listener so that the editable is blurred when enter is pressed
  span.onkeydown = (e) => {
    if (e.keyCode === 13) {
      e.preventDefault();
      span.blur();
    }
  };
  span.value = value;
}

function initializeConfigValueSpan(span, key) {
  // Here we mostly want to define the setter and getter
  const container = span.closest(".clipboard-span");
  Object.defineProperty(span, "value", {
    get: () => {
      return plot_obj.config.toImageButtonOptions[key];
    },
    set: (val) => {
      // if undefined is passed, we remove the entry from the options
      if (val === undefined) {
        delete plot_obj.config.toImageButtonOptions[key];
      } else {
        plot_obj.config.toImageButtonOptions[key] = val;
      }
      checkConfigSync(container);
    },
  });
}

const config_spans = {};
for (const [key, value] of Object.entries(getImageOptions())) {
  const container = CLIPBOARD_HEADER.querySelector(`.clipboard-span.${key}`);
  const label = container.querySelector(".label");
  // We give the label a function that on single click will set the current value and with double click will unset it
  label.onclick = DualClick(
    () => {
      container.config_value = container.ui_value;
    },
    (e) => {
      console.log("e", e);
      e.preventDefault();
      container.config_value = undefined;
    }
  );
  const ui_value_span = container.querySelector(".clipboard-value");
  const config_value_span =
    container.querySelector(".config-value") ??
    label.insertAdjacentElement(
      "afterbegin",
      html`<span class="config-value"></span>`
    );
  // Assing the two spans as properties of the containing span
  container.ui_span = ui_value_span;
  container.config_span = config_value_span;
  container.key = key;
  config_spans[key] = container;
  if (firstRun) {
    plot_obj.config.toImageButtonOptions =
      plot_obj.config.toImageButtonOptions ?? {};
    // We do the initialization of the value span
    initializeUIValueSpan(ui_value_span, key, value);
    // Then we initialize the config value
    initializeConfigValueSpan(config_value_span, key);
    // We put some convenience getters/setters
    // ui_value forward
    Object.defineProperty(container, "ui_value", {
      get: () => ui_value_span.value,
      set: (val) => {
        ui_value_span.value = val;
      },
    });
    // config_value forward
    Object.defineProperty(container, "config_value", {
      get: () => config_value_span.value,
      set: (val) => {
        config_value_span.value = val;
      },
    });
  }
}

// These objects will contain the default value

// This code updates the image options in the PLOT config with the provided ones
function setImageOptions(o) {
  for (const [key, container] of Object.entries(config_spans)) {
    container.config_value = o[key];
  }
}
function unsetImageOptions() {
  setImageOptions({});
}

const set_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.set");
const unset_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.unset");
if (firstRun) {
  set_button.onclick = (e) => {
    for (const container of Object.values(config_spans)) {
      container.config_value = container.ui_value;
    }
  };
  unset_button.onclick = unsetImageOptions;
}

// We add a function to check if the clipboard is popped out
CONTAINER.isPoppedOut = () => {
  return CONTAINER.classList.contains("popped-out");
};

CLIPBOARD_HEADER.onmousedown = function (event) {
  if (event.target.matches("span.clipboard-value")) {
    console.log("We don't move!");
    return;
  }
  const start = {
    left: parseFloat(CONTAINER.style.left),
    top: parseFloat(CONTAINER.style.top),
    X: event.pageX,
    Y: event.pageY,
  };
  function moveAt(event, start) {
    const top = event.pageY - start.Y + start.top + "px";
    const left = event.pageX - start.X + start.left + "px";
    CLIPBOARD_HEADER.style.left = left;
    CONTAINER.style.left = left;
    CONTAINER.style.top = top;
  }

  // move our absolutely positioned ball under the pointer
  moveAt(event, start);
  function onMouseMove(event) {
    moveAt(event, start);
  }

  // We use this to remove the mousemove when clicking outside of the container
  const controller = new AbortController();

  // move the container on mousemove
  document.addEventListener("mousemove", onMouseMove, {
    signal: controller.signal,
  });
  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        cleanUp();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );

  function cleanUp() {
    console.log("cleaning up the plot move listener");
    controller.abort();
    CLIPBOARD_HEADER.onmouseup = null;
  }

  // (3) drop the ball, remove unneeded handlers
  CLIPBOARD_HEADER.onmouseup = cleanUp;
};

function sendToClipboard(blob) {
  if (!navigator.clipboard) {
    alert(
      "The Clipboard API does not seem to be available, make sure the Pluto notebook is being used from either localhost or an https source."
    );
  }
  navigator.clipboard
    .write([
      new ClipboardItem({
        // The key is determined dynamically based on the blob's type.
        [blob.type]: blob,
      }),
    ])
    .then(
      function () {
        console.log("Async: Copying to clipboard was successful!");
      },
      function (err) {
        console.error("Async: Could not copy text: ", err);
      }
    );
}

function copyImageToClipboard() {
  // We extract the image options from the provided parameters (if they exist)
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key. We also ignore format because the clipboard only supports png.
    if (val === undefined || key === "format") {
      continue;
    }
    config[key] = val;
  }
  Plotly.toImage(PLOT, config).then(function (dataUrl) {
    fetch(dataUrl)
      .then((res) => res.blob())
      .then((blob) => {
        const paste_receiver = document.querySelector('paste-receiver.plutoplotly')
        if (paste_receiver) {
          paste_receiver.attachImage(dataUrl, CONTAINER)
        }
        sendToClipboard(blob)
      });
  });
}

function saveImageToFile() {
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key.
    if (val === undefined) {
      continue;
    }
    config[key] = val;
  }
  Plotly.downloadImage(PLOT, config);
}

let container_rect = { width: 0, height: 0, top: 0, left: 0 };
function unpop_container(cl) {
  CONTAINER.classList.toggle("popped-out", false);
  CONTAINER.classList.toggle(cl, false);
  // We fix the height back to the value it had before popout, also setting the flag to signal that upon first resize we remove the fixed inline-style
  CONTAINER.style.height = container_rect.height + "px";
  remove_container_size = true;
  // We set the other fixed inline-styles to null
  CONTAINER.style.width = "";
  CONTAINER.style.top = "";
  CONTAINER.style.left = "";
  // We also remove the CLIPBOARD_HEADER
  CLIPBOARD_HEADER.style.width = "";
  CLIPBOARD_HEADER.style.left = "";
  // Finally we remove the hidden class to the header
  CLIPBOARD_HEADER.classList.toggle("hidden", true);
  return;
}
function popout_container(opts) {
  const cl = opts?.cl;
  const target_container_size = opts?.target_container_size ?? {};
  const target_plot_size = opts?.target_plot_size ?? {};
  if (CONTAINER.isPoppedOut()) {
    return unpop_container(cl);
  }
  CONTAINER.classList.toggle(cl, cl === undefined ? false : true);
  // We extract the current size of the container, save them and fix them
  const { width, height, top, left } = CONTAINER.getBoundingClientRect();
  container_rect = { width, height, top, left };
  // We save the current plot size before we pop as it will fill the screen
  const current_plot_size = {
    width: PLOT._fullLayout.width,
    height: PLOT._fullLayout.height,
  };
  // We have to save the pad data before popping so we can resize precisely
  const pad = {};
  pad.unpopped = getSizeData().container_pad;
  CONTAINER.classList.toggle("popped-out", true);
  pad.popped = getSizeData().container_pad;
  // We do top and left based on the current rect
  for (const key of ["top", "left"]) {
    const start_val = target_container_size[key] ?? container_rect[key];
    let offset = 0;
    for (const kind of ["padding", "border"]) {
      offset += pad.popped[kind][key] - pad.unpopped[kind][key];
    }
    CONTAINER.style[key] = start_val - offset + "px";
    if (key === "left") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  // We compute the width and height depending on eventual config data
  const csz = computeContainerSize({
    width:
      target_plot_size.width ??
      config_spans.width.config_value ??
      current_plot_size.width,
    height:
      target_plot_size.height ??
      config_spans.height.config_value ??
      current_plot_size.height,
  });
  for (const key of ["width", "height"]) {
    const val = target_container_size[key] ?? csz[key];
    CONTAINER.style[key] = val + "px";
    if (key === "width") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  CLIPBOARD_HEADER.classList.toggle("hidden", false);
  const controller = new AbortController();

  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        unpop_container();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );
}

CONTAINER.popOut = popout_container;

function DualClick(single_func, dbl_func) {
  let nclicks = 0;
  return function (...args) {
    nclicks += 1;
    if (nclicks > 1) {
      dbl_func(...args);
      nclicks = 0;
    } else {
      delay(300).then(() => {
        if (nclicks == 1) {
          single_func(...args);
        }
        nclicks = 0;
      });
    }
  };
}

// We remove the default download image button
plot_obj.config.modeBarButtonsToRemove = _.union(
  plot_obj.config.modeBarButtonsToRemove,
  ["toImage"]
);
// We add the custom button to the modebar
plot_obj.config.modeBarButtonsToAdd = _.union(
  plot_obj.config.modeBarButtonsToAdd,
  [
    {
      name: "Copy PNG to Clipboard",
      icon: {
        height: 520,
        width: 520,
        path: "M280 64h40c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128C0 92.7 28.7 64 64 64h40 9.6C121 27.5 153.3 0 192 0s71 27.5 78.4 64H280zM64 112c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16H320c8.8 0 16-7.2 16-16V128c0-8.8-7.2-16-16-16H304v24c0 13.3-10.7 24-24 24H192 104c-13.3 0-24-10.7-24-24V112H64zm128-8a24 24 0 1 0 0-48 24 24 0 1 0 0 48z",
      },
      direction: "up",
      click: DualClick(copyImageToClipboard, () => {
        popout_container();
      }),
    },
    {
      name: "Download Image",
      icon: Plotly.Icons.camera,
      direction: "up",
      click: DualClick(saveImageToFile, () => {
        popout_container({ cl: "filesave" });
      }),
    },
  ]
);

function getOffsetData(el) {
  let cs = window.getComputedStyle(el, null);
  const odata = {
    padding: {
      left: parseFloat(cs.paddingLeft),
      right: parseFloat(cs.paddingRight),
      top: parseFloat(cs.paddingTop),
      bottom: parseFloat(cs.paddingBottom),
      width: parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight),
      height: parseFloat(cs.paddingTop) + parseFloat(cs.paddingBottom),
    },
    border: {
      left: parseFloat(cs.borderLeftWidth),
      right: parseFloat(cs.borderRightWidth),
      top: parseFloat(cs.borderTopWidth),
      bottom: parseFloat(cs.borderBottomWidth),
      width: parseFloat(cs.borderLeftWidth) + parseFloat(cs.borderRightWidth),
      height: parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth),
    }
  };
  if (el === PLOT) {
    // For the PLOT we also want to take into account the offset
    odata.offset = {
      top: PLOT.offsetParent == CONTAINER ? PLOT.offsetTop : 0,
      left: PLOT.offsetParent == CONTAINER ? PLOT.offsetLeft : 0,
    }
  }
  return odata;
}
function getSizeData() {
  const data = {
    plot_pad: getOffsetData(PLOT),
    plot_rect: PLOT.getBoundingClientRect(),
    container_pad: getOffsetData(CONTAINER),
    container_rect: CONTAINER.getBoundingClientRect(),
  };
  return data;
}
function computeContainerSize({ width, height }, sizeData = getSizeData()) {
  const computed_size = computePlotSize(sizeData);
  const offsets = computed_size.offsets;

  const plot_data = {
    width: width ?? computed_size.width,
    height: height ?? computed_size.height,
  };

  return {
    width: (width ?? computed_size.width) + offsets.width,
    height: (height ?? computed_size.height) + offsets.height,
    noChange: width == computed_size.width && height == computed_size.height,
  }
}

// This function will change the container size so that the resulting plot will be matching the provided specs
function changeContainerSize({ width, height }, sizeData = getSizeData()) {
  if (!CONTAINER.isPoppedOut()) {
    console.log("Tried to change container size when not popped, ignoring");
    return;
  }

  const csz = computeContainerSize({ width, height }, sizeData);

  if (csz.noChange) {
    console.log("Size is the same as current, ignoring");
    return
  }
  // We are now going to set he width and height of the container
  for (const key of ["width", "height"]) {
    CONTAINER.style[key] = csz[key] + "px";
  }
}
// We now create the function that will update the plot based on the values specified
function updateFromHeader() {
  const header_data = {
    height: config_spans.height.ui_value,
    width: config_spans.width.ui_value,
  };
  changeContainerSize(header_data);
}
// We assign this function to the onblur event of width and height
if (firstRun) {
  for (const container of Object.values(config_spans)) {
    container.ui_span.onblur = (e) => {
      container.ui_value = container.ui_span.textContent;
      updateFromHeader();
    };
  }
}
// This function computes the plot size to use for relayout as a function of the container size
function computePlotSize(data = getSizeData()) {
  // Remove Padding
  const { container_pad, plot_pad, container_rect } = data;
  const offsets = {
    width:
      plot_pad.padding.width +
      plot_pad.border.width +
      plot_pad.offset.left +
      container_pad.padding.width +
      container_pad.border.width,
    height:
      plot_pad.padding.height +
      plot_pad.border.height +
      plot_pad.offset.top +
      container_pad.padding.height +
      container_pad.border.height,
  };
  const sz = {
    width: Math.round(container_rect.width - offsets.width),
    height: Math.round(container_rect.height - offsets.height),
    offsets,
  };
  return sz;
}

// Create the resizeObserver to make the plot even more responsive! :magic:
const resizeObserver = new ResizeObserver((entries) => {
  const sizeData = getSizeData();
  const {container_rect, container_pad} = sizeData;
  let plot_size = computePlotSize(sizeData);
  // We save the height in the PLOT object
  PLOT.container_height = container_rect.height;
  // We deal with some stuff if the container is poppped
  CLIPBOARD_HEADER.style.width = container_rect.width + "px";
  CLIPBOARD_HEADER.style.left = container_rect.left + "px";
  config_spans.height.ui_value = plot_size.height;
  config_spans.width.ui_value = plot_size.width;
  /* 
		The addition of the invalid argument `plutoresize` seems to fix the problem with calling `relayout` simply with `{autosize: true}` as update breaking mouse relayout events tracking. 
		See https://github.com/plotly/plotly.js/issues/6156 for details
		*/
  let config = {
    // If this is popped out, we ignore the original width/height
    width: (CONTAINER.isPoppedOut() ? undefined : original_width) ?? plot_size.width,
    height: (CONTAINER.isPoppedOut() ? undefined : original_height) ?? plot_size.height,
    plutoresize: true,
  };
  Plotly.relayout(PLOT, config).then(() => {
    if (remove_container_size && !CONTAINER.isPoppedOut()) {
      // This is needed to avoid the first resize upon plot creation to already be without a fixed height
      CONTAINER.style.height = "";
      CONTAINER.style.width = "";
      remove_container_size = false;
    }
  });
});

resizeObserver.observe(CONTAINER);


Plotly.react(PLOT, plot_obj).then(() => {
	// Assign the Plotly event listeners
	for (const [key, listener_vec] of Object.entries(plotly_listeners)) {
		for (const listener of listener_vec) {
			PLOT.on(key, listener)
		}
	}
	// Assign the JS event listeners
	for (const [key, listener_vec] of Object.entries(js_listeners)) {
		for (const listener of listener_vec) {
			PLOT.addEventListener(key, listener, {
				signal: controller.signal
			})
		}
	}
}
)


invalidation.then(() => {
	// Remove all plotly listeners
	PLOT.removeAllListeners()
	// Remove all JS listeners
	controller.abort()
	// Remove the resizeObserver
	resizeObserver.disconnect()
})



		return CONTAINER
	</script>
</td></tr><tr><td align="right">No usable ace</td><td align="center">	<script id='plot_3'>
		// We start by putting all the variable interpolation here at the beginning
		// We have to convert all typedarrays in the layout to normal arrays. See Issue #25
		// We use lodash for this for compactness
		function removeTypedArray(o) {
			return _.isTypedArray(o) ? Array.from(o) :
			_.isPlainObject(o) ? _.mapValues(o, removeTypedArray) : 
			o
		}

		// Publish the plot object to JS
		let plot_obj = _.update(/* See the documentation for AbstractPlutoDingetjes.Display.published_to_js */ getPublishedObject("c6e0de0c-3901-11f0-234e-bd09c571f662/1c437dfc407d8916"), "layout", removeTypedArray)
		// Get the plotly listeners
		const plotly_listeners = {}
		// Get the JS listeners
		const js_listeners = {}
		// Deal with eventual custom classes
		let custom_classlist = []


		// Load the plotly library
		let Plotly = undefined
		try {
			let _mod = await import("./plotlyjs/plotlyjs-2.26.2.min.js")
			Plotly = _mod.default
		} catch (e) {
			console.log("Local load failed, trying with the web esm.sh version")
			let _mod = await import("https://esm.sh/plotly.js-dist-min@2.26.2/es2022/plotly.js-dist-min.mjs")
			Plotly = _mod.default
		}

		// Check if we have to force local mathjax font cache
		if (false && window?.MathJax?.config?.svg?.fontCache === 'global') {
			window.MathJax.config.svg.fontCache = 'local'
		}

		// Flag to check if this cell was  manually ran or reactively ran
const firstRun = this ? false : true
const CONTAINER = this ?? html`<div class='plutoplotly-container'>`
const PLOT = CONTAINER.querySelector('.js-plotly-plot') ?? CONTAINER.appendChild(html`<div>`)
const parent = CONTAINER.parentElement
// We use a controller to remove event listeners upon invalidation
const controller = new AbortController()
// We have to add this to keep supporting @bind with the old API using PLOT
PLOT.addEventListener('input', (e) => {
	CONTAINER.value = PLOT.value
	if (e.bubbles) {
		return
	}
	CONTAINER.dispatchEvent(new CustomEvent('input'))
}, { signal: controller.signal })

	// This create the style subdiv on first run
	firstRun && CONTAINER.appendChild(html`
	<style>
	.plutoplotly-container {
		width: 100%;
		height: 100%;
		min-height: 0;
		min-width: 0;
	}
	.plutoplotly-container .js-plotly-plot .plotly div {
		margin: 0 auto; // This centers the plot
	}
	.plutoplotly-container.popped-out {
		overflow: auto;
		z-index: 1000;
		position: fixed;
		resize: both;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		border-top-left-radius: 0px;
		border-top-right-radius: 0px;
	}
	.plutoplotly-clipboard-header {
		display: flex;
		flex-flow: row wrap;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-top-left-radius: 12px;
		border-top-right-radius: 12px;
		position: fixed;
		z-index: 1001;
		cursor: move;
		transform: translate(0px, -100%);
		padding: 5px;
	}
	.plutoplotly-clipboard-header span {
		display: inline-block;
		flex: 1
	}
	.plutoplotly-clipboard-header.hidden {
		display: none;
	}
	.clipboard-span {
		position: relative;
	}
	.clipboard-value {
		padding-right: 5px;
		padding-left: 2px;
		cursor: text;
	}
	.clipboard-span.format {
		display: none;
	}
	.clipboard-span.filename {
		flex: 0 0 100%;
		text-align: center;
		border-top: 3px solid var(--kbd-border-color);
		margin-top: 5px;
		display: none;
	}
	.plutoplotly-container.filesave .clipboard-span.filename {
		display: inline-block;
	}
	.clipboard-value.filename {
		margin-left: 3px;
		text-align: left;
		min-width: min(60%, min-content);
	}
	.plutoplotly-container.filesave .clipboard-span.format {
		display: inline-flex;
	}
	.clipboard-span.format .label {
		flex: 0 0 0;
	}
	.clipboard-value.format {
		position: relative;
		flex: 1 0 auto;
		min-width: 30px;
		margin-right: 10px;
	}
	div.format-options {
		display: inline-flex;
		flex-flow: column;
		position: absolute;
		background: var(--main-bg-color);
		border-radius: 12px;
		padding-left: 3px;
		z-index: 2000;
	}
	div.format-options:hover {
		cursor: pointer;
		border: 3px solid var(--kbd-border-color);
		padding: 3px;
		transform: translate(-3px, -6px);
	}
	div.format-options .format-option {
		display: none;
	}
	div.format-options:hover .format-option {
		display: inline-block;
	}
	.format-option:not(.selected) {
		margin-top: 3px;
	}
	div.format-options .format-option.selected {
		order: -1;
		display: inline-block;
	}
	.format-option:hover {
		background-color: var(--kbd-border-color);
	}
	span.config-value {
		font-weight: normal;
		color: var(--pluto-output-color);
		display: none;
		position: absolute;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		transform: translate(0px, calc(-100% - 10px));
		padding: 5px;
	}
	.label {
		user-select: none;
	}
	.label:hover span.config-value {
		display: inline-block;
		min-width: 150px;
	}
	.clipboard-span.matching-config .label {
		color: var(--cm-macro-color);
		font-weight: bold;
	}
	.clipboard-span.different-config .label {
		color: var(--cm-tag-color);
		font-weight: bold;
	}
</style>
`)

let original_height = plot_obj.layout.height
let original_width = plot_obj.layout.width
// For the height we have to also put a fixed value in case the plot is put on a non-fixed-size container (like the default wrapper)
// We define a variable to check whether we still have to remove the fixed height
let remove_container_size = firstRun
let container_height = original_height ?? PLOT.container_height ?? 400
CONTAINER.style.height = container_height + 'px'

// We create a Promise version of setTimeout
function delay(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

// We import interact for dragging/resizing
const { default: interact } = await import('https://esm.sh/interactjs@1.10.19')


function getImageOptions() {
  const o = plot_obj.config.toImageButtonOptions ?? {};
  return {
    format: o.format ?? "png",
    width: o.width ?? original_width,
    height: o.height ?? original_height,
    scale: o.scale ?? 1,
    filename: o.filename ?? "newplot",
  };
}

const CLIPBOARD_HEADER =
  CONTAINER.querySelector(".plutoplotly-clipboard-header") ??
  CONTAINER.insertAdjacentElement(
    "afterbegin",
    html`<div class="plutoplotly-clipboard-header hidden">
      <span class="clipboard-span format"
        ><span class="label">Format:</span
        ><span class="clipboard-value format"></span
      ></span>
      <span class="clipboard-span width"
        ><span class="label">Width:</span
        ><span class="clipboard-value width"></span>px</span
      >
      <span class="clipboard-span height"
        ><span class="label">Height:</span
        ><span class="clipboard-value height"></span>px</span
      >
      <span class="clipboard-span scale"
        ><span class="label">Scale:</span
        ><span class="clipboard-value scale"></span
      ></span>
      <button class="clipboard-span set">Set</button>
      <button class="clipboard-span unset">Unset</button>
      <span class="clipboard-span filename"
        ><span class="label">Filename:</span
        ><span class="clipboard-value filename"></span
      ></span>
    </div>`
  );

function checkConfigSync(container) {
  const valid_classes = [
    "missing-config",
    "matching-config",
    "different-config",
  ];
  function setClass(cl) {
    for (const name of valid_classes) {
      container.classList.toggle(name, name == cl);
    }
  }
  // We use the custom getters we'll set up in the container
  const { ui_value, config_value, config_span, key } = container;
  if (config_value === undefined) {
    setClass("missing-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> is not present in the config.`;
  } else if (ui_value == config_value) {
    setClass("matching-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has the same value in the config and in the header.`;
  } else {
    setClass("different-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has a different value (<em>${config_value}</em>) in the config.`;
  }
  // Add info about setting and unsetting
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click on the label <em><b>once</b></em> to set the current UI value in the config.`
  );
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click <em><b>twice</b></em> to remove this key from the config.`
  );
}

const valid_formats = ["png", "svg", "webp", "jpeg", "full-json"];
function initializeUIValueSpan(span, key, value) {
  const container = span.closest(".clipboard-span");
  span.contentEditable = key === "format" ? "false" : "true";
  let parse = (x) => x;
  let update = (x) => (span.textContent = x);
  if (key === "width" || key === "height") {
    parse = (x) => Math.round(parseFloat(x));
  } else if (key === "scale") {
    parse = parseFloat;
  } else if (key === "format") {
    // We remove contentEditable
    span.contentEditable = "false";
    // Here we first add the subspans for each option
    const opts_div = span.appendChild(html`<div class="format-options"></div>`);
    for (const fmt of valid_formats) {
      const opt = opts_div.appendChild(
        html`<span class="format-option ${fmt}">${fmt}</span>`
      );
      opt.onclick = (e) => {
        span.value = opt.textContent;
      };
    }
    parse = (x) => {
      return valid_formats.includes(x) ? x : localValue;
    };
    update = (x) => {
      for (const opt of opts_div.children) {
        opt.classList.toggle("selected", opt.textContent === x);
      }
    };
  } else {
    // We only have filename here
  }
  let localValue;
  Object.defineProperty(span, "value", {
    get: () => {
      return localValue;
    },
    set: (val) => {
      if (val !== "") {
        localValue = parse(val);
      }
      update(localValue);
      checkConfigSync(container);
    },
  });
  // We also assign a listener so that the editable is blurred when enter is pressed
  span.onkeydown = (e) => {
    if (e.keyCode === 13) {
      e.preventDefault();
      span.blur();
    }
  };
  span.value = value;
}

function initializeConfigValueSpan(span, key) {
  // Here we mostly want to define the setter and getter
  const container = span.closest(".clipboard-span");
  Object.defineProperty(span, "value", {
    get: () => {
      return plot_obj.config.toImageButtonOptions[key];
    },
    set: (val) => {
      // if undefined is passed, we remove the entry from the options
      if (val === undefined) {
        delete plot_obj.config.toImageButtonOptions[key];
      } else {
        plot_obj.config.toImageButtonOptions[key] = val;
      }
      checkConfigSync(container);
    },
  });
}

const config_spans = {};
for (const [key, value] of Object.entries(getImageOptions())) {
  const container = CLIPBOARD_HEADER.querySelector(`.clipboard-span.${key}`);
  const label = container.querySelector(".label");
  // We give the label a function that on single click will set the current value and with double click will unset it
  label.onclick = DualClick(
    () => {
      container.config_value = container.ui_value;
    },
    (e) => {
      console.log("e", e);
      e.preventDefault();
      container.config_value = undefined;
    }
  );
  const ui_value_span = container.querySelector(".clipboard-value");
  const config_value_span =
    container.querySelector(".config-value") ??
    label.insertAdjacentElement(
      "afterbegin",
      html`<span class="config-value"></span>`
    );
  // Assing the two spans as properties of the containing span
  container.ui_span = ui_value_span;
  container.config_span = config_value_span;
  container.key = key;
  config_spans[key] = container;
  if (firstRun) {
    plot_obj.config.toImageButtonOptions =
      plot_obj.config.toImageButtonOptions ?? {};
    // We do the initialization of the value span
    initializeUIValueSpan(ui_value_span, key, value);
    // Then we initialize the config value
    initializeConfigValueSpan(config_value_span, key);
    // We put some convenience getters/setters
    // ui_value forward
    Object.defineProperty(container, "ui_value", {
      get: () => ui_value_span.value,
      set: (val) => {
        ui_value_span.value = val;
      },
    });
    // config_value forward
    Object.defineProperty(container, "config_value", {
      get: () => config_value_span.value,
      set: (val) => {
        config_value_span.value = val;
      },
    });
  }
}

// These objects will contain the default value

// This code updates the image options in the PLOT config with the provided ones
function setImageOptions(o) {
  for (const [key, container] of Object.entries(config_spans)) {
    container.config_value = o[key];
  }
}
function unsetImageOptions() {
  setImageOptions({});
}

const set_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.set");
const unset_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.unset");
if (firstRun) {
  set_button.onclick = (e) => {
    for (const container of Object.values(config_spans)) {
      container.config_value = container.ui_value;
    }
  };
  unset_button.onclick = unsetImageOptions;
}

// We add a function to check if the clipboard is popped out
CONTAINER.isPoppedOut = () => {
  return CONTAINER.classList.contains("popped-out");
};

CLIPBOARD_HEADER.onmousedown = function (event) {
  if (event.target.matches("span.clipboard-value")) {
    console.log("We don't move!");
    return;
  }
  const start = {
    left: parseFloat(CONTAINER.style.left),
    top: parseFloat(CONTAINER.style.top),
    X: event.pageX,
    Y: event.pageY,
  };
  function moveAt(event, start) {
    const top = event.pageY - start.Y + start.top + "px";
    const left = event.pageX - start.X + start.left + "px";
    CLIPBOARD_HEADER.style.left = left;
    CONTAINER.style.left = left;
    CONTAINER.style.top = top;
  }

  // move our absolutely positioned ball under the pointer
  moveAt(event, start);
  function onMouseMove(event) {
    moveAt(event, start);
  }

  // We use this to remove the mousemove when clicking outside of the container
  const controller = new AbortController();

  // move the container on mousemove
  document.addEventListener("mousemove", onMouseMove, {
    signal: controller.signal,
  });
  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        cleanUp();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );

  function cleanUp() {
    console.log("cleaning up the plot move listener");
    controller.abort();
    CLIPBOARD_HEADER.onmouseup = null;
  }

  // (3) drop the ball, remove unneeded handlers
  CLIPBOARD_HEADER.onmouseup = cleanUp;
};

function sendToClipboard(blob) {
  if (!navigator.clipboard) {
    alert(
      "The Clipboard API does not seem to be available, make sure the Pluto notebook is being used from either localhost or an https source."
    );
  }
  navigator.clipboard
    .write([
      new ClipboardItem({
        // The key is determined dynamically based on the blob's type.
        [blob.type]: blob,
      }),
    ])
    .then(
      function () {
        console.log("Async: Copying to clipboard was successful!");
      },
      function (err) {
        console.error("Async: Could not copy text: ", err);
      }
    );
}

function copyImageToClipboard() {
  // We extract the image options from the provided parameters (if they exist)
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key. We also ignore format because the clipboard only supports png.
    if (val === undefined || key === "format") {
      continue;
    }
    config[key] = val;
  }
  Plotly.toImage(PLOT, config).then(function (dataUrl) {
    fetch(dataUrl)
      .then((res) => res.blob())
      .then((blob) => {
        const paste_receiver = document.querySelector('paste-receiver.plutoplotly')
        if (paste_receiver) {
          paste_receiver.attachImage(dataUrl, CONTAINER)
        }
        sendToClipboard(blob)
      });
  });
}

function saveImageToFile() {
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key.
    if (val === undefined) {
      continue;
    }
    config[key] = val;
  }
  Plotly.downloadImage(PLOT, config);
}

let container_rect = { width: 0, height: 0, top: 0, left: 0 };
function unpop_container(cl) {
  CONTAINER.classList.toggle("popped-out", false);
  CONTAINER.classList.toggle(cl, false);
  // We fix the height back to the value it had before popout, also setting the flag to signal that upon first resize we remove the fixed inline-style
  CONTAINER.style.height = container_rect.height + "px";
  remove_container_size = true;
  // We set the other fixed inline-styles to null
  CONTAINER.style.width = "";
  CONTAINER.style.top = "";
  CONTAINER.style.left = "";
  // We also remove the CLIPBOARD_HEADER
  CLIPBOARD_HEADER.style.width = "";
  CLIPBOARD_HEADER.style.left = "";
  // Finally we remove the hidden class to the header
  CLIPBOARD_HEADER.classList.toggle("hidden", true);
  return;
}
function popout_container(opts) {
  const cl = opts?.cl;
  const target_container_size = opts?.target_container_size ?? {};
  const target_plot_size = opts?.target_plot_size ?? {};
  if (CONTAINER.isPoppedOut()) {
    return unpop_container(cl);
  }
  CONTAINER.classList.toggle(cl, cl === undefined ? false : true);
  // We extract the current size of the container, save them and fix them
  const { width, height, top, left } = CONTAINER.getBoundingClientRect();
  container_rect = { width, height, top, left };
  // We save the current plot size before we pop as it will fill the screen
  const current_plot_size = {
    width: PLOT._fullLayout.width,
    height: PLOT._fullLayout.height,
  };
  // We have to save the pad data before popping so we can resize precisely
  const pad = {};
  pad.unpopped = getSizeData().container_pad;
  CONTAINER.classList.toggle("popped-out", true);
  pad.popped = getSizeData().container_pad;
  // We do top and left based on the current rect
  for (const key of ["top", "left"]) {
    const start_val = target_container_size[key] ?? container_rect[key];
    let offset = 0;
    for (const kind of ["padding", "border"]) {
      offset += pad.popped[kind][key] - pad.unpopped[kind][key];
    }
    CONTAINER.style[key] = start_val - offset + "px";
    if (key === "left") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  // We compute the width and height depending on eventual config data
  const csz = computeContainerSize({
    width:
      target_plot_size.width ??
      config_spans.width.config_value ??
      current_plot_size.width,
    height:
      target_plot_size.height ??
      config_spans.height.config_value ??
      current_plot_size.height,
  });
  for (const key of ["width", "height"]) {
    const val = target_container_size[key] ?? csz[key];
    CONTAINER.style[key] = val + "px";
    if (key === "width") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  CLIPBOARD_HEADER.classList.toggle("hidden", false);
  const controller = new AbortController();

  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        unpop_container();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );
}

CONTAINER.popOut = popout_container;

function DualClick(single_func, dbl_func) {
  let nclicks = 0;
  return function (...args) {
    nclicks += 1;
    if (nclicks > 1) {
      dbl_func(...args);
      nclicks = 0;
    } else {
      delay(300).then(() => {
        if (nclicks == 1) {
          single_func(...args);
        }
        nclicks = 0;
      });
    }
  };
}

// We remove the default download image button
plot_obj.config.modeBarButtonsToRemove = _.union(
  plot_obj.config.modeBarButtonsToRemove,
  ["toImage"]
);
// We add the custom button to the modebar
plot_obj.config.modeBarButtonsToAdd = _.union(
  plot_obj.config.modeBarButtonsToAdd,
  [
    {
      name: "Copy PNG to Clipboard",
      icon: {
        height: 520,
        width: 520,
        path: "M280 64h40c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128C0 92.7 28.7 64 64 64h40 9.6C121 27.5 153.3 0 192 0s71 27.5 78.4 64H280zM64 112c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16H320c8.8 0 16-7.2 16-16V128c0-8.8-7.2-16-16-16H304v24c0 13.3-10.7 24-24 24H192 104c-13.3 0-24-10.7-24-24V112H64zm128-8a24 24 0 1 0 0-48 24 24 0 1 0 0 48z",
      },
      direction: "up",
      click: DualClick(copyImageToClipboard, () => {
        popout_container();
      }),
    },
    {
      name: "Download Image",
      icon: Plotly.Icons.camera,
      direction: "up",
      click: DualClick(saveImageToFile, () => {
        popout_container({ cl: "filesave" });
      }),
    },
  ]
);

function getOffsetData(el) {
  let cs = window.getComputedStyle(el, null);
  const odata = {
    padding: {
      left: parseFloat(cs.paddingLeft),
      right: parseFloat(cs.paddingRight),
      top: parseFloat(cs.paddingTop),
      bottom: parseFloat(cs.paddingBottom),
      width: parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight),
      height: parseFloat(cs.paddingTop) + parseFloat(cs.paddingBottom),
    },
    border: {
      left: parseFloat(cs.borderLeftWidth),
      right: parseFloat(cs.borderRightWidth),
      top: parseFloat(cs.borderTopWidth),
      bottom: parseFloat(cs.borderBottomWidth),
      width: parseFloat(cs.borderLeftWidth) + parseFloat(cs.borderRightWidth),
      height: parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth),
    }
  };
  if (el === PLOT) {
    // For the PLOT we also want to take into account the offset
    odata.offset = {
      top: PLOT.offsetParent == CONTAINER ? PLOT.offsetTop : 0,
      left: PLOT.offsetParent == CONTAINER ? PLOT.offsetLeft : 0,
    }
  }
  return odata;
}
function getSizeData() {
  const data = {
    plot_pad: getOffsetData(PLOT),
    plot_rect: PLOT.getBoundingClientRect(),
    container_pad: getOffsetData(CONTAINER),
    container_rect: CONTAINER.getBoundingClientRect(),
  };
  return data;
}
function computeContainerSize({ width, height }, sizeData = getSizeData()) {
  const computed_size = computePlotSize(sizeData);
  const offsets = computed_size.offsets;

  const plot_data = {
    width: width ?? computed_size.width,
    height: height ?? computed_size.height,
  };

  return {
    width: (width ?? computed_size.width) + offsets.width,
    height: (height ?? computed_size.height) + offsets.height,
    noChange: width == computed_size.width && height == computed_size.height,
  }
}

// This function will change the container size so that the resulting plot will be matching the provided specs
function changeContainerSize({ width, height }, sizeData = getSizeData()) {
  if (!CONTAINER.isPoppedOut()) {
    console.log("Tried to change container size when not popped, ignoring");
    return;
  }

  const csz = computeContainerSize({ width, height }, sizeData);

  if (csz.noChange) {
    console.log("Size is the same as current, ignoring");
    return
  }
  // We are now going to set he width and height of the container
  for (const key of ["width", "height"]) {
    CONTAINER.style[key] = csz[key] + "px";
  }
}
// We now create the function that will update the plot based on the values specified
function updateFromHeader() {
  const header_data = {
    height: config_spans.height.ui_value,
    width: config_spans.width.ui_value,
  };
  changeContainerSize(header_data);
}
// We assign this function to the onblur event of width and height
if (firstRun) {
  for (const container of Object.values(config_spans)) {
    container.ui_span.onblur = (e) => {
      container.ui_value = container.ui_span.textContent;
      updateFromHeader();
    };
  }
}
// This function computes the plot size to use for relayout as a function of the container size
function computePlotSize(data = getSizeData()) {
  // Remove Padding
  const { container_pad, plot_pad, container_rect } = data;
  const offsets = {
    width:
      plot_pad.padding.width +
      plot_pad.border.width +
      plot_pad.offset.left +
      container_pad.padding.width +
      container_pad.border.width,
    height:
      plot_pad.padding.height +
      plot_pad.border.height +
      plot_pad.offset.top +
      container_pad.padding.height +
      container_pad.border.height,
  };
  const sz = {
    width: Math.round(container_rect.width - offsets.width),
    height: Math.round(container_rect.height - offsets.height),
    offsets,
  };
  return sz;
}

// Create the resizeObserver to make the plot even more responsive! :magic:
const resizeObserver = new ResizeObserver((entries) => {
  const sizeData = getSizeData();
  const {container_rect, container_pad} = sizeData;
  let plot_size = computePlotSize(sizeData);
  // We save the height in the PLOT object
  PLOT.container_height = container_rect.height;
  // We deal with some stuff if the container is poppped
  CLIPBOARD_HEADER.style.width = container_rect.width + "px";
  CLIPBOARD_HEADER.style.left = container_rect.left + "px";
  config_spans.height.ui_value = plot_size.height;
  config_spans.width.ui_value = plot_size.width;
  /* 
		The addition of the invalid argument `plutoresize` seems to fix the problem with calling `relayout` simply with `{autosize: true}` as update breaking mouse relayout events tracking. 
		See https://github.com/plotly/plotly.js/issues/6156 for details
		*/
  let config = {
    // If this is popped out, we ignore the original width/height
    width: (CONTAINER.isPoppedOut() ? undefined : original_width) ?? plot_size.width,
    height: (CONTAINER.isPoppedOut() ? undefined : original_height) ?? plot_size.height,
    plutoresize: true,
  };
  Plotly.relayout(PLOT, config).then(() => {
    if (remove_container_size && !CONTAINER.isPoppedOut()) {
      // This is needed to avoid the first resize upon plot creation to already be without a fixed height
      CONTAINER.style.height = "";
      CONTAINER.style.width = "";
      remove_container_size = false;
    }
  });
});

resizeObserver.observe(CONTAINER);


Plotly.react(PLOT, plot_obj).then(() => {
	// Assign the Plotly event listeners
	for (const [key, listener_vec] of Object.entries(plotly_listeners)) {
		for (const listener of listener_vec) {
			PLOT.on(key, listener)
		}
	}
	// Assign the JS event listeners
	for (const [key, listener_vec] of Object.entries(js_listeners)) {
		for (const listener of listener_vec) {
			PLOT.addEventListener(key, listener, {
				signal: controller.signal
			})
		}
	}
}
)


invalidation.then(() => {
	// Remove all plotly listeners
	PLOT.removeAllListeners()
	// Remove all JS listeners
	controller.abort()
	// Remove the resizeObserver
	resizeObserver.disconnect()
})



		return CONTAINER
	</script>
</td><td align="center">	<script id='plot_4'>
		// We start by putting all the variable interpolation here at the beginning
		// We have to convert all typedarrays in the layout to normal arrays. See Issue #25
		// We use lodash for this for compactness
		function removeTypedArray(o) {
			return _.isTypedArray(o) ? Array.from(o) :
			_.isPlainObject(o) ? _.mapValues(o, removeTypedArray) : 
			o
		}

		// Publish the plot object to JS
		let plot_obj = _.update(/* See the documentation for AbstractPlutoDingetjes.Display.published_to_js */ getPublishedObject("c6e0de0c-3901-11f0-234e-bd09c571f662/10b6971fa80c859d"), "layout", removeTypedArray)
		// Get the plotly listeners
		const plotly_listeners = {}
		// Get the JS listeners
		const js_listeners = {}
		// Deal with eventual custom classes
		let custom_classlist = []


		// Load the plotly library
		let Plotly = undefined
		try {
			let _mod = await import("./plotlyjs/plotlyjs-2.26.2.min.js")
			Plotly = _mod.default
		} catch (e) {
			console.log("Local load failed, trying with the web esm.sh version")
			let _mod = await import("https://esm.sh/plotly.js-dist-min@2.26.2/es2022/plotly.js-dist-min.mjs")
			Plotly = _mod.default
		}

		// Check if we have to force local mathjax font cache
		if (false && window?.MathJax?.config?.svg?.fontCache === 'global') {
			window.MathJax.config.svg.fontCache = 'local'
		}

		// Flag to check if this cell was  manually ran or reactively ran
const firstRun = this ? false : true
const CONTAINER = this ?? html`<div class='plutoplotly-container'>`
const PLOT = CONTAINER.querySelector('.js-plotly-plot') ?? CONTAINER.appendChild(html`<div>`)
const parent = CONTAINER.parentElement
// We use a controller to remove event listeners upon invalidation
const controller = new AbortController()
// We have to add this to keep supporting @bind with the old API using PLOT
PLOT.addEventListener('input', (e) => {
	CONTAINER.value = PLOT.value
	if (e.bubbles) {
		return
	}
	CONTAINER.dispatchEvent(new CustomEvent('input'))
}, { signal: controller.signal })

	// This create the style subdiv on first run
	firstRun && CONTAINER.appendChild(html`
	<style>
	.plutoplotly-container {
		width: 100%;
		height: 100%;
		min-height: 0;
		min-width: 0;
	}
	.plutoplotly-container .js-plotly-plot .plotly div {
		margin: 0 auto; // This centers the plot
	}
	.plutoplotly-container.popped-out {
		overflow: auto;
		z-index: 1000;
		position: fixed;
		resize: both;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		border-top-left-radius: 0px;
		border-top-right-radius: 0px;
	}
	.plutoplotly-clipboard-header {
		display: flex;
		flex-flow: row wrap;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-top-left-radius: 12px;
		border-top-right-radius: 12px;
		position: fixed;
		z-index: 1001;
		cursor: move;
		transform: translate(0px, -100%);
		padding: 5px;
	}
	.plutoplotly-clipboard-header span {
		display: inline-block;
		flex: 1
	}
	.plutoplotly-clipboard-header.hidden {
		display: none;
	}
	.clipboard-span {
		position: relative;
	}
	.clipboard-value {
		padding-right: 5px;
		padding-left: 2px;
		cursor: text;
	}
	.clipboard-span.format {
		display: none;
	}
	.clipboard-span.filename {
		flex: 0 0 100%;
		text-align: center;
		border-top: 3px solid var(--kbd-border-color);
		margin-top: 5px;
		display: none;
	}
	.plutoplotly-container.filesave .clipboard-span.filename {
		display: inline-block;
	}
	.clipboard-value.filename {
		margin-left: 3px;
		text-align: left;
		min-width: min(60%, min-content);
	}
	.plutoplotly-container.filesave .clipboard-span.format {
		display: inline-flex;
	}
	.clipboard-span.format .label {
		flex: 0 0 0;
	}
	.clipboard-value.format {
		position: relative;
		flex: 1 0 auto;
		min-width: 30px;
		margin-right: 10px;
	}
	div.format-options {
		display: inline-flex;
		flex-flow: column;
		position: absolute;
		background: var(--main-bg-color);
		border-radius: 12px;
		padding-left: 3px;
		z-index: 2000;
	}
	div.format-options:hover {
		cursor: pointer;
		border: 3px solid var(--kbd-border-color);
		padding: 3px;
		transform: translate(-3px, -6px);
	}
	div.format-options .format-option {
		display: none;
	}
	div.format-options:hover .format-option {
		display: inline-block;
	}
	.format-option:not(.selected) {
		margin-top: 3px;
	}
	div.format-options .format-option.selected {
		order: -1;
		display: inline-block;
	}
	.format-option:hover {
		background-color: var(--kbd-border-color);
	}
	span.config-value {
		font-weight: normal;
		color: var(--pluto-output-color);
		display: none;
		position: absolute;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		transform: translate(0px, calc(-100% - 10px));
		padding: 5px;
	}
	.label {
		user-select: none;
	}
	.label:hover span.config-value {
		display: inline-block;
		min-width: 150px;
	}
	.clipboard-span.matching-config .label {
		color: var(--cm-macro-color);
		font-weight: bold;
	}
	.clipboard-span.different-config .label {
		color: var(--cm-tag-color);
		font-weight: bold;
	}
</style>
`)

let original_height = plot_obj.layout.height
let original_width = plot_obj.layout.width
// For the height we have to also put a fixed value in case the plot is put on a non-fixed-size container (like the default wrapper)
// We define a variable to check whether we still have to remove the fixed height
let remove_container_size = firstRun
let container_height = original_height ?? PLOT.container_height ?? 400
CONTAINER.style.height = container_height + 'px'

// We create a Promise version of setTimeout
function delay(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

// We import interact for dragging/resizing
const { default: interact } = await import('https://esm.sh/interactjs@1.10.19')


function getImageOptions() {
  const o = plot_obj.config.toImageButtonOptions ?? {};
  return {
    format: o.format ?? "png",
    width: o.width ?? original_width,
    height: o.height ?? original_height,
    scale: o.scale ?? 1,
    filename: o.filename ?? "newplot",
  };
}

const CLIPBOARD_HEADER =
  CONTAINER.querySelector(".plutoplotly-clipboard-header") ??
  CONTAINER.insertAdjacentElement(
    "afterbegin",
    html`<div class="plutoplotly-clipboard-header hidden">
      <span class="clipboard-span format"
        ><span class="label">Format:</span
        ><span class="clipboard-value format"></span
      ></span>
      <span class="clipboard-span width"
        ><span class="label">Width:</span
        ><span class="clipboard-value width"></span>px</span
      >
      <span class="clipboard-span height"
        ><span class="label">Height:</span
        ><span class="clipboard-value height"></span>px</span
      >
      <span class="clipboard-span scale"
        ><span class="label">Scale:</span
        ><span class="clipboard-value scale"></span
      ></span>
      <button class="clipboard-span set">Set</button>
      <button class="clipboard-span unset">Unset</button>
      <span class="clipboard-span filename"
        ><span class="label">Filename:</span
        ><span class="clipboard-value filename"></span
      ></span>
    </div>`
  );

function checkConfigSync(container) {
  const valid_classes = [
    "missing-config",
    "matching-config",
    "different-config",
  ];
  function setClass(cl) {
    for (const name of valid_classes) {
      container.classList.toggle(name, name == cl);
    }
  }
  // We use the custom getters we'll set up in the container
  const { ui_value, config_value, config_span, key } = container;
  if (config_value === undefined) {
    setClass("missing-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> is not present in the config.`;
  } else if (ui_value == config_value) {
    setClass("matching-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has the same value in the config and in the header.`;
  } else {
    setClass("different-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has a different value (<em>${config_value}</em>) in the config.`;
  }
  // Add info about setting and unsetting
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click on the label <em><b>once</b></em> to set the current UI value in the config.`
  );
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click <em><b>twice</b></em> to remove this key from the config.`
  );
}

const valid_formats = ["png", "svg", "webp", "jpeg", "full-json"];
function initializeUIValueSpan(span, key, value) {
  const container = span.closest(".clipboard-span");
  span.contentEditable = key === "format" ? "false" : "true";
  let parse = (x) => x;
  let update = (x) => (span.textContent = x);
  if (key === "width" || key === "height") {
    parse = (x) => Math.round(parseFloat(x));
  } else if (key === "scale") {
    parse = parseFloat;
  } else if (key === "format") {
    // We remove contentEditable
    span.contentEditable = "false";
    // Here we first add the subspans for each option
    const opts_div = span.appendChild(html`<div class="format-options"></div>`);
    for (const fmt of valid_formats) {
      const opt = opts_div.appendChild(
        html`<span class="format-option ${fmt}">${fmt}</span>`
      );
      opt.onclick = (e) => {
        span.value = opt.textContent;
      };
    }
    parse = (x) => {
      return valid_formats.includes(x) ? x : localValue;
    };
    update = (x) => {
      for (const opt of opts_div.children) {
        opt.classList.toggle("selected", opt.textContent === x);
      }
    };
  } else {
    // We only have filename here
  }
  let localValue;
  Object.defineProperty(span, "value", {
    get: () => {
      return localValue;
    },
    set: (val) => {
      if (val !== "") {
        localValue = parse(val);
      }
      update(localValue);
      checkConfigSync(container);
    },
  });
  // We also assign a listener so that the editable is blurred when enter is pressed
  span.onkeydown = (e) => {
    if (e.keyCode === 13) {
      e.preventDefault();
      span.blur();
    }
  };
  span.value = value;
}

function initializeConfigValueSpan(span, key) {
  // Here we mostly want to define the setter and getter
  const container = span.closest(".clipboard-span");
  Object.defineProperty(span, "value", {
    get: () => {
      return plot_obj.config.toImageButtonOptions[key];
    },
    set: (val) => {
      // if undefined is passed, we remove the entry from the options
      if (val === undefined) {
        delete plot_obj.config.toImageButtonOptions[key];
      } else {
        plot_obj.config.toImageButtonOptions[key] = val;
      }
      checkConfigSync(container);
    },
  });
}

const config_spans = {};
for (const [key, value] of Object.entries(getImageOptions())) {
  const container = CLIPBOARD_HEADER.querySelector(`.clipboard-span.${key}`);
  const label = container.querySelector(".label");
  // We give the label a function that on single click will set the current value and with double click will unset it
  label.onclick = DualClick(
    () => {
      container.config_value = container.ui_value;
    },
    (e) => {
      console.log("e", e);
      e.preventDefault();
      container.config_value = undefined;
    }
  );
  const ui_value_span = container.querySelector(".clipboard-value");
  const config_value_span =
    container.querySelector(".config-value") ??
    label.insertAdjacentElement(
      "afterbegin",
      html`<span class="config-value"></span>`
    );
  // Assing the two spans as properties of the containing span
  container.ui_span = ui_value_span;
  container.config_span = config_value_span;
  container.key = key;
  config_spans[key] = container;
  if (firstRun) {
    plot_obj.config.toImageButtonOptions =
      plot_obj.config.toImageButtonOptions ?? {};
    // We do the initialization of the value span
    initializeUIValueSpan(ui_value_span, key, value);
    // Then we initialize the config value
    initializeConfigValueSpan(config_value_span, key);
    // We put some convenience getters/setters
    // ui_value forward
    Object.defineProperty(container, "ui_value", {
      get: () => ui_value_span.value,
      set: (val) => {
        ui_value_span.value = val;
      },
    });
    // config_value forward
    Object.defineProperty(container, "config_value", {
      get: () => config_value_span.value,
      set: (val) => {
        config_value_span.value = val;
      },
    });
  }
}

// These objects will contain the default value

// This code updates the image options in the PLOT config with the provided ones
function setImageOptions(o) {
  for (const [key, container] of Object.entries(config_spans)) {
    container.config_value = o[key];
  }
}
function unsetImageOptions() {
  setImageOptions({});
}

const set_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.set");
const unset_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.unset");
if (firstRun) {
  set_button.onclick = (e) => {
    for (const container of Object.values(config_spans)) {
      container.config_value = container.ui_value;
    }
  };
  unset_button.onclick = unsetImageOptions;
}

// We add a function to check if the clipboard is popped out
CONTAINER.isPoppedOut = () => {
  return CONTAINER.classList.contains("popped-out");
};

CLIPBOARD_HEADER.onmousedown = function (event) {
  if (event.target.matches("span.clipboard-value")) {
    console.log("We don't move!");
    return;
  }
  const start = {
    left: parseFloat(CONTAINER.style.left),
    top: parseFloat(CONTAINER.style.top),
    X: event.pageX,
    Y: event.pageY,
  };
  function moveAt(event, start) {
    const top = event.pageY - start.Y + start.top + "px";
    const left = event.pageX - start.X + start.left + "px";
    CLIPBOARD_HEADER.style.left = left;
    CONTAINER.style.left = left;
    CONTAINER.style.top = top;
  }

  // move our absolutely positioned ball under the pointer
  moveAt(event, start);
  function onMouseMove(event) {
    moveAt(event, start);
  }

  // We use this to remove the mousemove when clicking outside of the container
  const controller = new AbortController();

  // move the container on mousemove
  document.addEventListener("mousemove", onMouseMove, {
    signal: controller.signal,
  });
  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        cleanUp();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );

  function cleanUp() {
    console.log("cleaning up the plot move listener");
    controller.abort();
    CLIPBOARD_HEADER.onmouseup = null;
  }

  // (3) drop the ball, remove unneeded handlers
  CLIPBOARD_HEADER.onmouseup = cleanUp;
};

function sendToClipboard(blob) {
  if (!navigator.clipboard) {
    alert(
      "The Clipboard API does not seem to be available, make sure the Pluto notebook is being used from either localhost or an https source."
    );
  }
  navigator.clipboard
    .write([
      new ClipboardItem({
        // The key is determined dynamically based on the blob's type.
        [blob.type]: blob,
      }),
    ])
    .then(
      function () {
        console.log("Async: Copying to clipboard was successful!");
      },
      function (err) {
        console.error("Async: Could not copy text: ", err);
      }
    );
}

function copyImageToClipboard() {
  // We extract the image options from the provided parameters (if they exist)
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key. We also ignore format because the clipboard only supports png.
    if (val === undefined || key === "format") {
      continue;
    }
    config[key] = val;
  }
  Plotly.toImage(PLOT, config).then(function (dataUrl) {
    fetch(dataUrl)
      .then((res) => res.blob())
      .then((blob) => {
        const paste_receiver = document.querySelector('paste-receiver.plutoplotly')
        if (paste_receiver) {
          paste_receiver.attachImage(dataUrl, CONTAINER)
        }
        sendToClipboard(blob)
      });
  });
}

function saveImageToFile() {
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key.
    if (val === undefined) {
      continue;
    }
    config[key] = val;
  }
  Plotly.downloadImage(PLOT, config);
}

let container_rect = { width: 0, height: 0, top: 0, left: 0 };
function unpop_container(cl) {
  CONTAINER.classList.toggle("popped-out", false);
  CONTAINER.classList.toggle(cl, false);
  // We fix the height back to the value it had before popout, also setting the flag to signal that upon first resize we remove the fixed inline-style
  CONTAINER.style.height = container_rect.height + "px";
  remove_container_size = true;
  // We set the other fixed inline-styles to null
  CONTAINER.style.width = "";
  CONTAINER.style.top = "";
  CONTAINER.style.left = "";
  // We also remove the CLIPBOARD_HEADER
  CLIPBOARD_HEADER.style.width = "";
  CLIPBOARD_HEADER.style.left = "";
  // Finally we remove the hidden class to the header
  CLIPBOARD_HEADER.classList.toggle("hidden", true);
  return;
}
function popout_container(opts) {
  const cl = opts?.cl;
  const target_container_size = opts?.target_container_size ?? {};
  const target_plot_size = opts?.target_plot_size ?? {};
  if (CONTAINER.isPoppedOut()) {
    return unpop_container(cl);
  }
  CONTAINER.classList.toggle(cl, cl === undefined ? false : true);
  // We extract the current size of the container, save them and fix them
  const { width, height, top, left } = CONTAINER.getBoundingClientRect();
  container_rect = { width, height, top, left };
  // We save the current plot size before we pop as it will fill the screen
  const current_plot_size = {
    width: PLOT._fullLayout.width,
    height: PLOT._fullLayout.height,
  };
  // We have to save the pad data before popping so we can resize precisely
  const pad = {};
  pad.unpopped = getSizeData().container_pad;
  CONTAINER.classList.toggle("popped-out", true);
  pad.popped = getSizeData().container_pad;
  // We do top and left based on the current rect
  for (const key of ["top", "left"]) {
    const start_val = target_container_size[key] ?? container_rect[key];
    let offset = 0;
    for (const kind of ["padding", "border"]) {
      offset += pad.popped[kind][key] - pad.unpopped[kind][key];
    }
    CONTAINER.style[key] = start_val - offset + "px";
    if (key === "left") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  // We compute the width and height depending on eventual config data
  const csz = computeContainerSize({
    width:
      target_plot_size.width ??
      config_spans.width.config_value ??
      current_plot_size.width,
    height:
      target_plot_size.height ??
      config_spans.height.config_value ??
      current_plot_size.height,
  });
  for (const key of ["width", "height"]) {
    const val = target_container_size[key] ?? csz[key];
    CONTAINER.style[key] = val + "px";
    if (key === "width") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  CLIPBOARD_HEADER.classList.toggle("hidden", false);
  const controller = new AbortController();

  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        unpop_container();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );
}

CONTAINER.popOut = popout_container;

function DualClick(single_func, dbl_func) {
  let nclicks = 0;
  return function (...args) {
    nclicks += 1;
    if (nclicks > 1) {
      dbl_func(...args);
      nclicks = 0;
    } else {
      delay(300).then(() => {
        if (nclicks == 1) {
          single_func(...args);
        }
        nclicks = 0;
      });
    }
  };
}

// We remove the default download image button
plot_obj.config.modeBarButtonsToRemove = _.union(
  plot_obj.config.modeBarButtonsToRemove,
  ["toImage"]
);
// We add the custom button to the modebar
plot_obj.config.modeBarButtonsToAdd = _.union(
  plot_obj.config.modeBarButtonsToAdd,
  [
    {
      name: "Copy PNG to Clipboard",
      icon: {
        height: 520,
        width: 520,
        path: "M280 64h40c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128C0 92.7 28.7 64 64 64h40 9.6C121 27.5 153.3 0 192 0s71 27.5 78.4 64H280zM64 112c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16H320c8.8 0 16-7.2 16-16V128c0-8.8-7.2-16-16-16H304v24c0 13.3-10.7 24-24 24H192 104c-13.3 0-24-10.7-24-24V112H64zm128-8a24 24 0 1 0 0-48 24 24 0 1 0 0 48z",
      },
      direction: "up",
      click: DualClick(copyImageToClipboard, () => {
        popout_container();
      }),
    },
    {
      name: "Download Image",
      icon: Plotly.Icons.camera,
      direction: "up",
      click: DualClick(saveImageToFile, () => {
        popout_container({ cl: "filesave" });
      }),
    },
  ]
);

function getOffsetData(el) {
  let cs = window.getComputedStyle(el, null);
  const odata = {
    padding: {
      left: parseFloat(cs.paddingLeft),
      right: parseFloat(cs.paddingRight),
      top: parseFloat(cs.paddingTop),
      bottom: parseFloat(cs.paddingBottom),
      width: parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight),
      height: parseFloat(cs.paddingTop) + parseFloat(cs.paddingBottom),
    },
    border: {
      left: parseFloat(cs.borderLeftWidth),
      right: parseFloat(cs.borderRightWidth),
      top: parseFloat(cs.borderTopWidth),
      bottom: parseFloat(cs.borderBottomWidth),
      width: parseFloat(cs.borderLeftWidth) + parseFloat(cs.borderRightWidth),
      height: parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth),
    }
  };
  if (el === PLOT) {
    // For the PLOT we also want to take into account the offset
    odata.offset = {
      top: PLOT.offsetParent == CONTAINER ? PLOT.offsetTop : 0,
      left: PLOT.offsetParent == CONTAINER ? PLOT.offsetLeft : 0,
    }
  }
  return odata;
}
function getSizeData() {
  const data = {
    plot_pad: getOffsetData(PLOT),
    plot_rect: PLOT.getBoundingClientRect(),
    container_pad: getOffsetData(CONTAINER),
    container_rect: CONTAINER.getBoundingClientRect(),
  };
  return data;
}
function computeContainerSize({ width, height }, sizeData = getSizeData()) {
  const computed_size = computePlotSize(sizeData);
  const offsets = computed_size.offsets;

  const plot_data = {
    width: width ?? computed_size.width,
    height: height ?? computed_size.height,
  };

  return {
    width: (width ?? computed_size.width) + offsets.width,
    height: (height ?? computed_size.height) + offsets.height,
    noChange: width == computed_size.width && height == computed_size.height,
  }
}

// This function will change the container size so that the resulting plot will be matching the provided specs
function changeContainerSize({ width, height }, sizeData = getSizeData()) {
  if (!CONTAINER.isPoppedOut()) {
    console.log("Tried to change container size when not popped, ignoring");
    return;
  }

  const csz = computeContainerSize({ width, height }, sizeData);

  if (csz.noChange) {
    console.log("Size is the same as current, ignoring");
    return
  }
  // We are now going to set he width and height of the container
  for (const key of ["width", "height"]) {
    CONTAINER.style[key] = csz[key] + "px";
  }
}
// We now create the function that will update the plot based on the values specified
function updateFromHeader() {
  const header_data = {
    height: config_spans.height.ui_value,
    width: config_spans.width.ui_value,
  };
  changeContainerSize(header_data);
}
// We assign this function to the onblur event of width and height
if (firstRun) {
  for (const container of Object.values(config_spans)) {
    container.ui_span.onblur = (e) => {
      container.ui_value = container.ui_span.textContent;
      updateFromHeader();
    };
  }
}
// This function computes the plot size to use for relayout as a function of the container size
function computePlotSize(data = getSizeData()) {
  // Remove Padding
  const { container_pad, plot_pad, container_rect } = data;
  const offsets = {
    width:
      plot_pad.padding.width +
      plot_pad.border.width +
      plot_pad.offset.left +
      container_pad.padding.width +
      container_pad.border.width,
    height:
      plot_pad.padding.height +
      plot_pad.border.height +
      plot_pad.offset.top +
      container_pad.padding.height +
      container_pad.border.height,
  };
  const sz = {
    width: Math.round(container_rect.width - offsets.width),
    height: Math.round(container_rect.height - offsets.height),
    offsets,
  };
  return sz;
}

// Create the resizeObserver to make the plot even more responsive! :magic:
const resizeObserver = new ResizeObserver((entries) => {
  const sizeData = getSizeData();
  const {container_rect, container_pad} = sizeData;
  let plot_size = computePlotSize(sizeData);
  // We save the height in the PLOT object
  PLOT.container_height = container_rect.height;
  // We deal with some stuff if the container is poppped
  CLIPBOARD_HEADER.style.width = container_rect.width + "px";
  CLIPBOARD_HEADER.style.left = container_rect.left + "px";
  config_spans.height.ui_value = plot_size.height;
  config_spans.width.ui_value = plot_size.width;
  /* 
		The addition of the invalid argument `plutoresize` seems to fix the problem with calling `relayout` simply with `{autosize: true}` as update breaking mouse relayout events tracking. 
		See https://github.com/plotly/plotly.js/issues/6156 for details
		*/
  let config = {
    // If this is popped out, we ignore the original width/height
    width: (CONTAINER.isPoppedOut() ? undefined : original_width) ?? plot_size.width,
    height: (CONTAINER.isPoppedOut() ? undefined : original_height) ?? plot_size.height,
    plutoresize: true,
  };
  Plotly.relayout(PLOT, config).then(() => {
    if (remove_container_size && !CONTAINER.isPoppedOut()) {
      // This is needed to avoid the first resize upon plot creation to already be without a fixed height
      CONTAINER.style.height = "";
      CONTAINER.style.width = "";
      remove_container_size = false;
    }
  });
});

resizeObserver.observe(CONTAINER);


Plotly.react(PLOT, plot_obj).then(() => {
	// Assign the Plotly event listeners
	for (const [key, listener_vec] of Object.entries(plotly_listeners)) {
		for (const listener of listener_vec) {
			PLOT.on(key, listener)
		}
	}
	// Assign the JS event listeners
	for (const [key, listener_vec] of Object.entries(js_listeners)) {
		for (const listener of listener_vec) {
			PLOT.addEventListener(key, listener, {
				signal: controller.signal
			})
		}
	}
}
)


invalidation.then(() => {
	// Remove all plotly listeners
	PLOT.removeAllListeners()
	// Remove all JS listeners
	controller.abort()
	// Remove the resizeObserver
	resizeObserver.disconnect()
})



		return CONTAINER
	</script>
</td></tr></table>
</div>mimetext/htmlrootassigneelast_run_timestampA(Npersist_js_state·has_pluto_hook_features§cell_id$f9bc84ff-c2f9-4ac2-b2ce-34dfcf837a73depends_on_disabled_cells§runtimeΜIpublished_object_keys5c6e0de0c-3901-11f0-234e-bd09c571f662/10b6971fa80c859d5c6e0de0c-3901-11f0-234e-bd09c571f662/1c437dfc407d89165c6e0de0c-3901-11f0-234e-bd09c571f662/7b3f5adc32cbaebf5c6e0de0c-3901-11f0-234e-bd09c571f662/acf9294267fab534depends_on_skipped_cells§errored$8f38a3e9-1872-4ea6-9a03-87112af4bf07queued¤logsrunning¦outputbody1sampleracepolicy (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA/persist_js_state·has_pluto_hook_features§cell_id$8f38a3e9-1872-4ea6-9a03-87112af4bf07depends_on_disabled_cells§runtime Kpublished_object_keysdepends_on_skipped_cells§errored$627d5aa3-974f-4949-8b65-9500eba1d7ccqueued¤logsrunning¦outputbody+figure_5_2 (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA&Fpersist_js_state·has_pluto_hook_features§cell_id$627d5aa3-974f-4949-8b65-9500eba1d7ccdepends_on_disabled_cells§runtimeMApublished_object_keysdepends_on_skipped_cells§errored$02dd1e77-2a7e-4123-94db-d17b31a8b15aqueued¤logsrunning¦outputbodyprefixBlackjackStateelementssum13text/plainupcard2text/plainuatruetext/plaintypestructprefix_shortBlackjackStateobjectida2f2eb542cb25fd2mime!application/vnd.pluto.tree+objectrootassigneeconst blackjack_state1last_run_timestampA)Npersist_js_state·has_pluto_hook_features§cell_id$02dd1e77-2a7e-4123-94db-d17b31a8b15adepends_on_disabled_cells§runtime 7published_object_keysdepends_on_skipped_cells§errored$09b67730-39e7-4209-8117-6bc3adfb342aqueued¤logsrunning¦outputbody<div class="markdown"><p class="tex">$$\begin&#123;flalign&#125;
	&amp;&#61;0.1 \sum_&#123;N&#61;1&#125;^\infty \left &#40; \frac&#123;1&#125;&#123;2&#125; \right &#41; ^N 0.9^&#123;N-1&#125; \left &#40; \frac&#123;\sum_&#123;i&#61;1&#125;^N 2^i&#125;&#123;N&#125; \right &#41; ^2 \\
	&amp;&#61;\frac&#123;0.1&#125;&#123;0.9&#125; \sum_&#123;N&#61;1&#125;^\infty 0.45^&#123;N&#125; N^&#123;-2&#125; \left &#40; \sum_&#123;i&#61;1&#125;^N 2^i \right &#41; ^2 \\
\end&#123;flalign&#125;$$</p>
<p>Consider the term: <span class="tex">$\left &#40; \sum_&#123;i&#61;1&#125;^N 2^i \right &#41; ^2 &#61; &#40;2 &#43; 2^2 &#43; 2^3 &#43; \cdots &#43; 2^N&#41;^2 \gt 2^&#123;2N&#125;$</span> since all the other terms in the parentheses are positive.</p>
<p class="tex">$$\begin&#123;flalign&#125;
	&amp;\gt\frac&#123;0.1&#125;&#123;0.9&#125; \sum_&#123;N&#61;1&#125;^\infty 0.45^&#123;N&#125; N^&#123;-2&#125; 2^&#123;2N&#125; \\
	&amp;&#61; \frac&#123;0.1&#125;&#123;0.9&#125; \sum_&#123;N&#61;1&#125;^\infty 0.45^&#123;N&#125; N^&#123;-2&#125; 4^&#123;N&#125; \\
	&amp;&#61; \frac&#123;0.1&#125;&#123;0.9&#125; \sum_&#123;N&#61;1&#125;^\infty \frac&#123;1.8^&#123;N&#125;&#125;&#123;N^&#123;2&#125;&#125; \\
\end&#123;flalign&#125;$$</p>
<p>The question is then reduced to whether the following infinite sum diverges: <span class="tex">$\sum_&#123;N&#61;1&#125;^\infty \frac&#123;1.8^&#123;N&#125;&#125;&#123;N^&#123;2&#125;&#125;$</span>.  Consider the logarithm of each term in the series <span class="tex">$\log &#123;\frac&#123;1.8^N&#125;&#123;N^2&#125;&#125; &#61; \log&#123;1.8^N&#125; - \log&#123;N^2&#125; &#61; N \log&#123;1.8&#125; - 2 \log&#123;N&#125;$</span>.  As N approaches infinity <span class="tex">$N \gt \log&#123;N&#125;$</span> so the log of each term diverges as do the terms individually as does the series.  Therefore the variance diverges with ever-visit MC as it does with first visit MC.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA"(װpersist_js_state·has_pluto_hook_features§cell_id$09b67730-39e7-4209-8117-6bc3adfb342adepends_on_disabled_cells§runtime ëpublished_object_keysdepends_on_skipped_cells§errored$b7dfc031-6bf6-44cd-b814-05f693a0a27dqueued¤logsrunning¦outputbodyڴ	<div style = "display: flex;">
	<div>
Race finished in 65 steps
<div style="background-color: white; color: black;">
	<div style="display:flex; align-items: flex-start">
	<div class = "track">
		<div class = "start" style="grid-column-start: 4; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "-1" dvy = "0" style="grid-column-start: 8; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "0" dvy = "1" style="grid-column-start: 9; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "1" dvy = "0" style="grid-column-start: 6; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "1" dvy = "-1" style="grid-column-start: 7; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "-1" dvy = "0" style="grid-column-start: 5; grid-row-start: 1;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 27;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "0" style="grid-column-start: 9; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 18;"></div><div class = "" vx = "1" vy = "0" dvx = "0" dvy = "-1" style="grid-column-start: 10; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 11;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "-1" style="grid-column-start: 7; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 13;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "0" style="grid-column-start: 8; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 7;"></div><div class = "" vx = "1" vy = "4" dvx = "-1" dvy = "-1" style="grid-column-start: 8; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 25;"></div><div class = "" vx = "1" vy = "0" dvx = "1" dvy = "-1" style="grid-column-start: 12; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 26;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "0" style="grid-column-start: 6; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 30;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "1" style="grid-column-start: 6; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 3;"></div><div class = "" vx = "0" vy = "4" dvx = "1" dvy = "1" style="grid-column-start: 8; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 9;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "1" style="grid-column-start: 8; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 25;"></div><div class = "" vx = "1" vy = "2" dvx = "-1" dvy = "0" style="grid-column-start: 6; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 20;"></div><div class = "" vx = "0" vy = "3" dvx = "1" dvy = "0" style="grid-column-start: 8; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 31;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "-1" style="grid-column-start: 9; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 31;"></div><div class = "" vx = "1" vy = "0" dvx = "0" dvy = "0" style="grid-column-start: 11; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 21;"></div><div class = "" vx = "1" vy = "3" dvx = "-1" dvy = "-1" style="grid-column-start: 9; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 27;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "0" style="grid-column-start: 5; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 7;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "1" style="grid-column-start: 9; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 21;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "0" style="grid-column-start: 8; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 24;"></div><div class = "" vx = "2" vy = "0" dvx = "1" dvy = "-1" style="grid-column-start: 14; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 32;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "-1" style="grid-column-start: 9; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 19;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "-1" style="grid-column-start: 8; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 14;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "1" style="grid-column-start: 5; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 8;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "1" style="grid-column-start: 8; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 16;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "1" style="grid-column-start: 9; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 7;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "1" style="grid-column-start: 8; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 15;"></div><div class = "" vx = "1" vy = "3" dvx = "0" dvy = "1" style="grid-column-start: 7; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 29;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "1" style="grid-column-start: 8; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 31;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "-1" style="grid-column-start: 8; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 16;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "1" style="grid-column-start: 8; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 28;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 28;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 29;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 31;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 30;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 27;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 32;"></div>
	</div>
	Finish <br> line
	</div>
	<div>Starting line</div>
</div>
</div>

	<div>
Race finished in 200 steps
<div style="background-color: white; color: black;">
	<div style="display:flex; align-items: flex-start">
	<div class = "track">
		<div class = "start" vx = "0" vy = "0" dvx = "-1" dvy = "0" style="grid-column-start: 4; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "-1" dvy = "0" style="grid-column-start: 8; grid-row-start: 1;"></div><div class = "start" vx = "1" vy = "0" dvx = "0" dvy = "1" style="grid-column-start: 9; grid-row-start: 1;"></div><div class = "start" vx = "1" vy = "0" dvx = "1" dvy = "-1" style="grid-column-start: 6; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "1" dvy = "-1" style="grid-column-start: 7; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "-1" dvy = "0" style="grid-column-start: 5; grid-row-start: 1;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 27;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "0" style="grid-column-start: 9; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 18;"></div><div class = "" vx = "1" vy = "0" dvx = "0" dvy = "-1" style="grid-column-start: 10; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 11;"></div><div class = "" vx = "2" vy = "1" dvx = "-1" dvy = "-1" style="grid-column-start: 7; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 13;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "0" style="grid-column-start: 8; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 7;"></div><div class = "" vx = "1" vy = "4" dvx = "-1" dvy = "-1" style="grid-column-start: 8; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 25;"></div><div class = "" vx = "1" vy = "0" dvx = "1" dvy = "-1" style="grid-column-start: 12; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 26;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "0" style="grid-column-start: 6; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 30;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "1" style="grid-column-start: 6; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 3;"></div><div class = "" vx = "0" vy = "4" dvx = "1" dvy = "1" style="grid-column-start: 8; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 9;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "1" style="grid-column-start: 8; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 25;"></div><div class = "" vx = "1" vy = "2" dvx = "-1" dvy = "0" style="grid-column-start: 6; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 20;"></div><div class = "" vx = "0" vy = "3" dvx = "1" dvy = "0" style="grid-column-start: 8; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 31;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "-1" style="grid-column-start: 9; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 31;"></div><div class = "" vx = "1" vy = "0" dvx = "0" dvy = "0" style="grid-column-start: 11; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 21;"></div><div class = "" vx = "1" vy = "3" dvx = "-1" dvy = "-1" style="grid-column-start: 9; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 27;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "0" style="grid-column-start: 5; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 7;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "1" style="grid-column-start: 9; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 21;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "0" style="grid-column-start: 8; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 24;"></div><div class = "" vx = "2" vy = "0" dvx = "1" dvy = "-1" style="grid-column-start: 14; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 32;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "-1" style="grid-column-start: 9; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 19;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "-1" style="grid-column-start: 8; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 14;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "1" style="grid-column-start: 5; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 8;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "1" style="grid-column-start: 8; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 16;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "1" style="grid-column-start: 9; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 7;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "1" style="grid-column-start: 8; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 15;"></div><div class = "" vx = "1" vy = "3" dvx = "0" dvy = "1" style="grid-column-start: 7; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 29;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "1" style="grid-column-start: 8; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 31;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "-1" style="grid-column-start: 8; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 10;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "-1" style="grid-column-start: 4; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 16;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "1" style="grid-column-start: 8; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 28;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 28;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 29;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 31;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 30;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 27;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 32;"></div>
	</div>
	Finish <br> line
	</div>
	<div>Starting line</div>
</div>
</div>

	</div>
mimetext/htmlrootassigneelast_run_timestampA3persist_js_state·has_pluto_hook_features§cell_id$b7dfc031-6bf6-44cd-b814-05f693a0a27ddepends_on_disabled_cells§runtime -published_object_keysdepends_on_skipped_cells§errored$2572e35c-e6a3-4562-aa0f-6a5ab32d39eaqueued¤logsrunning¦outputbody		<div style="display: flex; flex-direction: row; align-items: flex-start; justify-content: center; background-color: rgb(100, 100, 100)">
	
	<div class="backup">
		<div>State Value Function</div>
		<div class="circlestate"></div>
		<div class="arrow"></div>
		<div class="circleaction"></div>
		<div class="arrow"></div>
		<div class="circlestate"></div>
		<div class="arrow"></div>
		<div class="circleaction"></div>
		<div style = "color: black; font-size: 30px;">&#8942;</div>
		<div class="circleaction"></div>
		<div class="arrow"></div>
		<div class="term"></div>
	</div>
	<div class="backup">
		<div>State Action Value Function</div>
		<div class="circleaction"></div>
		<div class="arrow"></div>
		<div class="circlestate"></div>
		<div class="arrow"></div>
		<div class="circleaction"></div>
		<div class="arrow"></div>
		<div class="circlestate"></div>
		<div style = "color: black; font-size: 30px;">&#8942;</div>
		<div class="circlestate"></div>
		<div class="arrow"></div>
		<div class="circleaction"></div>
		<div class="arrow"></div>
		<div class="term"></div>
	</div>
	<div>
		<div class="q_backup"></div>
	</div>
</div>

<style>

	.backup {
		margin: 5px;
	}
	.backup, .backup * {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		color: black;
	}
	.circlestate, .circleaction {
		margin: 0;
	}
	.circlestate::before {
		content: '';
		display: inline-block;
		border: 1px solid black;
		border-radius: 50%;
		height: 20px;
		width: 20px;
		background-color: white;
	}
	.circleaction::before {
		content: '';
		display: inline-block;
		border: 1px solid black;
		border-radius: 50%;
		height: 10px;
		width: 10px;
		background-color: black;
	}
	.arrow {
		display: flex;
		justify-content: center;
		align-items: center;
	}
	.arrow::before {
		content: '';
		display: inline-block;
		width: 2px;
		height: 30px;
		background-color: black;
		margin-bottom: 0px;
	}
	.arrow::after {
		content: '';
		display: inline-block;
		width: 4px;
		height: 4px;
		border-bottom: 3px solid black;
		border-right: 3px solid black;
		transform: translateY(-5px) rotate(45deg);
		position: relative;
	}
	.term::before {
		content: '';
		display: inline-block;
		width: 20px;
		height: 20px;
		border: 2px solid black;
		background-color: rgb(50, 50, 50);
	}
</style>
mimetext/htmlrootassigneelast_run_timestampA%ypersist_js_state·has_pluto_hook_features§cell_id$2572e35c-e6a3-4562-aa0f-6a5ab32d39eadepends_on_disabled_cells§runtime 8published_object_keysdepends_on_skipped_cells§errored$859354fe-7f40-4658-bf12-b5ee20a815a7queued¤logsrunning¦outputbodyO<div class="markdown"><h2>5.8 Discounting-aware Importance Sampling</h2>
</div>mimetext/htmlrootassigneelast_run_timestampA"+"persist_js_state·has_pluto_hook_features§cell_id$859354fe-7f40-4658-bf12-b5ee20a815a7depends_on_disabled_cells§runtime :published_object_keysdepends_on_skipped_cells§errored$f9f6c182-62f8-4a5a-8b43-8716db468427queued¤logsrunning¦outputbody5.656854249492381mimetext/plainrootassigneeconst maxspeedlast_run_timestampA/0̰persist_js_state·has_pluto_hook_features§cell_id$f9f6c182-62f8-4a5a-8b43-8716db468427depends_on_disabled_cells§runtimeq:published_object_keysdepends_on_skipped_cells§errored$47daf83b-8fe9-4491-b9ae-84bd269d5546queued¤logsrunning¦outputbody=<div class="markdown"><h2>5.3 Monte Carlo Control</h2>
</div>mimetext/htmlrootassigneelast_run_timestampA"&persist_js_state·has_pluto_hook_features§cell_id$47daf83b-8fe9-4491-b9ae-84bd269d5546depends_on_disabled_cells§runtime %published_object_keysdepends_on_skipped_cells§errored$ba8a5804-4be3-43fe-95d7-c957ce02a1d4queued¤logsrunning¦outputbody2make_action_style (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA0 persist_js_state·has_pluto_hook_features§cell_id$ba8a5804-4be3-43fe-95d7-c957ce02a1d4depends_on_disabled_cells§runtime 	Ypublished_object_keysdepends_on_skipped_cells§errored$481ad435-cc80-4164-882d-8310b010ca91queued¤logsrunning¦outputbody=make_simple_blackjack_policy (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA%<bpersist_js_state·has_pluto_hook_features§cell_id$481ad435-cc80-4164-882d-8310b010ca91depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$8bcaa31b-8caf-43da-83a0-47e0c04c2a30queued¤logsrunning¦outputbody<div style="display: flex; justify-content: space-around;">
<div>Track 1</div>
<div>Track 2</div>
</div>
<div style="display: flex; justify-content: space-between; align-items: flex-end; background-color: gray;">
<div>

<div style="background-color: white; color: black;">
	<div style="display:flex; align-items: flex-start">
	<div class = "track">
		<div class = "start" style="grid-column-start: 4; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 8; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 9; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 6; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 7; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 5; grid-row-start: 1;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 28;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 28;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 29;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 31;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 30;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 27;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 32;"></div>
	</div>
	Finish <br> line
	</div>
	<div>Starting line</div>
</div>
</div>

<div>

<div style="background-color: white; color: black;">
	<div style="display:flex; align-items: flex-start">
	<div class = "track">
		<div class = "start" style="grid-column-start: 8; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 5; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 14; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 16; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 3; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 11; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 19; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 22; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 6; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 17; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 21; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 13; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 9; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 18; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 2; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 20; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 1; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 23; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 7; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 12; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 10; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 15; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 4; grid-row-start: 1;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 27;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 30;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 27;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 23;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 28;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 29;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 26;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 25;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 24;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 22;"></div>
	</div>
	Finish <br> line
	</div>
	<div>Starting line</div>
</div>
</div>

</div>
mimetext/htmlrootassigneelast_run_timestampA0?2persist_js_state·has_pluto_hook_features§cell_id$8bcaa31b-8caf-43da-83a0-47e0c04c2a30depends_on_disabled_cells§runtimes̵published_object_keysdepends_on_skipped_cells§errored$7c9486cd-1916-4e13-b415-fb113bd9e04bqueued¤logsrunning¦outputbodyH<div class="markdown"><h2>5.7 Off-policy Monte Carlo Control</h2>
</div>mimetext/htmlrootassigneelast_run_timestampA")8persist_js_state·has_pluto_hook_features§cell_id$7c9486cd-1916-4e13-b415-fb113bd9e04bdepends_on_disabled_cells§runtime Ppublished_object_keysdepends_on_skipped_cells§errored$821ce23a-524b-4203-96d6-4d5b454fe1fdqueued¤logsrunning¦outputbodym~<div class="markdown"><p>Statistics for Steps to Finish Race on Track 2</p>

<table><tr><th align="right">Statistic</th><th align="right"><div class="markdown"><p>Monte Carlo ϵ-Soft</p>
</div></th><th align="right">Random Policy</th></tr><tr><td align="right">Mean</td><td align="right">24</td><td align="right">288</td></tr><tr><td align="right">Median</td><td align="right">18</td><td align="right">202</td></tr><tr><td align="right">Std</td><td align="right">16</td><td align="right">273</td></tr><tr><td align="right">Minimum</td><td align="right">9</td><td align="right">12</td></tr><tr><td align="right">Maximum</td><td align="right">113</td><td align="right">1782</td></tr></table>
<p>Cummulative Distribution Function of Steps to Finish Race 	<script id='plot_1'>
		// We start by putting all the variable interpolation here at the beginning
		// We have to convert all typedarrays in the layout to normal arrays. See Issue #25
		// We use lodash for this for compactness
		function removeTypedArray(o) {
			return _.isTypedArray(o) ? Array.from(o) :
			_.isPlainObject(o) ? _.mapValues(o, removeTypedArray) : 
			o
		}

		// Publish the plot object to JS
		let plot_obj = _.update(/* See the documentation for AbstractPlutoDingetjes.Display.published_to_js */ getPublishedObject("c6e0de0c-3901-11f0-234e-bd09c571f662/47097f3aa74a6daf"), "layout", removeTypedArray)
		// Get the plotly listeners
		const plotly_listeners = {}
		// Get the JS listeners
		const js_listeners = {}
		// Deal with eventual custom classes
		let custom_classlist = []


		// Load the plotly library
		let Plotly = undefined
		try {
			let _mod = await import("./plotlyjs/plotlyjs-2.26.2.min.js")
			Plotly = _mod.default
		} catch (e) {
			console.log("Local load failed, trying with the web esm.sh version")
			let _mod = await import("https://esm.sh/plotly.js-dist-min@2.26.2/es2022/plotly.js-dist-min.mjs")
			Plotly = _mod.default
		}

		// Check if we have to force local mathjax font cache
		if (false && window?.MathJax?.config?.svg?.fontCache === 'global') {
			window.MathJax.config.svg.fontCache = 'local'
		}

		// Flag to check if this cell was  manually ran or reactively ran
const firstRun = this ? false : true
const CONTAINER = this ?? html`<div class='plutoplotly-container'>`
const PLOT = CONTAINER.querySelector('.js-plotly-plot') ?? CONTAINER.appendChild(html`<div>`)
const parent = CONTAINER.parentElement
// We use a controller to remove event listeners upon invalidation
const controller = new AbortController()
// We have to add this to keep supporting @bind with the old API using PLOT
PLOT.addEventListener('input', (e) => {
	CONTAINER.value = PLOT.value
	if (e.bubbles) {
		return
	}
	CONTAINER.dispatchEvent(new CustomEvent('input'))
}, { signal: controller.signal })

	// This create the style subdiv on first run
	firstRun && CONTAINER.appendChild(html`
	<style>
	.plutoplotly-container {
		width: 100%;
		height: 100%;
		min-height: 0;
		min-width: 0;
	}
	.plutoplotly-container .js-plotly-plot .plotly div {
		margin: 0 auto; // This centers the plot
	}
	.plutoplotly-container.popped-out {
		overflow: auto;
		z-index: 1000;
		position: fixed;
		resize: both;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		border-top-left-radius: 0px;
		border-top-right-radius: 0px;
	}
	.plutoplotly-clipboard-header {
		display: flex;
		flex-flow: row wrap;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-top-left-radius: 12px;
		border-top-right-radius: 12px;
		position: fixed;
		z-index: 1001;
		cursor: move;
		transform: translate(0px, -100%);
		padding: 5px;
	}
	.plutoplotly-clipboard-header span {
		display: inline-block;
		flex: 1
	}
	.plutoplotly-clipboard-header.hidden {
		display: none;
	}
	.clipboard-span {
		position: relative;
	}
	.clipboard-value {
		padding-right: 5px;
		padding-left: 2px;
		cursor: text;
	}
	.clipboard-span.format {
		display: none;
	}
	.clipboard-span.filename {
		flex: 0 0 100%;
		text-align: center;
		border-top: 3px solid var(--kbd-border-color);
		margin-top: 5px;
		display: none;
	}
	.plutoplotly-container.filesave .clipboard-span.filename {
		display: inline-block;
	}
	.clipboard-value.filename {
		margin-left: 3px;
		text-align: left;
		min-width: min(60%, min-content);
	}
	.plutoplotly-container.filesave .clipboard-span.format {
		display: inline-flex;
	}
	.clipboard-span.format .label {
		flex: 0 0 0;
	}
	.clipboard-value.format {
		position: relative;
		flex: 1 0 auto;
		min-width: 30px;
		margin-right: 10px;
	}
	div.format-options {
		display: inline-flex;
		flex-flow: column;
		position: absolute;
		background: var(--main-bg-color);
		border-radius: 12px;
		padding-left: 3px;
		z-index: 2000;
	}
	div.format-options:hover {
		cursor: pointer;
		border: 3px solid var(--kbd-border-color);
		padding: 3px;
		transform: translate(-3px, -6px);
	}
	div.format-options .format-option {
		display: none;
	}
	div.format-options:hover .format-option {
		display: inline-block;
	}
	.format-option:not(.selected) {
		margin-top: 3px;
	}
	div.format-options .format-option.selected {
		order: -1;
		display: inline-block;
	}
	.format-option:hover {
		background-color: var(--kbd-border-color);
	}
	span.config-value {
		font-weight: normal;
		color: var(--pluto-output-color);
		display: none;
		position: absolute;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		transform: translate(0px, calc(-100% - 10px));
		padding: 5px;
	}
	.label {
		user-select: none;
	}
	.label:hover span.config-value {
		display: inline-block;
		min-width: 150px;
	}
	.clipboard-span.matching-config .label {
		color: var(--cm-macro-color);
		font-weight: bold;
	}
	.clipboard-span.different-config .label {
		color: var(--cm-tag-color);
		font-weight: bold;
	}
</style>
`)

let original_height = plot_obj.layout.height
let original_width = plot_obj.layout.width
// For the height we have to also put a fixed value in case the plot is put on a non-fixed-size container (like the default wrapper)
// We define a variable to check whether we still have to remove the fixed height
let remove_container_size = firstRun
let container_height = original_height ?? PLOT.container_height ?? 400
CONTAINER.style.height = container_height + 'px'

// We create a Promise version of setTimeout
function delay(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

// We import interact for dragging/resizing
const { default: interact } = await import('https://esm.sh/interactjs@1.10.19')


function getImageOptions() {
  const o = plot_obj.config.toImageButtonOptions ?? {};
  return {
    format: o.format ?? "png",
    width: o.width ?? original_width,
    height: o.height ?? original_height,
    scale: o.scale ?? 1,
    filename: o.filename ?? "newplot",
  };
}

const CLIPBOARD_HEADER =
  CONTAINER.querySelector(".plutoplotly-clipboard-header") ??
  CONTAINER.insertAdjacentElement(
    "afterbegin",
    html`<div class="plutoplotly-clipboard-header hidden">
      <span class="clipboard-span format"
        ><span class="label">Format:</span
        ><span class="clipboard-value format"></span
      ></span>
      <span class="clipboard-span width"
        ><span class="label">Width:</span
        ><span class="clipboard-value width"></span>px</span
      >
      <span class="clipboard-span height"
        ><span class="label">Height:</span
        ><span class="clipboard-value height"></span>px</span
      >
      <span class="clipboard-span scale"
        ><span class="label">Scale:</span
        ><span class="clipboard-value scale"></span
      ></span>
      <button class="clipboard-span set">Set</button>
      <button class="clipboard-span unset">Unset</button>
      <span class="clipboard-span filename"
        ><span class="label">Filename:</span
        ><span class="clipboard-value filename"></span
      ></span>
    </div>`
  );

function checkConfigSync(container) {
  const valid_classes = [
    "missing-config",
    "matching-config",
    "different-config",
  ];
  function setClass(cl) {
    for (const name of valid_classes) {
      container.classList.toggle(name, name == cl);
    }
  }
  // We use the custom getters we'll set up in the container
  const { ui_value, config_value, config_span, key } = container;
  if (config_value === undefined) {
    setClass("missing-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> is not present in the config.`;
  } else if (ui_value == config_value) {
    setClass("matching-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has the same value in the config and in the header.`;
  } else {
    setClass("different-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has a different value (<em>${config_value}</em>) in the config.`;
  }
  // Add info about setting and unsetting
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click on the label <em><b>once</b></em> to set the current UI value in the config.`
  );
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click <em><b>twice</b></em> to remove this key from the config.`
  );
}

const valid_formats = ["png", "svg", "webp", "jpeg", "full-json"];
function initializeUIValueSpan(span, key, value) {
  const container = span.closest(".clipboard-span");
  span.contentEditable = key === "format" ? "false" : "true";
  let parse = (x) => x;
  let update = (x) => (span.textContent = x);
  if (key === "width" || key === "height") {
    parse = (x) => Math.round(parseFloat(x));
  } else if (key === "scale") {
    parse = parseFloat;
  } else if (key === "format") {
    // We remove contentEditable
    span.contentEditable = "false";
    // Here we first add the subspans for each option
    const opts_div = span.appendChild(html`<div class="format-options"></div>`);
    for (const fmt of valid_formats) {
      const opt = opts_div.appendChild(
        html`<span class="format-option ${fmt}">${fmt}</span>`
      );
      opt.onclick = (e) => {
        span.value = opt.textContent;
      };
    }
    parse = (x) => {
      return valid_formats.includes(x) ? x : localValue;
    };
    update = (x) => {
      for (const opt of opts_div.children) {
        opt.classList.toggle("selected", opt.textContent === x);
      }
    };
  } else {
    // We only have filename here
  }
  let localValue;
  Object.defineProperty(span, "value", {
    get: () => {
      return localValue;
    },
    set: (val) => {
      if (val !== "") {
        localValue = parse(val);
      }
      update(localValue);
      checkConfigSync(container);
    },
  });
  // We also assign a listener so that the editable is blurred when enter is pressed
  span.onkeydown = (e) => {
    if (e.keyCode === 13) {
      e.preventDefault();
      span.blur();
    }
  };
  span.value = value;
}

function initializeConfigValueSpan(span, key) {
  // Here we mostly want to define the setter and getter
  const container = span.closest(".clipboard-span");
  Object.defineProperty(span, "value", {
    get: () => {
      return plot_obj.config.toImageButtonOptions[key];
    },
    set: (val) => {
      // if undefined is passed, we remove the entry from the options
      if (val === undefined) {
        delete plot_obj.config.toImageButtonOptions[key];
      } else {
        plot_obj.config.toImageButtonOptions[key] = val;
      }
      checkConfigSync(container);
    },
  });
}

const config_spans = {};
for (const [key, value] of Object.entries(getImageOptions())) {
  const container = CLIPBOARD_HEADER.querySelector(`.clipboard-span.${key}`);
  const label = container.querySelector(".label");
  // We give the label a function that on single click will set the current value and with double click will unset it
  label.onclick = DualClick(
    () => {
      container.config_value = container.ui_value;
    },
    (e) => {
      console.log("e", e);
      e.preventDefault();
      container.config_value = undefined;
    }
  );
  const ui_value_span = container.querySelector(".clipboard-value");
  const config_value_span =
    container.querySelector(".config-value") ??
    label.insertAdjacentElement(
      "afterbegin",
      html`<span class="config-value"></span>`
    );
  // Assing the two spans as properties of the containing span
  container.ui_span = ui_value_span;
  container.config_span = config_value_span;
  container.key = key;
  config_spans[key] = container;
  if (firstRun) {
    plot_obj.config.toImageButtonOptions =
      plot_obj.config.toImageButtonOptions ?? {};
    // We do the initialization of the value span
    initializeUIValueSpan(ui_value_span, key, value);
    // Then we initialize the config value
    initializeConfigValueSpan(config_value_span, key);
    // We put some convenience getters/setters
    // ui_value forward
    Object.defineProperty(container, "ui_value", {
      get: () => ui_value_span.value,
      set: (val) => {
        ui_value_span.value = val;
      },
    });
    // config_value forward
    Object.defineProperty(container, "config_value", {
      get: () => config_value_span.value,
      set: (val) => {
        config_value_span.value = val;
      },
    });
  }
}

// These objects will contain the default value

// This code updates the image options in the PLOT config with the provided ones
function setImageOptions(o) {
  for (const [key, container] of Object.entries(config_spans)) {
    container.config_value = o[key];
  }
}
function unsetImageOptions() {
  setImageOptions({});
}

const set_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.set");
const unset_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.unset");
if (firstRun) {
  set_button.onclick = (e) => {
    for (const container of Object.values(config_spans)) {
      container.config_value = container.ui_value;
    }
  };
  unset_button.onclick = unsetImageOptions;
}

// We add a function to check if the clipboard is popped out
CONTAINER.isPoppedOut = () => {
  return CONTAINER.classList.contains("popped-out");
};

CLIPBOARD_HEADER.onmousedown = function (event) {
  if (event.target.matches("span.clipboard-value")) {
    console.log("We don't move!");
    return;
  }
  const start = {
    left: parseFloat(CONTAINER.style.left),
    top: parseFloat(CONTAINER.style.top),
    X: event.pageX,
    Y: event.pageY,
  };
  function moveAt(event, start) {
    const top = event.pageY - start.Y + start.top + "px";
    const left = event.pageX - start.X + start.left + "px";
    CLIPBOARD_HEADER.style.left = left;
    CONTAINER.style.left = left;
    CONTAINER.style.top = top;
  }

  // move our absolutely positioned ball under the pointer
  moveAt(event, start);
  function onMouseMove(event) {
    moveAt(event, start);
  }

  // We use this to remove the mousemove when clicking outside of the container
  const controller = new AbortController();

  // move the container on mousemove
  document.addEventListener("mousemove", onMouseMove, {
    signal: controller.signal,
  });
  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        cleanUp();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );

  function cleanUp() {
    console.log("cleaning up the plot move listener");
    controller.abort();
    CLIPBOARD_HEADER.onmouseup = null;
  }

  // (3) drop the ball, remove unneeded handlers
  CLIPBOARD_HEADER.onmouseup = cleanUp;
};

function sendToClipboard(blob) {
  if (!navigator.clipboard) {
    alert(
      "The Clipboard API does not seem to be available, make sure the Pluto notebook is being used from either localhost or an https source."
    );
  }
  navigator.clipboard
    .write([
      new ClipboardItem({
        // The key is determined dynamically based on the blob's type.
        [blob.type]: blob,
      }),
    ])
    .then(
      function () {
        console.log("Async: Copying to clipboard was successful!");
      },
      function (err) {
        console.error("Async: Could not copy text: ", err);
      }
    );
}

function copyImageToClipboard() {
  // We extract the image options from the provided parameters (if they exist)
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key. We also ignore format because the clipboard only supports png.
    if (val === undefined || key === "format") {
      continue;
    }
    config[key] = val;
  }
  Plotly.toImage(PLOT, config).then(function (dataUrl) {
    fetch(dataUrl)
      .then((res) => res.blob())
      .then((blob) => {
        const paste_receiver = document.querySelector('paste-receiver.plutoplotly')
        if (paste_receiver) {
          paste_receiver.attachImage(dataUrl, CONTAINER)
        }
        sendToClipboard(blob)
      });
  });
}

function saveImageToFile() {
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key.
    if (val === undefined) {
      continue;
    }
    config[key] = val;
  }
  Plotly.downloadImage(PLOT, config);
}

let container_rect = { width: 0, height: 0, top: 0, left: 0 };
function unpop_container(cl) {
  CONTAINER.classList.toggle("popped-out", false);
  CONTAINER.classList.toggle(cl, false);
  // We fix the height back to the value it had before popout, also setting the flag to signal that upon first resize we remove the fixed inline-style
  CONTAINER.style.height = container_rect.height + "px";
  remove_container_size = true;
  // We set the other fixed inline-styles to null
  CONTAINER.style.width = "";
  CONTAINER.style.top = "";
  CONTAINER.style.left = "";
  // We also remove the CLIPBOARD_HEADER
  CLIPBOARD_HEADER.style.width = "";
  CLIPBOARD_HEADER.style.left = "";
  // Finally we remove the hidden class to the header
  CLIPBOARD_HEADER.classList.toggle("hidden", true);
  return;
}
function popout_container(opts) {
  const cl = opts?.cl;
  const target_container_size = opts?.target_container_size ?? {};
  const target_plot_size = opts?.target_plot_size ?? {};
  if (CONTAINER.isPoppedOut()) {
    return unpop_container(cl);
  }
  CONTAINER.classList.toggle(cl, cl === undefined ? false : true);
  // We extract the current size of the container, save them and fix them
  const { width, height, top, left } = CONTAINER.getBoundingClientRect();
  container_rect = { width, height, top, left };
  // We save the current plot size before we pop as it will fill the screen
  const current_plot_size = {
    width: PLOT._fullLayout.width,
    height: PLOT._fullLayout.height,
  };
  // We have to save the pad data before popping so we can resize precisely
  const pad = {};
  pad.unpopped = getSizeData().container_pad;
  CONTAINER.classList.toggle("popped-out", true);
  pad.popped = getSizeData().container_pad;
  // We do top and left based on the current rect
  for (const key of ["top", "left"]) {
    const start_val = target_container_size[key] ?? container_rect[key];
    let offset = 0;
    for (const kind of ["padding", "border"]) {
      offset += pad.popped[kind][key] - pad.unpopped[kind][key];
    }
    CONTAINER.style[key] = start_val - offset + "px";
    if (key === "left") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  // We compute the width and height depending on eventual config data
  const csz = computeContainerSize({
    width:
      target_plot_size.width ??
      config_spans.width.config_value ??
      current_plot_size.width,
    height:
      target_plot_size.height ??
      config_spans.height.config_value ??
      current_plot_size.height,
  });
  for (const key of ["width", "height"]) {
    const val = target_container_size[key] ?? csz[key];
    CONTAINER.style[key] = val + "px";
    if (key === "width") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  CLIPBOARD_HEADER.classList.toggle("hidden", false);
  const controller = new AbortController();

  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        unpop_container();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );
}

CONTAINER.popOut = popout_container;

function DualClick(single_func, dbl_func) {
  let nclicks = 0;
  return function (...args) {
    nclicks += 1;
    if (nclicks > 1) {
      dbl_func(...args);
      nclicks = 0;
    } else {
      delay(300).then(() => {
        if (nclicks == 1) {
          single_func(...args);
        }
        nclicks = 0;
      });
    }
  };
}

// We remove the default download image button
plot_obj.config.modeBarButtonsToRemove = _.union(
  plot_obj.config.modeBarButtonsToRemove,
  ["toImage"]
);
// We add the custom button to the modebar
plot_obj.config.modeBarButtonsToAdd = _.union(
  plot_obj.config.modeBarButtonsToAdd,
  [
    {
      name: "Copy PNG to Clipboard",
      icon: {
        height: 520,
        width: 520,
        path: "M280 64h40c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128C0 92.7 28.7 64 64 64h40 9.6C121 27.5 153.3 0 192 0s71 27.5 78.4 64H280zM64 112c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16H320c8.8 0 16-7.2 16-16V128c0-8.8-7.2-16-16-16H304v24c0 13.3-10.7 24-24 24H192 104c-13.3 0-24-10.7-24-24V112H64zm128-8a24 24 0 1 0 0-48 24 24 0 1 0 0 48z",
      },
      direction: "up",
      click: DualClick(copyImageToClipboard, () => {
        popout_container();
      }),
    },
    {
      name: "Download Image",
      icon: Plotly.Icons.camera,
      direction: "up",
      click: DualClick(saveImageToFile, () => {
        popout_container({ cl: "filesave" });
      }),
    },
  ]
);

function getOffsetData(el) {
  let cs = window.getComputedStyle(el, null);
  const odata = {
    padding: {
      left: parseFloat(cs.paddingLeft),
      right: parseFloat(cs.paddingRight),
      top: parseFloat(cs.paddingTop),
      bottom: parseFloat(cs.paddingBottom),
      width: parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight),
      height: parseFloat(cs.paddingTop) + parseFloat(cs.paddingBottom),
    },
    border: {
      left: parseFloat(cs.borderLeftWidth),
      right: parseFloat(cs.borderRightWidth),
      top: parseFloat(cs.borderTopWidth),
      bottom: parseFloat(cs.borderBottomWidth),
      width: parseFloat(cs.borderLeftWidth) + parseFloat(cs.borderRightWidth),
      height: parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth),
    }
  };
  if (el === PLOT) {
    // For the PLOT we also want to take into account the offset
    odata.offset = {
      top: PLOT.offsetParent == CONTAINER ? PLOT.offsetTop : 0,
      left: PLOT.offsetParent == CONTAINER ? PLOT.offsetLeft : 0,
    }
  }
  return odata;
}
function getSizeData() {
  const data = {
    plot_pad: getOffsetData(PLOT),
    plot_rect: PLOT.getBoundingClientRect(),
    container_pad: getOffsetData(CONTAINER),
    container_rect: CONTAINER.getBoundingClientRect(),
  };
  return data;
}
function computeContainerSize({ width, height }, sizeData = getSizeData()) {
  const computed_size = computePlotSize(sizeData);
  const offsets = computed_size.offsets;

  const plot_data = {
    width: width ?? computed_size.width,
    height: height ?? computed_size.height,
  };

  return {
    width: (width ?? computed_size.width) + offsets.width,
    height: (height ?? computed_size.height) + offsets.height,
    noChange: width == computed_size.width && height == computed_size.height,
  }
}

// This function will change the container size so that the resulting plot will be matching the provided specs
function changeContainerSize({ width, height }, sizeData = getSizeData()) {
  if (!CONTAINER.isPoppedOut()) {
    console.log("Tried to change container size when not popped, ignoring");
    return;
  }

  const csz = computeContainerSize({ width, height }, sizeData);

  if (csz.noChange) {
    console.log("Size is the same as current, ignoring");
    return
  }
  // We are now going to set he width and height of the container
  for (const key of ["width", "height"]) {
    CONTAINER.style[key] = csz[key] + "px";
  }
}
// We now create the function that will update the plot based on the values specified
function updateFromHeader() {
  const header_data = {
    height: config_spans.height.ui_value,
    width: config_spans.width.ui_value,
  };
  changeContainerSize(header_data);
}
// We assign this function to the onblur event of width and height
if (firstRun) {
  for (const container of Object.values(config_spans)) {
    container.ui_span.onblur = (e) => {
      container.ui_value = container.ui_span.textContent;
      updateFromHeader();
    };
  }
}
// This function computes the plot size to use for relayout as a function of the container size
function computePlotSize(data = getSizeData()) {
  // Remove Padding
  const { container_pad, plot_pad, container_rect } = data;
  const offsets = {
    width:
      plot_pad.padding.width +
      plot_pad.border.width +
      plot_pad.offset.left +
      container_pad.padding.width +
      container_pad.border.width,
    height:
      plot_pad.padding.height +
      plot_pad.border.height +
      plot_pad.offset.top +
      container_pad.padding.height +
      container_pad.border.height,
  };
  const sz = {
    width: Math.round(container_rect.width - offsets.width),
    height: Math.round(container_rect.height - offsets.height),
    offsets,
  };
  return sz;
}

// Create the resizeObserver to make the plot even more responsive! :magic:
const resizeObserver = new ResizeObserver((entries) => {
  const sizeData = getSizeData();
  const {container_rect, container_pad} = sizeData;
  let plot_size = computePlotSize(sizeData);
  // We save the height in the PLOT object
  PLOT.container_height = container_rect.height;
  // We deal with some stuff if the container is poppped
  CLIPBOARD_HEADER.style.width = container_rect.width + "px";
  CLIPBOARD_HEADER.style.left = container_rect.left + "px";
  config_spans.height.ui_value = plot_size.height;
  config_spans.width.ui_value = plot_size.width;
  /* 
		The addition of the invalid argument `plutoresize` seems to fix the problem with calling `relayout` simply with `{autosize: true}` as update breaking mouse relayout events tracking. 
		See https://github.com/plotly/plotly.js/issues/6156 for details
		*/
  let config = {
    // If this is popped out, we ignore the original width/height
    width: (CONTAINER.isPoppedOut() ? undefined : original_width) ?? plot_size.width,
    height: (CONTAINER.isPoppedOut() ? undefined : original_height) ?? plot_size.height,
    plutoresize: true,
  };
  Plotly.relayout(PLOT, config).then(() => {
    if (remove_container_size && !CONTAINER.isPoppedOut()) {
      // This is needed to avoid the first resize upon plot creation to already be without a fixed height
      CONTAINER.style.height = "";
      CONTAINER.style.width = "";
      remove_container_size = false;
    }
  });
});

resizeObserver.observe(CONTAINER);


Plotly.react(PLOT, plot_obj).then(() => {
	// Assign the Plotly event listeners
	for (const [key, listener_vec] of Object.entries(plotly_listeners)) {
		for (const listener of listener_vec) {
			PLOT.on(key, listener)
		}
	}
	// Assign the JS event listeners
	for (const [key, listener_vec] of Object.entries(js_listeners)) {
		for (const listener of listener_vec) {
			PLOT.addEventListener(key, listener, {
				signal: controller.signal
			})
		}
	}
}
)


invalidation.then(() => {
	// Remove all plotly listeners
	PLOT.removeAllListeners()
	// Remove all JS listeners
	controller.abort()
	// Remove the resizeObserver
	resizeObserver.disconnect()
})



		return CONTAINER
	</script>
</p>
</div>mimetext/htmlrootassigneelast_run_timestampA4+persist_js_state·has_pluto_hook_features§cell_id$821ce23a-524b-4203-96d6-4d5b454fe1fddepends_on_disabled_cells§runtimepublished_object_keys5c6e0de0c-3901-11f0-234e-bd09c571f662/47097f3aa74a6dafdepends_on_skipped_cells§errored$dc57a71f-e44c-4385-ad2a-e6c14d5e5201queued¤logsrunning¦outputbody	<div class="markdown"><blockquote>
<h3><em>Exercise 5.14</em></h3>
<p>Modify the algorithm for off-policy Monte Carlo control &#40;page 111&#41; to use the idea of the truncated weighted-average estimator &#40;5.10&#41;.  Note that you will first need to convert this equation to action values.</p>
</blockquote>
<p>Equation &#40;5.10&#41;</p>
<p class="tex">$$V&#40;s&#41; &#61; \frac&#123;\sum_&#123;t \in \mathscr&#123;T&#125;&#40;s&#41;&#125;\left&#40;&#40;1-\gamma&#41;\sum_&#123;h&#61;t&#43;1&#125;^&#123;T&#40;t&#41;-1&#125;\gamma^&#123;h-t-1&#125; \rho_&#123;t:h-1&#125; \bar&#123;G&#125;_&#123;t:h&#125; &#43; \gamma^&#123;T&#40;t&#41;-t-1&#125; \rho_&#123;t:T&#40;t&#41;-1&#125; \bar&#123;G&#125;_&#123;t:T&#40;t&#41;&#125; \right&#41;&#125;&#123;\sum_&#123;t \in \mathscr&#123;T&#125;&#40;s&#41;&#125; \left&#40; &#40;1-\gamma&#41; \sum_&#123;h&#61;t&#43;1&#125;^&#123;T&#40;t&#41;-1&#125; \gamma^&#123;h-t-1&#125; \rho_&#123;t:h-1&#125; &#43; \gamma^&#123;T&#40;t&#41;-t-1&#125; \rho_&#123;t:T&#40;t&#41;-1&#125; \right&#41;&#125;$$</p>
<p>Converting this to action-value estimates:</p>
<p class="tex">$$Q&#40;s,a&#41; &#61; \frac&#123;\sum_&#123;t \in \mathscr&#123;T&#125;&#40;s,a&#41;&#125;\left&#40; R_&#123;t&#43;1&#125; &#43; &#40;1-\gamma&#41;\sum_&#123;h&#61;t&#43;2&#125;^&#123;T&#40;t&#41;-1&#125;\gamma^&#123;h-t-1&#125; \rho_&#123;t&#43;1:h-1&#125; \bar&#123;G&#125;_&#123;t&#43;1:h&#125; &#43; \gamma^&#123;T&#40;t&#41;-t-1&#125; \rho_&#123;t&#43;1:T&#40;t&#41;-1&#125; \bar&#123;G&#125;_&#123;t&#43;1:T&#40;t&#41;&#125; \right&#41;&#125;&#123;\sum_&#123;t \in \mathscr&#123;T&#125;&#40;s,a&#41;&#125; \left&#40; 1 &#43; &#40;1-\gamma&#41; \sum_&#123;h&#61;t&#43;2&#125;^&#123;T&#40;t&#41;-1&#125; \gamma^&#123;h-t-1&#125; \rho_&#123;t&#43;1:h-1&#125; &#43; \gamma^&#123;T&#40;t&#41;-t-1&#125; \rho_&#123;t&#43;1:T&#40;t&#41;-1&#125; \right&#41;&#125;$$</p>
<p>For the algorithm on page 111, need to add a variable in the loop to keep track of <span class="tex">$\bar&#123;G&#125;$</span> both from the start of the episode forwards.  The inner loop should also start from the beginning of each episode and go forwards rather than starting at the end going backwards.  The term added to the numerator and denominator will be ready including <span class="tex">$\bar&#123;G&#125;$</span> and <span class="tex">$\rho$</span> once the end of the episode is reached.  A <span class="tex">$\gamma$</span> accumulator can be initiazed at 1 and kept track of in the inner loop by repeatedly multiplying by γ each iteration.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA",([persist_js_state·has_pluto_hook_features§cell_id$dc57a71f-e44c-4385-ad2a-e6c14d5e5201depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$00cd2194-af13-415a-b725-bb34832e5d9aqueued¤logsrunning¦outputbody*figure5_3 (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA+0Qpersist_js_state·has_pluto_hook_features§cell_id$00cd2194-af13-415a-b725-bb34832e5d9adepends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$da66b3be-1fe2-4edb-9560-71ce7c0bed12queued¤logsrunning¦outputbodyelements9×12875 Matrix{Float32}:
 0.111111  0.111111  0.111111  0.111111  …  0.111111  0.111111  0.111111  0.111111
 0.111111  0.111111  0.111111  0.111111     0.111111  0.111111  0.111111  0.111111
 0.111111  0.111111  0.111111  0.111111     0.111111  0.111111  0.111111  0.111111
 0.111111  0.111111  0.111111  0.111111     0.111111  0.111111  0.111111  0.111111
 0.111111  0.111111  0.111111  0.111111     0.111111  0.111111  0.111111  0.111111
 0.111111  0.111111  0.111111  0.111111  …  0.111111  0.111111  0.111111  0.111111
 0.111111  0.111111  0.111111  0.111111     0.111111  0.111111  0.111111  0.111111
 0.111111  0.111111  0.111111  0.111111     0.111111  0.111111  0.111111  0.111111
 0.111111  0.111111  0.111111  0.111111     0.111111  0.111111  0.111111  0.111111text/plain9×12875 Matrix{Float32}:
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  …  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0     0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0     0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0     0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0     0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  …  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0     0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0     0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0     0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0text/plaintypeTupleobjectid2c7d92a4fbb2a408mime!application/vnd.pluto.tree+objectrootassigneelast_run_timestampA2{ưpersist_js_state·has_pluto_hook_features§cell_id$da66b3be-1fe2-4edb-9560-71ce7c0bed12depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cells§errored$d16ac2a8-1a5a-4ded-9285-d2c6cd550066queued¤logsrunning¦outputbody-0.2774324f0mimetext/plainrootassigneeconst blackjack_state_value1last_run_timestampA*|persist_js_state·has_pluto_hook_features§cell_id$d16ac2a8-1a5a-4ded-9285-d2c6cd550066depends_on_disabled_cells§runtimeήpublished_object_keysdepends_on_skipped_cells§errored$830d6d61-7259-43e7-8d6d-09bc81818dd9queued¤logsrunning¦outputbodyl<div class="markdown"><h3>Figure 5.4</h3>
<p>Ordinary importance sampling produces surprisingly unstable estimates on the one-state MDP shown in Example 5.5.  The correct estimate here is 1 &#40;<span class="tex">$\gamma &#61; 1$</span>&#41;, and, even through this is the expected value of a sample return &#40;after importance sampling&#41;, the variance of the samples is infinite, and the estimates do not converge to this value.  In contrast weighted importance samping produces the correct value of 1 after the first episode that ends with the left action. 	<script id='plot_1'>
		// We start by putting all the variable interpolation here at the beginning
		// We have to convert all typedarrays in the layout to normal arrays. See Issue #25
		// We use lodash for this for compactness
		function removeTypedArray(o) {
			return _.isTypedArray(o) ? Array.from(o) :
			_.isPlainObject(o) ? _.mapValues(o, removeTypedArray) : 
			o
		}

		// Publish the plot object to JS
		let plot_obj = _.update(/* See the documentation for AbstractPlutoDingetjes.Display.published_to_js */ getPublishedObject("c6e0de0c-3901-11f0-234e-bd09c571f662/aebe9ff9bf4a3c7"), "layout", removeTypedArray)
		// Get the plotly listeners
		const plotly_listeners = {}
		// Get the JS listeners
		const js_listeners = {}
		// Deal with eventual custom classes
		let custom_classlist = []


		// Load the plotly library
		let Plotly = undefined
		try {
			let _mod = await import("./plotlyjs/plotlyjs-2.26.2.min.js")
			Plotly = _mod.default
		} catch (e) {
			console.log("Local load failed, trying with the web esm.sh version")
			let _mod = await import("https://esm.sh/plotly.js-dist-min@2.26.2/es2022/plotly.js-dist-min.mjs")
			Plotly = _mod.default
		}

		// Check if we have to force local mathjax font cache
		if (false && window?.MathJax?.config?.svg?.fontCache === 'global') {
			window.MathJax.config.svg.fontCache = 'local'
		}

		// Flag to check if this cell was  manually ran or reactively ran
const firstRun = this ? false : true
const CONTAINER = this ?? html`<div class='plutoplotly-container'>`
const PLOT = CONTAINER.querySelector('.js-plotly-plot') ?? CONTAINER.appendChild(html`<div>`)
const parent = CONTAINER.parentElement
// We use a controller to remove event listeners upon invalidation
const controller = new AbortController()
// We have to add this to keep supporting @bind with the old API using PLOT
PLOT.addEventListener('input', (e) => {
	CONTAINER.value = PLOT.value
	if (e.bubbles) {
		return
	}
	CONTAINER.dispatchEvent(new CustomEvent('input'))
}, { signal: controller.signal })

	// This create the style subdiv on first run
	firstRun && CONTAINER.appendChild(html`
	<style>
	.plutoplotly-container {
		width: 100%;
		height: 100%;
		min-height: 0;
		min-width: 0;
	}
	.plutoplotly-container .js-plotly-plot .plotly div {
		margin: 0 auto; // This centers the plot
	}
	.plutoplotly-container.popped-out {
		overflow: auto;
		z-index: 1000;
		position: fixed;
		resize: both;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		border-top-left-radius: 0px;
		border-top-right-radius: 0px;
	}
	.plutoplotly-clipboard-header {
		display: flex;
		flex-flow: row wrap;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-top-left-radius: 12px;
		border-top-right-radius: 12px;
		position: fixed;
		z-index: 1001;
		cursor: move;
		transform: translate(0px, -100%);
		padding: 5px;
	}
	.plutoplotly-clipboard-header span {
		display: inline-block;
		flex: 1
	}
	.plutoplotly-clipboard-header.hidden {
		display: none;
	}
	.clipboard-span {
		position: relative;
	}
	.clipboard-value {
		padding-right: 5px;
		padding-left: 2px;
		cursor: text;
	}
	.clipboard-span.format {
		display: none;
	}
	.clipboard-span.filename {
		flex: 0 0 100%;
		text-align: center;
		border-top: 3px solid var(--kbd-border-color);
		margin-top: 5px;
		display: none;
	}
	.plutoplotly-container.filesave .clipboard-span.filename {
		display: inline-block;
	}
	.clipboard-value.filename {
		margin-left: 3px;
		text-align: left;
		min-width: min(60%, min-content);
	}
	.plutoplotly-container.filesave .clipboard-span.format {
		display: inline-flex;
	}
	.clipboard-span.format .label {
		flex: 0 0 0;
	}
	.clipboard-value.format {
		position: relative;
		flex: 1 0 auto;
		min-width: 30px;
		margin-right: 10px;
	}
	div.format-options {
		display: inline-flex;
		flex-flow: column;
		position: absolute;
		background: var(--main-bg-color);
		border-radius: 12px;
		padding-left: 3px;
		z-index: 2000;
	}
	div.format-options:hover {
		cursor: pointer;
		border: 3px solid var(--kbd-border-color);
		padding: 3px;
		transform: translate(-3px, -6px);
	}
	div.format-options .format-option {
		display: none;
	}
	div.format-options:hover .format-option {
		display: inline-block;
	}
	.format-option:not(.selected) {
		margin-top: 3px;
	}
	div.format-options .format-option.selected {
		order: -1;
		display: inline-block;
	}
	.format-option:hover {
		background-color: var(--kbd-border-color);
	}
	span.config-value {
		font-weight: normal;
		color: var(--pluto-output-color);
		display: none;
		position: absolute;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		transform: translate(0px, calc(-100% - 10px));
		padding: 5px;
	}
	.label {
		user-select: none;
	}
	.label:hover span.config-value {
		display: inline-block;
		min-width: 150px;
	}
	.clipboard-span.matching-config .label {
		color: var(--cm-macro-color);
		font-weight: bold;
	}
	.clipboard-span.different-config .label {
		color: var(--cm-tag-color);
		font-weight: bold;
	}
</style>
`)

let original_height = plot_obj.layout.height
let original_width = plot_obj.layout.width
// For the height we have to also put a fixed value in case the plot is put on a non-fixed-size container (like the default wrapper)
// We define a variable to check whether we still have to remove the fixed height
let remove_container_size = firstRun
let container_height = original_height ?? PLOT.container_height ?? 400
CONTAINER.style.height = container_height + 'px'

// We create a Promise version of setTimeout
function delay(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

// We import interact for dragging/resizing
const { default: interact } = await import('https://esm.sh/interactjs@1.10.19')


function getImageOptions() {
  const o = plot_obj.config.toImageButtonOptions ?? {};
  return {
    format: o.format ?? "png",
    width: o.width ?? original_width,
    height: o.height ?? original_height,
    scale: o.scale ?? 1,
    filename: o.filename ?? "newplot",
  };
}

const CLIPBOARD_HEADER =
  CONTAINER.querySelector(".plutoplotly-clipboard-header") ??
  CONTAINER.insertAdjacentElement(
    "afterbegin",
    html`<div class="plutoplotly-clipboard-header hidden">
      <span class="clipboard-span format"
        ><span class="label">Format:</span
        ><span class="clipboard-value format"></span
      ></span>
      <span class="clipboard-span width"
        ><span class="label">Width:</span
        ><span class="clipboard-value width"></span>px</span
      >
      <span class="clipboard-span height"
        ><span class="label">Height:</span
        ><span class="clipboard-value height"></span>px</span
      >
      <span class="clipboard-span scale"
        ><span class="label">Scale:</span
        ><span class="clipboard-value scale"></span
      ></span>
      <button class="clipboard-span set">Set</button>
      <button class="clipboard-span unset">Unset</button>
      <span class="clipboard-span filename"
        ><span class="label">Filename:</span
        ><span class="clipboard-value filename"></span
      ></span>
    </div>`
  );

function checkConfigSync(container) {
  const valid_classes = [
    "missing-config",
    "matching-config",
    "different-config",
  ];
  function setClass(cl) {
    for (const name of valid_classes) {
      container.classList.toggle(name, name == cl);
    }
  }
  // We use the custom getters we'll set up in the container
  const { ui_value, config_value, config_span, key } = container;
  if (config_value === undefined) {
    setClass("missing-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> is not present in the config.`;
  } else if (ui_value == config_value) {
    setClass("matching-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has the same value in the config and in the header.`;
  } else {
    setClass("different-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has a different value (<em>${config_value}</em>) in the config.`;
  }
  // Add info about setting and unsetting
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click on the label <em><b>once</b></em> to set the current UI value in the config.`
  );
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click <em><b>twice</b></em> to remove this key from the config.`
  );
}

const valid_formats = ["png", "svg", "webp", "jpeg", "full-json"];
function initializeUIValueSpan(span, key, value) {
  const container = span.closest(".clipboard-span");
  span.contentEditable = key === "format" ? "false" : "true";
  let parse = (x) => x;
  let update = (x) => (span.textContent = x);
  if (key === "width" || key === "height") {
    parse = (x) => Math.round(parseFloat(x));
  } else if (key === "scale") {
    parse = parseFloat;
  } else if (key === "format") {
    // We remove contentEditable
    span.contentEditable = "false";
    // Here we first add the subspans for each option
    const opts_div = span.appendChild(html`<div class="format-options"></div>`);
    for (const fmt of valid_formats) {
      const opt = opts_div.appendChild(
        html`<span class="format-option ${fmt}">${fmt}</span>`
      );
      opt.onclick = (e) => {
        span.value = opt.textContent;
      };
    }
    parse = (x) => {
      return valid_formats.includes(x) ? x : localValue;
    };
    update = (x) => {
      for (const opt of opts_div.children) {
        opt.classList.toggle("selected", opt.textContent === x);
      }
    };
  } else {
    // We only have filename here
  }
  let localValue;
  Object.defineProperty(span, "value", {
    get: () => {
      return localValue;
    },
    set: (val) => {
      if (val !== "") {
        localValue = parse(val);
      }
      update(localValue);
      checkConfigSync(container);
    },
  });
  // We also assign a listener so that the editable is blurred when enter is pressed
  span.onkeydown = (e) => {
    if (e.keyCode === 13) {
      e.preventDefault();
      span.blur();
    }
  };
  span.value = value;
}

function initializeConfigValueSpan(span, key) {
  // Here we mostly want to define the setter and getter
  const container = span.closest(".clipboard-span");
  Object.defineProperty(span, "value", {
    get: () => {
      return plot_obj.config.toImageButtonOptions[key];
    },
    set: (val) => {
      // if undefined is passed, we remove the entry from the options
      if (val === undefined) {
        delete plot_obj.config.toImageButtonOptions[key];
      } else {
        plot_obj.config.toImageButtonOptions[key] = val;
      }
      checkConfigSync(container);
    },
  });
}

const config_spans = {};
for (const [key, value] of Object.entries(getImageOptions())) {
  const container = CLIPBOARD_HEADER.querySelector(`.clipboard-span.${key}`);
  const label = container.querySelector(".label");
  // We give the label a function that on single click will set the current value and with double click will unset it
  label.onclick = DualClick(
    () => {
      container.config_value = container.ui_value;
    },
    (e) => {
      console.log("e", e);
      e.preventDefault();
      container.config_value = undefined;
    }
  );
  const ui_value_span = container.querySelector(".clipboard-value");
  const config_value_span =
    container.querySelector(".config-value") ??
    label.insertAdjacentElement(
      "afterbegin",
      html`<span class="config-value"></span>`
    );
  // Assing the two spans as properties of the containing span
  container.ui_span = ui_value_span;
  container.config_span = config_value_span;
  container.key = key;
  config_spans[key] = container;
  if (firstRun) {
    plot_obj.config.toImageButtonOptions =
      plot_obj.config.toImageButtonOptions ?? {};
    // We do the initialization of the value span
    initializeUIValueSpan(ui_value_span, key, value);
    // Then we initialize the config value
    initializeConfigValueSpan(config_value_span, key);
    // We put some convenience getters/setters
    // ui_value forward
    Object.defineProperty(container, "ui_value", {
      get: () => ui_value_span.value,
      set: (val) => {
        ui_value_span.value = val;
      },
    });
    // config_value forward
    Object.defineProperty(container, "config_value", {
      get: () => config_value_span.value,
      set: (val) => {
        config_value_span.value = val;
      },
    });
  }
}

// These objects will contain the default value

// This code updates the image options in the PLOT config with the provided ones
function setImageOptions(o) {
  for (const [key, container] of Object.entries(config_spans)) {
    container.config_value = o[key];
  }
}
function unsetImageOptions() {
  setImageOptions({});
}

const set_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.set");
const unset_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.unset");
if (firstRun) {
  set_button.onclick = (e) => {
    for (const container of Object.values(config_spans)) {
      container.config_value = container.ui_value;
    }
  };
  unset_button.onclick = unsetImageOptions;
}

// We add a function to check if the clipboard is popped out
CONTAINER.isPoppedOut = () => {
  return CONTAINER.classList.contains("popped-out");
};

CLIPBOARD_HEADER.onmousedown = function (event) {
  if (event.target.matches("span.clipboard-value")) {
    console.log("We don't move!");
    return;
  }
  const start = {
    left: parseFloat(CONTAINER.style.left),
    top: parseFloat(CONTAINER.style.top),
    X: event.pageX,
    Y: event.pageY,
  };
  function moveAt(event, start) {
    const top = event.pageY - start.Y + start.top + "px";
    const left = event.pageX - start.X + start.left + "px";
    CLIPBOARD_HEADER.style.left = left;
    CONTAINER.style.left = left;
    CONTAINER.style.top = top;
  }

  // move our absolutely positioned ball under the pointer
  moveAt(event, start);
  function onMouseMove(event) {
    moveAt(event, start);
  }

  // We use this to remove the mousemove when clicking outside of the container
  const controller = new AbortController();

  // move the container on mousemove
  document.addEventListener("mousemove", onMouseMove, {
    signal: controller.signal,
  });
  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        cleanUp();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );

  function cleanUp() {
    console.log("cleaning up the plot move listener");
    controller.abort();
    CLIPBOARD_HEADER.onmouseup = null;
  }

  // (3) drop the ball, remove unneeded handlers
  CLIPBOARD_HEADER.onmouseup = cleanUp;
};

function sendToClipboard(blob) {
  if (!navigator.clipboard) {
    alert(
      "The Clipboard API does not seem to be available, make sure the Pluto notebook is being used from either localhost or an https source."
    );
  }
  navigator.clipboard
    .write([
      new ClipboardItem({
        // The key is determined dynamically based on the blob's type.
        [blob.type]: blob,
      }),
    ])
    .then(
      function () {
        console.log("Async: Copying to clipboard was successful!");
      },
      function (err) {
        console.error("Async: Could not copy text: ", err);
      }
    );
}

function copyImageToClipboard() {
  // We extract the image options from the provided parameters (if they exist)
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key. We also ignore format because the clipboard only supports png.
    if (val === undefined || key === "format") {
      continue;
    }
    config[key] = val;
  }
  Plotly.toImage(PLOT, config).then(function (dataUrl) {
    fetch(dataUrl)
      .then((res) => res.blob())
      .then((blob) => {
        const paste_receiver = document.querySelector('paste-receiver.plutoplotly')
        if (paste_receiver) {
          paste_receiver.attachImage(dataUrl, CONTAINER)
        }
        sendToClipboard(blob)
      });
  });
}

function saveImageToFile() {
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key.
    if (val === undefined) {
      continue;
    }
    config[key] = val;
  }
  Plotly.downloadImage(PLOT, config);
}

let container_rect = { width: 0, height: 0, top: 0, left: 0 };
function unpop_container(cl) {
  CONTAINER.classList.toggle("popped-out", false);
  CONTAINER.classList.toggle(cl, false);
  // We fix the height back to the value it had before popout, also setting the flag to signal that upon first resize we remove the fixed inline-style
  CONTAINER.style.height = container_rect.height + "px";
  remove_container_size = true;
  // We set the other fixed inline-styles to null
  CONTAINER.style.width = "";
  CONTAINER.style.top = "";
  CONTAINER.style.left = "";
  // We also remove the CLIPBOARD_HEADER
  CLIPBOARD_HEADER.style.width = "";
  CLIPBOARD_HEADER.style.left = "";
  // Finally we remove the hidden class to the header
  CLIPBOARD_HEADER.classList.toggle("hidden", true);
  return;
}
function popout_container(opts) {
  const cl = opts?.cl;
  const target_container_size = opts?.target_container_size ?? {};
  const target_plot_size = opts?.target_plot_size ?? {};
  if (CONTAINER.isPoppedOut()) {
    return unpop_container(cl);
  }
  CONTAINER.classList.toggle(cl, cl === undefined ? false : true);
  // We extract the current size of the container, save them and fix them
  const { width, height, top, left } = CONTAINER.getBoundingClientRect();
  container_rect = { width, height, top, left };
  // We save the current plot size before we pop as it will fill the screen
  const current_plot_size = {
    width: PLOT._fullLayout.width,
    height: PLOT._fullLayout.height,
  };
  // We have to save the pad data before popping so we can resize precisely
  const pad = {};
  pad.unpopped = getSizeData().container_pad;
  CONTAINER.classList.toggle("popped-out", true);
  pad.popped = getSizeData().container_pad;
  // We do top and left based on the current rect
  for (const key of ["top", "left"]) {
    const start_val = target_container_size[key] ?? container_rect[key];
    let offset = 0;
    for (const kind of ["padding", "border"]) {
      offset += pad.popped[kind][key] - pad.unpopped[kind][key];
    }
    CONTAINER.style[key] = start_val - offset + "px";
    if (key === "left") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  // We compute the width and height depending on eventual config data
  const csz = computeContainerSize({
    width:
      target_plot_size.width ??
      config_spans.width.config_value ??
      current_plot_size.width,
    height:
      target_plot_size.height ??
      config_spans.height.config_value ??
      current_plot_size.height,
  });
  for (const key of ["width", "height"]) {
    const val = target_container_size[key] ?? csz[key];
    CONTAINER.style[key] = val + "px";
    if (key === "width") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  CLIPBOARD_HEADER.classList.toggle("hidden", false);
  const controller = new AbortController();

  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        unpop_container();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );
}

CONTAINER.popOut = popout_container;

function DualClick(single_func, dbl_func) {
  let nclicks = 0;
  return function (...args) {
    nclicks += 1;
    if (nclicks > 1) {
      dbl_func(...args);
      nclicks = 0;
    } else {
      delay(300).then(() => {
        if (nclicks == 1) {
          single_func(...args);
        }
        nclicks = 0;
      });
    }
  };
}

// We remove the default download image button
plot_obj.config.modeBarButtonsToRemove = _.union(
  plot_obj.config.modeBarButtonsToRemove,
  ["toImage"]
);
// We add the custom button to the modebar
plot_obj.config.modeBarButtonsToAdd = _.union(
  plot_obj.config.modeBarButtonsToAdd,
  [
    {
      name: "Copy PNG to Clipboard",
      icon: {
        height: 520,
        width: 520,
        path: "M280 64h40c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128C0 92.7 28.7 64 64 64h40 9.6C121 27.5 153.3 0 192 0s71 27.5 78.4 64H280zM64 112c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16H320c8.8 0 16-7.2 16-16V128c0-8.8-7.2-16-16-16H304v24c0 13.3-10.7 24-24 24H192 104c-13.3 0-24-10.7-24-24V112H64zm128-8a24 24 0 1 0 0-48 24 24 0 1 0 0 48z",
      },
      direction: "up",
      click: DualClick(copyImageToClipboard, () => {
        popout_container();
      }),
    },
    {
      name: "Download Image",
      icon: Plotly.Icons.camera,
      direction: "up",
      click: DualClick(saveImageToFile, () => {
        popout_container({ cl: "filesave" });
      }),
    },
  ]
);

function getOffsetData(el) {
  let cs = window.getComputedStyle(el, null);
  const odata = {
    padding: {
      left: parseFloat(cs.paddingLeft),
      right: parseFloat(cs.paddingRight),
      top: parseFloat(cs.paddingTop),
      bottom: parseFloat(cs.paddingBottom),
      width: parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight),
      height: parseFloat(cs.paddingTop) + parseFloat(cs.paddingBottom),
    },
    border: {
      left: parseFloat(cs.borderLeftWidth),
      right: parseFloat(cs.borderRightWidth),
      top: parseFloat(cs.borderTopWidth),
      bottom: parseFloat(cs.borderBottomWidth),
      width: parseFloat(cs.borderLeftWidth) + parseFloat(cs.borderRightWidth),
      height: parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth),
    }
  };
  if (el === PLOT) {
    // For the PLOT we also want to take into account the offset
    odata.offset = {
      top: PLOT.offsetParent == CONTAINER ? PLOT.offsetTop : 0,
      left: PLOT.offsetParent == CONTAINER ? PLOT.offsetLeft : 0,
    }
  }
  return odata;
}
function getSizeData() {
  const data = {
    plot_pad: getOffsetData(PLOT),
    plot_rect: PLOT.getBoundingClientRect(),
    container_pad: getOffsetData(CONTAINER),
    container_rect: CONTAINER.getBoundingClientRect(),
  };
  return data;
}
function computeContainerSize({ width, height }, sizeData = getSizeData()) {
  const computed_size = computePlotSize(sizeData);
  const offsets = computed_size.offsets;

  const plot_data = {
    width: width ?? computed_size.width,
    height: height ?? computed_size.height,
  };

  return {
    width: (width ?? computed_size.width) + offsets.width,
    height: (height ?? computed_size.height) + offsets.height,
    noChange: width == computed_size.width && height == computed_size.height,
  }
}

// This function will change the container size so that the resulting plot will be matching the provided specs
function changeContainerSize({ width, height }, sizeData = getSizeData()) {
  if (!CONTAINER.isPoppedOut()) {
    console.log("Tried to change container size when not popped, ignoring");
    return;
  }

  const csz = computeContainerSize({ width, height }, sizeData);

  if (csz.noChange) {
    console.log("Size is the same as current, ignoring");
    return
  }
  // We are now going to set he width and height of the container
  for (const key of ["width", "height"]) {
    CONTAINER.style[key] = csz[key] + "px";
  }
}
// We now create the function that will update the plot based on the values specified
function updateFromHeader() {
  const header_data = {
    height: config_spans.height.ui_value,
    width: config_spans.width.ui_value,
  };
  changeContainerSize(header_data);
}
// We assign this function to the onblur event of width and height
if (firstRun) {
  for (const container of Object.values(config_spans)) {
    container.ui_span.onblur = (e) => {
      container.ui_value = container.ui_span.textContent;
      updateFromHeader();
    };
  }
}
// This function computes the plot size to use for relayout as a function of the container size
function computePlotSize(data = getSizeData()) {
  // Remove Padding
  const { container_pad, plot_pad, container_rect } = data;
  const offsets = {
    width:
      plot_pad.padding.width +
      plot_pad.border.width +
      plot_pad.offset.left +
      container_pad.padding.width +
      container_pad.border.width,
    height:
      plot_pad.padding.height +
      plot_pad.border.height +
      plot_pad.offset.top +
      container_pad.padding.height +
      container_pad.border.height,
  };
  const sz = {
    width: Math.round(container_rect.width - offsets.width),
    height: Math.round(container_rect.height - offsets.height),
    offsets,
  };
  return sz;
}

// Create the resizeObserver to make the plot even more responsive! :magic:
const resizeObserver = new ResizeObserver((entries) => {
  const sizeData = getSizeData();
  const {container_rect, container_pad} = sizeData;
  let plot_size = computePlotSize(sizeData);
  // We save the height in the PLOT object
  PLOT.container_height = container_rect.height;
  // We deal with some stuff if the container is poppped
  CLIPBOARD_HEADER.style.width = container_rect.width + "px";
  CLIPBOARD_HEADER.style.left = container_rect.left + "px";
  config_spans.height.ui_value = plot_size.height;
  config_spans.width.ui_value = plot_size.width;
  /* 
		The addition of the invalid argument `plutoresize` seems to fix the problem with calling `relayout` simply with `{autosize: true}` as update breaking mouse relayout events tracking. 
		See https://github.com/plotly/plotly.js/issues/6156 for details
		*/
  let config = {
    // If this is popped out, we ignore the original width/height
    width: (CONTAINER.isPoppedOut() ? undefined : original_width) ?? plot_size.width,
    height: (CONTAINER.isPoppedOut() ? undefined : original_height) ?? plot_size.height,
    plutoresize: true,
  };
  Plotly.relayout(PLOT, config).then(() => {
    if (remove_container_size && !CONTAINER.isPoppedOut()) {
      // This is needed to avoid the first resize upon plot creation to already be without a fixed height
      CONTAINER.style.height = "";
      CONTAINER.style.width = "";
      remove_container_size = false;
    }
  });
});

resizeObserver.observe(CONTAINER);


Plotly.react(PLOT, plot_obj).then(() => {
	// Assign the Plotly event listeners
	for (const [key, listener_vec] of Object.entries(plotly_listeners)) {
		for (const listener of listener_vec) {
			PLOT.on(key, listener)
		}
	}
	// Assign the JS event listeners
	for (const [key, listener_vec] of Object.entries(js_listeners)) {
		for (const listener of listener_vec) {
			PLOT.addEventListener(key, listener, {
				signal: controller.signal
			})
		}
	}
}
)


invalidation.then(() => {
	// Remove all plotly listeners
	PLOT.removeAllListeners()
	// Remove all JS listeners
	controller.abort()
	// Remove the resizeObserver
	resizeObserver.disconnect()
})



		return CONTAINER
	</script>
</p>
</div>mimetext/htmlrootassigneelast_run_timestampA-9-4persist_js_state·has_pluto_hook_features§cell_id$830d6d61-7259-43e7-8d6d-09bc81818dd9depends_on_disabled_cells§runtime`published_object_keys4c6e0de0c-3901-11f0-234e-bd09c571f662/aebe9ff9bf4a3c7depends_on_skipped_cells§errored$e293e184-5938-40b5-a04b-5306760a06aequeued¤logsrunning¦outputbody9estimate_blackjack_state (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA)Qepersist_js_state·has_pluto_hook_features§cell_id$e293e184-5938-40b5-a04b-5306760a06aedepends_on_disabled_cells§runtime Zpublished_object_keysdepends_on_skipped_cells§errored$66645f1a-b591-43e7-b931-8ed0cc7d6898queued¤logsrunning¦outputbody A	<div style = "display: flex;">
	<div>
Race finished in 58 steps
<div style="background-color: white; color: black;">
	<div style="display:flex; align-items: flex-start">
	<div class = "track">
		<div class = "start" style="grid-column-start: 8; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 5; grid-row-start: 1;"></div><div class = "start" vx = "2" vy = "0" dvx = "0" dvy = "-1" style="grid-column-start: 14; grid-row-start: 1;"></div><div class = "start" vx = "1" vy = "0" dvx = "-1" dvy = "-1" style="grid-column-start: 16; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "0" dvy = "-1" style="grid-column-start: 3; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "1" dvy = "-1" style="grid-column-start: 11; grid-row-start: 1;"></div><div class = "start" vx = "3" vy = "0" dvx = "1" dvy = "0" style="grid-column-start: 19; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "1" dvy = "1" style="grid-column-start: 22; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 6; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 17; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 21; grid-row-start: 1;"></div><div class = "start" vx = "1" vy = "0" dvx = "1" dvy = "0" style="grid-column-start: 13; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "1" dvy = "0" style="grid-column-start: 9; grid-row-start: 1;"></div><div class = "start" vx = "2" vy = "0" dvx = "1" dvy = "1" style="grid-column-start: 18; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 2; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 20; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 1; grid-row-start: 1;"></div><div class = "start" vx = "4" vy = "0" dvx = "1" dvy = "1" style="grid-column-start: 23; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 7; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "0" dvy = "0" style="grid-column-start: 12; grid-row-start: 1;"></div><div class = "start" vx = "1" vy = "0" dvx = "1" dvy = "1" style="grid-column-start: 10; grid-row-start: 1;"></div><div class = "start" vx = "2" vy = "0" dvx = "-1" dvy = "-1" style="grid-column-start: 15; grid-row-start: 1;"></div><div class = "start" vx = "1" vy = "0" dvx = "1" dvy = "1" style="grid-column-start: 4; grid-row-start: 1;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 15;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "1" style="grid-column-start: 8; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 13;"></div><div class = "" vx = "0" vy = "3" dvx = "1" dvy = "0" style="grid-column-start: 19; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 27;"></div><div class = "" vx = "2" vy = "2" dvx = "1" dvy = "1" style="grid-column-start: 31; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 8;"></div><div class = "" vx = "1" vy = "4" dvx = "-1" dvy = "1" style="grid-column-start: 18; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 20;"></div><div class = "" vx = "0" vy = "3" dvx = "1" dvy = "0" style="grid-column-start: 18; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 4;"></div><div class = "" vx = "0" vy = "4" dvx = "1" dvy = "-1" style="grid-column-start: 18; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 8;"></div><div class = "" vx = "1" vy = "2" dvx = "-1" dvy = "1" style="grid-column-start: 17; grid-row-start: 4;"></div><div class = "" vx = "2" vy = "2" dvx = "0" dvy = "0" style="grid-column-start: 29; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 21;"></div><div class = "" vx = "4" vy = "1" dvx = "0" dvy = "1" style="grid-column-start: 19; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 9;"></div><div class = "" vx = "2" vy = "4" dvx = "-1" dvy = "1" style="grid-column-start: 17; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 11;"></div><div class = "" vx = "1" vy = "3" dvx = "-1" dvy = "0" style="grid-column-start: 20; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 28;"></div><div class = "" vx = "4" vy = "2" dvx = "1" dvy = "0" style="grid-column-start: 23; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 4;"></div><div class = "" vx = "1" vy = "3" dvx = "-1" dvy = "0" style="grid-column-start: 19; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 2;"></div><div class = "" vx = "2" vy = "0" dvx = "0" dvy = "0" style="grid-column-start: 23; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 8;"></div><div class = "" vx = "1" vy = "4" dvx = "-1" dvy = "-1" style="grid-column-start: 18; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 9;"></div><div class = "" vx = "1" vy = "2" dvx = "0" dvy = "1" style="grid-column-start: 7; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 28;"></div><div class = "" vx = "2" vy = "1" dvx = "-1" dvy = "1" style="grid-column-start: 6; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 4;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "1" style="grid-column-start: 14; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 23;"></div><div class = "" vx = "1" vy = "3" dvx = "-1" dvy = "-1" style="grid-column-start: 8; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 5;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "0" style="grid-column-start: 18; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 4;"></div><div class = "" vx = "0" vy = "3" dvx = "1" dvy = "1" style="grid-column-start: 17; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 14;"></div><div class = "" vx = "2" vy = "0" dvx = "1" dvy = "0" style="grid-column-start: 18; grid-row-start: 2;"></div><div class = "" vx = "3" vy = "2" dvx = "0" dvy = "0" style="grid-column-start: 24; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 30;"></div><div class = "" vx = "2" vy = "2" dvx = "1" dvy = "0" style="grid-column-start: 21; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 12;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "1" style="grid-column-start: 16; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 2;"></div><div class = "" vx = "1" vy = "1" dvx = "1" dvy = "-1" style="grid-column-start: 14; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 9;"></div><div class = "" vx = "2" vy = "1" dvx = "1" dvy = "-1" style="grid-column-start: 12; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 23;"></div><div class = "" vx = "3" vy = "1" dvx = "-1" dvy = "-1" style="grid-column-start: 21; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 17;"></div><div class = "" vx = "3" vy = "2" dvx = "-1" dvy = "0" style="grid-column-start: 27; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 29;"></div><div class = "" vx = "3" vy = "0" dvx = "1" dvy = "1" style="grid-column-start: 15; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 26;"></div><div class = "" vx = "1" vy = "3" dvx = "1" dvy = "1" style="grid-column-start: 15; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 21;"></div><div class = "" vx = "1" vy = "3" dvx = "1" dvy = "-1" style="grid-column-start: 19; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 27;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 30;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 27;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 23;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 28;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 29;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 26;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 25;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 24;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 22;"></div>
	</div>
	Finish <br> line
	</div>
	<div>Starting line</div>
</div>
</div>

	<div>
Race finished in 117 steps
<div style="background-color: white; color: black;">
	<div style="display:flex; align-items: flex-start">
	<div class = "track">
		<div class = "start" vx = "0" vy = "0" dvx = "-1" dvy = "1" style="grid-column-start: 8; grid-row-start: 1;"></div><div class = "start" vx = "2" vy = "0" dvx = "0" dvy = "0" style="grid-column-start: 5; grid-row-start: 1;"></div><div class = "start" vx = "1" vy = "0" dvx = "0" dvy = "0" style="grid-column-start: 14; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 16; grid-row-start: 1;"></div><div class = "start" vx = "1" vy = "0" dvx = "1" dvy = "-1" style="grid-column-start: 3; grid-row-start: 1;"></div><div class = "start" vx = "1" vy = "0" dvx = "-1" dvy = "-1" style="grid-column-start: 11; grid-row-start: 1;"></div><div class = "start" vx = "1" vy = "0" dvx = "-1" dvy = "1" style="grid-column-start: 19; grid-row-start: 1;"></div><div class = "start" vx = "1" vy = "0" dvx = "-1" dvy = "1" style="grid-column-start: 22; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 6; grid-row-start: 1;"></div><div class = "start" vx = "4" vy = "0" dvx = "1" dvy = "1" style="grid-column-start: 17; grid-row-start: 1;"></div><div class = "start" vx = "1" vy = "0" dvx = "0" dvy = "-1" style="grid-column-start: 21; grid-row-start: 1;"></div><div class = "start" vx = "3" vy = "0" dvx = "1" dvy = "0" style="grid-column-start: 13; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "0" dvy = "-1" style="grid-column-start: 9; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "0" dvy = "1" style="grid-column-start: 18; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "1" dvy = "-1" style="grid-column-start: 2; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "1" dvy = "-1" style="grid-column-start: 20; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "-1" dvy = "0" style="grid-column-start: 1; grid-row-start: 1;"></div><div class = "start" vx = "1" vy = "0" dvx = "0" dvy = "1" style="grid-column-start: 23; grid-row-start: 1;"></div><div class = "start" vx = "2" vy = "0" dvx = "-1" dvy = "0" style="grid-column-start: 7; grid-row-start: 1;"></div><div class = "start" vx = "1" vy = "0" dvx = "0" dvy = "0" style="grid-column-start: 12; grid-row-start: 1;"></div><div class = "start" vx = "2" vy = "0" dvx = "1" dvy = "-1" style="grid-column-start: 10; grid-row-start: 1;"></div><div class = "start" vx = "1" vy = "0" dvx = "1" dvy = "-1" style="grid-column-start: 15; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 4; grid-row-start: 1;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 17;"></div><div class = "" vx = "2" vy = "1" dvx = "-1" dvy = "-1" style="grid-column-start: 17; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 13;"></div><div class = "" vx = "3" vy = "2" dvx = "0" dvy = "-1" style="grid-column-start: 29; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 17;"></div><div class = "" vx = "2" vy = "0" dvx = "0" dvy = "0" style="grid-column-start: 20; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 25;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "1" style="grid-column-start: 23; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 19;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "1" style="grid-column-start: 19; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 24;"></div><div class = "" vx = "0" vy = "4" dvx = "-1" dvy = "1" style="grid-column-start: 21; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 26;"></div><div class = "" vx = "1" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 23; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 8;"></div><div class = "" vx = "1" vy = "0" dvx = "1" dvy = "-1" style="grid-column-start: 18; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 6;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 22; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 24;"></div><div class = "" vx = "1" vy = "1" dvx = "1" dvy = "1" style="grid-column-start: 13; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 25;"></div><div class = "" vx = "1" vy = "3" dvx = "-1" dvy = "0" style="grid-column-start: 19; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 27;"></div><div class = "" vx = "1" vy = "2" dvx = "-1" dvy = "1" style="grid-column-start: 20; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 4;"></div><div class = "" vx = "0" vy = "4" dvx = "-1" dvy = "0" style="grid-column-start: 18; grid-row-start: 19;"></div><div class = "" vx = "1" vy = "2" dvx = "-1" dvy = "1" style="grid-column-start: 18; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 11;"></div><div class = "" vx = "1" vy = "1" dvx = "0" dvy = "1" style="grid-column-start: 2; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 2;"></div><div class = "" vx = "1" vy = "1" dvx = "-1" dvy = "1" style="grid-column-start: 23; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 25;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "-1" style="grid-column-start: 19; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 15;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "-1" style="grid-column-start: 18; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 10;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "-1" style="grid-column-start: 8; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 2;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "-1" style="grid-column-start: 19; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 8;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "-1" style="grid-column-start: 17; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 21;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "1" style="grid-column-start: 18; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 21;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "-1" style="grid-column-start: 8; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 10;"></div><div class = "" vx = "0" vy = "3" dvx = "1" dvy = "1" style="grid-column-start: 14; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 7;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "1" style="grid-column-start: 11; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 20;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "1" style="grid-column-start: 21; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 20;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "-1" style="grid-column-start: 20; grid-row-start: 11;"></div><div class = "" vx = "0" vy = "4" dvx = "1" dvy = "1" style="grid-column-start: 20; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 3;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "1" style="grid-column-start: 18; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 28;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "0" style="grid-column-start: 23; grid-row-start: 5;"></div><div class = "" vx = "0" vy = "4" dvx = "-1" dvy = "-1" style="grid-column-start: 23; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 22;"></div><div class = "" vx = "1" vy = "0" dvx = "-1" dvy = "0" style="grid-column-start: 11; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 5;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "-1" style="grid-column-start: 10; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 11;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "0" style="grid-column-start: 18; grid-row-start: 3;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "-1" style="grid-column-start: 18; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 25;"></div><div class = "" vx = "1" vy = "2" dvx = "-1" dvy = "-1" style="grid-column-start: 19; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 11;"></div><div class = "" vx = "1" vy = "3" dvx = "-1" dvy = "1" style="grid-column-start: 20; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 4;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "1" style="grid-column-start: 23; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 26;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "0" style="grid-column-start: 9; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 5;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "0" style="grid-column-start: 18; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 3;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "1" style="grid-column-start: 14; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 4;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "0" style="grid-column-start: 19; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 21;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "1" style="grid-column-start: 17; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 6;"></div><div class = "" vx = "2" vy = "2" dvx = "1" dvy = "0" style="grid-column-start: 26; grid-row-start: 23;"></div><div class = "" vx = "1" vy = "2" dvx = "0" dvy = "-1" style="grid-column-start: 12; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 3;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "1" style="grid-column-start: 8; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 4;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "0" style="grid-column-start: 9; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 23;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "1" style="grid-column-start: 19; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 11;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "1" style="grid-column-start: 17; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 23;"></div><div class = "" vx = "2" vy = "0" dvx = "-1" dvy = "0" style="grid-column-start: 22; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 3;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "1" style="grid-column-start: 19; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 4;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "0" style="grid-column-start: 17; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 22;"></div><div class = "" vx = "1" vy = "3" dvx = "-1" dvy = "0" style="grid-column-start: 18; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 14;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "-1" style="grid-column-start: 18; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 5;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "1" style="grid-column-start: 14; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 15;"></div><div class = "" vx = "0" vy = "4" dvx = "-1" dvy = "0" style="grid-column-start: 20; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 2;"></div><div class = "" vx = "1" vy = "1" dvx = "-1" dvy = "0" style="grid-column-start: 14; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 20;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "0" style="grid-column-start: 9; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 7;"></div><div class = "" vx = "1" vy = "4" dvx = "0" dvy = "0" style="grid-column-start: 15; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 18;"></div><div class = "" vx = "0" vy = "4" dvx = "-1" dvy = "1" style="grid-column-start: 21; grid-row-start: 23;"></div><div class = "" vx = "4" vy = "1" dvx = "-1" dvy = "-1" style="grid-column-start: 21; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 4;"></div><div class = "" vx = "1" vy = "4" dvx = "0" dvy = "0" style="grid-column-start: 16; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 26;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 1; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 27;"></div><div class = "" vx = "1" vy = "1" dvx = "-1" dvy = "-1" style="grid-column-start: 9; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 7;"></div><div class = "" vx = "1" vy = "0" dvx = "0" dvy = "-1" style="grid-column-start: 23; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 5;"></div><div class = "" vx = "2" vy = "2" dvx = "0" dvy = "-1" style="grid-column-start: 15; grid-row-start: 14;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "-1" style="grid-column-start: 23; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 28;"></div><div class = "" vx = "1" vy = "1" dvx = "0" dvy = "0" style="grid-column-start: 22; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 2;"></div><div class = "" vx = "1" vy = "0" dvx = "-1" dvy = "0" style="grid-column-start: 10; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 23;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "0" style="grid-column-start: 23; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 30;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "-1" style="grid-column-start: 9; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 7;"></div><div class = "" vx = "0" vy = "4" dvx = "0" dvy = "0" style="grid-column-start: 20; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 13;"></div><div class = "" vx = "1" vy = "3" dvx = "-1" dvy = "0" style="grid-column-start: 21; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 12;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "1" style="grid-column-start: 20; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 30;"></div><div class = "" vx = "1" vy = "2" dvx = "1" dvy = "0" style="grid-column-start: 24; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 27;"></div><div class = "" vx = "1" vy = "4" dvx = "0" dvy = "-1" style="grid-column-start: 17; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 6;"></div><div class = "" vx = "0" vy = "4" dvx = "0" dvy = "0" style="grid-column-start: 20; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 27;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 30;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 27;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 23;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 28;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 29;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 26;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 25;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 24;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 22;"></div>
	</div>
	Finish <br> line
	</div>
	<div>Starting line</div>
</div>
</div>

	</div>
mimetext/htmlrootassigneelast_run_timestampA2}@persist_js_state·has_pluto_hook_features§cell_id$66645f1a-b591-43e7-b931-8ed0cc7d6898depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$658ceeaa-1b45-47bd-a364-eaa1759d17acqueued¤logsrunning¦outputbody3race_track_episode (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA/_persist_js_state·has_pluto_hook_features§cell_id$658ceeaa-1b45-47bd-a364-eaa1759d17acdepends_on_disabled_cells§runtime xpublished_object_keysdepends_on_skipped_cells§errored$04752549-ffca-4e31-869e-714f835d3e85queued¤logsrunning¦outputbody23mimetext/plainrootassigneeconst blackjack_stateindex1last_run_timestampA)persist_js_state·has_pluto_hook_features§cell_id$04752549-ffca-4e31-869e-714f835d3e85depends_on_disabled_cells§runtime M&published_object_keysdepends_on_skipped_cells§errored$e89706f1-0c6a-4da4-82a1-ccf153f2e186queued¤logsrunning¦outputbodyR<div class="markdown"><h4>Monte Carlo Exploring Starts Solution Method</h4>
</div>mimetext/htmlrootassigneelast_run_timestampA"*xpersist_js_state·has_pluto_hook_features§cell_id$e89706f1-0c6a-4da4-82a1-ccf153f2e186depends_on_disabled_cells§runtime ^published_object_keysdepends_on_skipped_cells§errored$ab10ccd7-75ba-475c-af26-f8b36daaf880queued¤logsrunning¦outputbody<div class="markdown"><blockquote>
<h3><em>Exercise 5.11</em></h3>
<p>In the boxed algorithm for off-policy MC control, you may have been expecting the <span class="tex">$W$</span> update to have involved the importance-sampling ratio <span class="tex">$\frac&#123;\pi&#40;A_t|S_t&#41;&#125;&#123;b&#40;A_t|S_T&#41;&#125;$</span>, but instead it involves <span class="tex">$\frac&#123;1&#125;&#123;b&#40;A_t|S_t&#41;&#125;$</span>.  Why is this nevertheless correct?</p>
</blockquote>
<p>The target policy <span class="tex">$\pi&#40;s&#41;$</span> is always deterministic, only selecting a single action according to <span class="tex">$\pi&#40;s&#41;&#61;\text&#123;argmax&#125;_a Q&#40;s,a&#41;$</span>.  Therefore the numerator in importance-sampling ratio will either be 1 when the trajectory action matches the one given by <span class="tex">$\pi&#40;s&#41;$</span> or it will be 0.  The inner loop will exit if such as action is selected as it will result in zero values of W for the rest of the trajectory and thus no further updates to <span class="tex">$Q&#40;s,a&#41;$</span> or <span class="tex">$\pi&#40;s&#41;$</span>.  The only value of <span class="tex">$\pi&#40;s&#41;$</span> that would be encountered in the equation is therefore 1 which is why the numerator is a constant.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA")|persist_js_state·has_pluto_hook_features§cell_id$ab10ccd7-75ba-475c-af26-f8b36daaf880depends_on_disabled_cells§runtime Jpublished_object_keysdepends_on_skipped_cells§errored$4481fa33-1ff3-4778-8486-d4d8a15775cdqueued¤logsrunning¦outputbody 4b	<div style = "display: flex;">
	<div>
Race finished in 14 steps
<div style="background-color: white; color: black;">
	<div style="display:flex; align-items: flex-start">
	<div class = "track">
		<div class = "start" style="grid-column-start: 8; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 5; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 14; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "-1" dvy = "0" style="grid-column-start: 16; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 3; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 11; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 19; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 22; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 6; grid-row-start: 1;"></div><div class = "start" vx = "1" vy = "0" dvx = "-1" dvy = "1" style="grid-column-start: 17; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 21; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 13; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 9; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 18; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 2; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 20; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 1; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 23; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 7; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 12; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 10; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 15; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 4; grid-row-start: 1;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 29;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "0" style="grid-column-start: 18; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 8;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "1" style="grid-column-start: 17; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 3;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "-1" style="grid-column-start: 18; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 5;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "-1" style="grid-column-start: 18; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 10;"></div><div class = "" vx = "2" vy = "2" dvx = "1" dvy = "1" style="grid-column-start: 22; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 11;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "1" style="grid-column-start: 17; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 5;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "1" style="grid-column-start: 18; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 30;"></div><div class = "" vx = "1" vy = "3" dvx = "-1" dvy = "0" style="grid-column-start: 18; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 14;"></div><div class = "" vx = "1" vy = "2" dvx = "0" dvy = "0" style="grid-column-start: 19; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 5;"></div><div class = "" vx = "4" vy = "4" dvx = "0" dvy = "0" style="grid-column-start: 29; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 21;"></div><div class = "" vx = "1" vy = "2" dvx = "1" dvy = "0" style="grid-column-start: 20; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 3;"></div><div class = "" vx = "3" vy = "3" dvx = "1" dvy = "1" style="grid-column-start: 25; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 27;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 30;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 27;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 23;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 28;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 29;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 26;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 25;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 24;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 22;"></div>
	</div>
	Finish <br> line
	</div>
	<div>Starting line</div>
</div>
</div>

	<div>
Race finished in 44 steps
<div style="background-color: white; color: black;">
	<div style="display:flex; align-items: flex-start">
	<div class = "track">
		<div class = "start" style="grid-column-start: 8; grid-row-start: 1;"></div><div class = "start" vx = "1" vy = "0" dvx = "-1" dvy = "-1" style="grid-column-start: 5; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 14; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 16; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 3; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 11; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "0" dvy = "-1" style="grid-column-start: 19; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 22; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 6; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 17; grid-row-start: 1;"></div><div class = "start" vx = "1" vy = "0" dvx = "-1" dvy = "1" style="grid-column-start: 21; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 13; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 9; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "-1" dvy = "1" style="grid-column-start: 18; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "-1" dvy = "1" style="grid-column-start: 2; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "1" dvy = "0" style="grid-column-start: 20; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 1; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 23; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 7; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "-1" dvy = "1" style="grid-column-start: 12; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 10; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 15; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "-1" dvy = "0" style="grid-column-start: 4; grid-row-start: 1;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 29;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "1" style="grid-column-start: 21; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 2;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "0" style="grid-column-start: 19; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 8;"></div><div class = "" vx = "1" vy = "0" dvx = "1" dvy = "-1" style="grid-column-start: 17; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 25;"></div><div class = "" vx = "0" vy = "4" dvx = "1" dvy = "0" style="grid-column-start: 21; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 21;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "0" style="grid-column-start: 19; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 8;"></div><div class = "" vx = "4" vy = "3" dvx = "-1" dvy = "0" style="grid-column-start: 31; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 28;"></div><div class = "" vx = "2" vy = "1" dvx = "1" dvy = "-1" style="grid-column-start: 23; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 26;"></div><div class = "" vx = "1" vy = "2" dvx = "-1" dvy = "0" style="grid-column-start: 21; grid-row-start: 8;"></div><div class = "" vx = "1" vy = "0" dvx = "0" dvy = "-1" style="grid-column-start: 16; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 6;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "1" style="grid-column-start: 2; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 10;"></div><div class = "" vx = "1" vy = "2" dvx = "-1" dvy = "1" style="grid-column-start: 6; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 22;"></div><div class = "" vx = "1" vy = "1" dvx = "0" dvy = "1" style="grid-column-start: 20; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 4;"></div><div class = "" vx = "1" vy = "1" dvx = "0" dvy = "-1" style="grid-column-start: 14; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 4;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "1" style="grid-column-start: 21; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 28;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "1" style="grid-column-start: 5; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 13;"></div><div class = "" vx = "1" vy = "2" dvx = "0" dvy = "1" style="grid-column-start: 3; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 4;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 19; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 29;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "0" style="grid-column-start: 21; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 23;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "0" style="grid-column-start: 19; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 21;"></div><div class = "" vx = "1" vy = "0" dvx = "-1" dvy = "-1" style="grid-column-start: 15; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 14;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "1" style="grid-column-start: 18; grid-row-start: 2;"></div><div class = "" vx = "2" vy = "3" dvx = "1" dvy = "-1" style="grid-column-start: 24; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 23;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "0" style="grid-column-start: 21; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 26;"></div><div class = "" vx = "1" vy = "2" dvx = "1" dvy = "0" style="grid-column-start: 22; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 22;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "0" style="grid-column-start: 5; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 9;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 12; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 28; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 23;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "1" style="grid-column-start: 21; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 2;"></div><div class = "" vx = "1" vy = "4" dvx = "1" dvy = "-1" style="grid-column-start: 22; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 17;"></div><div class = "" vx = "3" vy = "2" dvx = "1" dvy = "1" style="grid-column-start: 27; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 25; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 29; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 23; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 24;"></div><div class = "" vx = "2" vy = "2" dvx = "1" dvy = "-1" style="grid-column-start: 23; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 31; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 21; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 32; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 22; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 26; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 30; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 24; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 17; grid-row-start: 20;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "-1" style="grid-column-start: 6; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 20; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 19; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 18; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 28;"></div><div class = "" vx = "1" vy = "1" dvx = "0" dvy = "0" style="grid-column-start: 13; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 27; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 27;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 30;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 27;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 23;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 28;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 29;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 26;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 25;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 24;"></div><div class = "finish" style="grid-column-start: 32; grid-row-start: 22;"></div>
	</div>
	Finish <br> line
	</div>
	<div>Starting line</div>
</div>
</div>

	</div>
mimetext/htmlrootassigneelast_run_timestampA3*wpersist_js_state·has_pluto_hook_features§cell_id$4481fa33-1ff3-4778-8486-d4d8a15775cddepends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$1b02e593-d791-424c-b956-62cc480fcf40queued¤logsrunning¦outputbody<div class="markdown"><h5>Results Summary</h5>
<p>Unlike the other techniques, Monte Carlo ϵ-Soft requires selecting the parameter ϵ and the performance of each algorithm varies a lot with this parameter and the number of training episodes.  For a short training time of 1,000 episodes, small values of ϵ seem to perform better such as 0.01 or 0.02.  Under those conditions, performance of the policies is far better than random with mean episode lengths of 32 and 24 respectively.  Longer training improves the results but also requires changing ϵ and possibly introducing a decay rate so it can start high and approach 0 after a large number of episodes.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA"+persist_js_state·has_pluto_hook_features§cell_id$1b02e593-d791-424c-b956-62cc480fcf40depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$72e9721f-ee17-4557-b090-71728e6c22cequeued¤logsrunning¦outputbody+makelookup (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA$حpersist_js_state·has_pluto_hook_features§cell_id$72e9721f-ee17-4557-b090-71728e6c22cedepends_on_disabled_cells§runtime Bpublished_object_keysdepends_on_skipped_cells§errored$11723075-d1db-4512-abf2-3fe494a71a3bqueued¤logsrunning¦outputbody-check_policy (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA$persist_js_state·has_pluto_hook_features§cell_id$11723075-d1db-4512-abf2-3fe494a71a3bdepends_on_disabled_cells§runtime uʵpublished_object_keysdepends_on_skipped_cells§errored$059b1c0f-eb21-4a4a-8aed-64e9ac07b541queued¤logsrunning¦outputbody<div class="markdown"><p>Number of Episodes: <bond def="mces2" unique_id="HBhB843vhuLe"><span style='display: contents;'>
	<input type='number' min='1' step='1' max='10000000' value='1000'>
	<input type=submit id='ajycuyrqfj'>
	<script id='ajycuyrqfj'>

let key = "ajycuyrqfj"

let div = currentScript.parentElement
let button = currentScript.previousElementSibling
let input = div.firstElementChild
if(input === button) {
	return
}


let set_input_value = (() => {
	let result = null
	try {
	result = setBoundElementValueLikePluto
} catch (e) {
	result = ((input, new_value) => {
	// fallback in case https://github.com/fonsp/Pluto.jl/pull/1755 is not available
    if (new_value == null) {
        //@ts-ignore
        input.value = new_value
        return
    }
    if (input instanceof HTMLInputElement) {
        switch (input.type) {
            case "range":
            case "number": {
                if (input.valueAsNumber !== new_value) {
                    input.valueAsNumber = new_value
                }
                return
            }
            case "date": {
                if (input.valueAsDate == null || Number(input.valueAsDate) !== Number(new_value)) {
                    input.valueAsDate = new_value
                }
                return
            }
            case "checkbox": {
                if (input.checked !== new_value) {
                    input.checked = new_value
                }
                return
            }
            case "file": {
                // Can't set files :(
                return
            }
        }
    } else if (input instanceof HTMLSelectElement && input.multiple) {
        for (let option of Array.from(input.options)) {
            option.selected = new_value.includes(option.value)
        }
        return
    }
    //@ts-ignore
    if (input.value !== new_value) {
        //@ts-ignore
        input.value = new_value
    }
})
}
return result
})()



let private_value = null
let public_value = null




private_value = public_value = div.value
if(private_value != null) {
	set_input_value(input, private_value)
} else {

	// private_value = public_value = input.value
}

input.oninput = (e) => {
	e.stopPropagation()
}
const gen = Generators.input(input)

// If the child does not have an initial value, the `gen.next().value` promise will never resolve. If it does, then it resolves instantly.
let first_value = await Promise.any([
	gen.next().value,
	Promise.resolve(undefined)
])
private_value = public_value = first_value

;(async () => {
	while(true) {
		private_value = await gen.next().value
		// div.dispatchEvent(new CustomEvent("input", {}))
	}
})()

button.addEventListener("click", () => {
	public_value = private_value
	div.dispatchEvent(new CustomEvent("input", {}))
})


Object.defineProperty(div, 'value', {
	get: () => public_value,
	set: (newval) => {
		private_value = newval
		public_value = newval
		
		set_input_value(input, newval)
	},
	configurable: true,
});

</script></span></bond></p>
</div>mimetext/htmlrootassigneelast_run_timestampA3"persist_js_state·has_pluto_hook_features§cell_id$059b1c0f-eb21-4a4a-8aed-64e9ac07b541depends_on_disabled_cells§runtime ypublished_object_keysdepends_on_skipped_cells§errored$b2115f33-f8e2-452e-9b0e-90610f0f09b1queued¤logsrunning¦outputbody3make_random_policy (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA$mpersist_js_state·has_pluto_hook_features§cell_id$b2115f33-f8e2-452e-9b0e-90610f0f09b1depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$82284c63-2306-4469-9b1a-a5ec87037e79queued¤logsrunning¦outputbody S<div style = "display: flex; flex-wrap: wrap; flex-direction: row; width: 800px; background-color: white; color: black; align-items: center; justify-content: center;">
	<div style = "width: 50px;">Usable ace</div>
	<div>	<script id='plot_1'>
		// We start by putting all the variable interpolation here at the beginning
		// We have to convert all typedarrays in the layout to normal arrays. See Issue #25
		// We use lodash for this for compactness
		function removeTypedArray(o) {
			return _.isTypedArray(o) ? Array.from(o) :
			_.isPlainObject(o) ? _.mapValues(o, removeTypedArray) : 
			o
		}

		// Publish the plot object to JS
		let plot_obj = _.update(/* See the documentation for AbstractPlutoDingetjes.Display.published_to_js */ getPublishedObject("c6e0de0c-3901-11f0-234e-bd09c571f662/c2f9f46c95453d02"), "layout", removeTypedArray)
		// Get the plotly listeners
		const plotly_listeners = {}
		// Get the JS listeners
		const js_listeners = {}
		// Deal with eventual custom classes
		let custom_classlist = []


		// Load the plotly library
		let Plotly = undefined
		try {
			let _mod = await import("./plotlyjs/plotlyjs-2.26.2.min.js")
			Plotly = _mod.default
		} catch (e) {
			console.log("Local load failed, trying with the web esm.sh version")
			let _mod = await import("https://esm.sh/plotly.js-dist-min@2.26.2/es2022/plotly.js-dist-min.mjs")
			Plotly = _mod.default
		}

		// Check if we have to force local mathjax font cache
		if (false && window?.MathJax?.config?.svg?.fontCache === 'global') {
			window.MathJax.config.svg.fontCache = 'local'
		}

		// Flag to check if this cell was  manually ran or reactively ran
const firstRun = this ? false : true
const CONTAINER = this ?? html`<div class='plutoplotly-container'>`
const PLOT = CONTAINER.querySelector('.js-plotly-plot') ?? CONTAINER.appendChild(html`<div>`)
const parent = CONTAINER.parentElement
// We use a controller to remove event listeners upon invalidation
const controller = new AbortController()
// We have to add this to keep supporting @bind with the old API using PLOT
PLOT.addEventListener('input', (e) => {
	CONTAINER.value = PLOT.value
	if (e.bubbles) {
		return
	}
	CONTAINER.dispatchEvent(new CustomEvent('input'))
}, { signal: controller.signal })

	// This create the style subdiv on first run
	firstRun && CONTAINER.appendChild(html`
	<style>
	.plutoplotly-container {
		width: 100%;
		height: 100%;
		min-height: 0;
		min-width: 0;
	}
	.plutoplotly-container .js-plotly-plot .plotly div {
		margin: 0 auto; // This centers the plot
	}
	.plutoplotly-container.popped-out {
		overflow: auto;
		z-index: 1000;
		position: fixed;
		resize: both;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		border-top-left-radius: 0px;
		border-top-right-radius: 0px;
	}
	.plutoplotly-clipboard-header {
		display: flex;
		flex-flow: row wrap;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-top-left-radius: 12px;
		border-top-right-radius: 12px;
		position: fixed;
		z-index: 1001;
		cursor: move;
		transform: translate(0px, -100%);
		padding: 5px;
	}
	.plutoplotly-clipboard-header span {
		display: inline-block;
		flex: 1
	}
	.plutoplotly-clipboard-header.hidden {
		display: none;
	}
	.clipboard-span {
		position: relative;
	}
	.clipboard-value {
		padding-right: 5px;
		padding-left: 2px;
		cursor: text;
	}
	.clipboard-span.format {
		display: none;
	}
	.clipboard-span.filename {
		flex: 0 0 100%;
		text-align: center;
		border-top: 3px solid var(--kbd-border-color);
		margin-top: 5px;
		display: none;
	}
	.plutoplotly-container.filesave .clipboard-span.filename {
		display: inline-block;
	}
	.clipboard-value.filename {
		margin-left: 3px;
		text-align: left;
		min-width: min(60%, min-content);
	}
	.plutoplotly-container.filesave .clipboard-span.format {
		display: inline-flex;
	}
	.clipboard-span.format .label {
		flex: 0 0 0;
	}
	.clipboard-value.format {
		position: relative;
		flex: 1 0 auto;
		min-width: 30px;
		margin-right: 10px;
	}
	div.format-options {
		display: inline-flex;
		flex-flow: column;
		position: absolute;
		background: var(--main-bg-color);
		border-radius: 12px;
		padding-left: 3px;
		z-index: 2000;
	}
	div.format-options:hover {
		cursor: pointer;
		border: 3px solid var(--kbd-border-color);
		padding: 3px;
		transform: translate(-3px, -6px);
	}
	div.format-options .format-option {
		display: none;
	}
	div.format-options:hover .format-option {
		display: inline-block;
	}
	.format-option:not(.selected) {
		margin-top: 3px;
	}
	div.format-options .format-option.selected {
		order: -1;
		display: inline-block;
	}
	.format-option:hover {
		background-color: var(--kbd-border-color);
	}
	span.config-value {
		font-weight: normal;
		color: var(--pluto-output-color);
		display: none;
		position: absolute;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		transform: translate(0px, calc(-100% - 10px));
		padding: 5px;
	}
	.label {
		user-select: none;
	}
	.label:hover span.config-value {
		display: inline-block;
		min-width: 150px;
	}
	.clipboard-span.matching-config .label {
		color: var(--cm-macro-color);
		font-weight: bold;
	}
	.clipboard-span.different-config .label {
		color: var(--cm-tag-color);
		font-weight: bold;
	}
</style>
`)

let original_height = plot_obj.layout.height
let original_width = plot_obj.layout.width
// For the height we have to also put a fixed value in case the plot is put on a non-fixed-size container (like the default wrapper)
// We define a variable to check whether we still have to remove the fixed height
let remove_container_size = firstRun
let container_height = original_height ?? PLOT.container_height ?? 400
CONTAINER.style.height = container_height + 'px'

// We create a Promise version of setTimeout
function delay(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

// We import interact for dragging/resizing
const { default: interact } = await import('https://esm.sh/interactjs@1.10.19')


function getImageOptions() {
  const o = plot_obj.config.toImageButtonOptions ?? {};
  return {
    format: o.format ?? "png",
    width: o.width ?? original_width,
    height: o.height ?? original_height,
    scale: o.scale ?? 1,
    filename: o.filename ?? "newplot",
  };
}

const CLIPBOARD_HEADER =
  CONTAINER.querySelector(".plutoplotly-clipboard-header") ??
  CONTAINER.insertAdjacentElement(
    "afterbegin",
    html`<div class="plutoplotly-clipboard-header hidden">
      <span class="clipboard-span format"
        ><span class="label">Format:</span
        ><span class="clipboard-value format"></span
      ></span>
      <span class="clipboard-span width"
        ><span class="label">Width:</span
        ><span class="clipboard-value width"></span>px</span
      >
      <span class="clipboard-span height"
        ><span class="label">Height:</span
        ><span class="clipboard-value height"></span>px</span
      >
      <span class="clipboard-span scale"
        ><span class="label">Scale:</span
        ><span class="clipboard-value scale"></span
      ></span>
      <button class="clipboard-span set">Set</button>
      <button class="clipboard-span unset">Unset</button>
      <span class="clipboard-span filename"
        ><span class="label">Filename:</span
        ><span class="clipboard-value filename"></span
      ></span>
    </div>`
  );

function checkConfigSync(container) {
  const valid_classes = [
    "missing-config",
    "matching-config",
    "different-config",
  ];
  function setClass(cl) {
    for (const name of valid_classes) {
      container.classList.toggle(name, name == cl);
    }
  }
  // We use the custom getters we'll set up in the container
  const { ui_value, config_value, config_span, key } = container;
  if (config_value === undefined) {
    setClass("missing-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> is not present in the config.`;
  } else if (ui_value == config_value) {
    setClass("matching-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has the same value in the config and in the header.`;
  } else {
    setClass("different-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has a different value (<em>${config_value}</em>) in the config.`;
  }
  // Add info about setting and unsetting
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click on the label <em><b>once</b></em> to set the current UI value in the config.`
  );
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click <em><b>twice</b></em> to remove this key from the config.`
  );
}

const valid_formats = ["png", "svg", "webp", "jpeg", "full-json"];
function initializeUIValueSpan(span, key, value) {
  const container = span.closest(".clipboard-span");
  span.contentEditable = key === "format" ? "false" : "true";
  let parse = (x) => x;
  let update = (x) => (span.textContent = x);
  if (key === "width" || key === "height") {
    parse = (x) => Math.round(parseFloat(x));
  } else if (key === "scale") {
    parse = parseFloat;
  } else if (key === "format") {
    // We remove contentEditable
    span.contentEditable = "false";
    // Here we first add the subspans for each option
    const opts_div = span.appendChild(html`<div class="format-options"></div>`);
    for (const fmt of valid_formats) {
      const opt = opts_div.appendChild(
        html`<span class="format-option ${fmt}">${fmt}</span>`
      );
      opt.onclick = (e) => {
        span.value = opt.textContent;
      };
    }
    parse = (x) => {
      return valid_formats.includes(x) ? x : localValue;
    };
    update = (x) => {
      for (const opt of opts_div.children) {
        opt.classList.toggle("selected", opt.textContent === x);
      }
    };
  } else {
    // We only have filename here
  }
  let localValue;
  Object.defineProperty(span, "value", {
    get: () => {
      return localValue;
    },
    set: (val) => {
      if (val !== "") {
        localValue = parse(val);
      }
      update(localValue);
      checkConfigSync(container);
    },
  });
  // We also assign a listener so that the editable is blurred when enter is pressed
  span.onkeydown = (e) => {
    if (e.keyCode === 13) {
      e.preventDefault();
      span.blur();
    }
  };
  span.value = value;
}

function initializeConfigValueSpan(span, key) {
  // Here we mostly want to define the setter and getter
  const container = span.closest(".clipboard-span");
  Object.defineProperty(span, "value", {
    get: () => {
      return plot_obj.config.toImageButtonOptions[key];
    },
    set: (val) => {
      // if undefined is passed, we remove the entry from the options
      if (val === undefined) {
        delete plot_obj.config.toImageButtonOptions[key];
      } else {
        plot_obj.config.toImageButtonOptions[key] = val;
      }
      checkConfigSync(container);
    },
  });
}

const config_spans = {};
for (const [key, value] of Object.entries(getImageOptions())) {
  const container = CLIPBOARD_HEADER.querySelector(`.clipboard-span.${key}`);
  const label = container.querySelector(".label");
  // We give the label a function that on single click will set the current value and with double click will unset it
  label.onclick = DualClick(
    () => {
      container.config_value = container.ui_value;
    },
    (e) => {
      console.log("e", e);
      e.preventDefault();
      container.config_value = undefined;
    }
  );
  const ui_value_span = container.querySelector(".clipboard-value");
  const config_value_span =
    container.querySelector(".config-value") ??
    label.insertAdjacentElement(
      "afterbegin",
      html`<span class="config-value"></span>`
    );
  // Assing the two spans as properties of the containing span
  container.ui_span = ui_value_span;
  container.config_span = config_value_span;
  container.key = key;
  config_spans[key] = container;
  if (firstRun) {
    plot_obj.config.toImageButtonOptions =
      plot_obj.config.toImageButtonOptions ?? {};
    // We do the initialization of the value span
    initializeUIValueSpan(ui_value_span, key, value);
    // Then we initialize the config value
    initializeConfigValueSpan(config_value_span, key);
    // We put some convenience getters/setters
    // ui_value forward
    Object.defineProperty(container, "ui_value", {
      get: () => ui_value_span.value,
      set: (val) => {
        ui_value_span.value = val;
      },
    });
    // config_value forward
    Object.defineProperty(container, "config_value", {
      get: () => config_value_span.value,
      set: (val) => {
        config_value_span.value = val;
      },
    });
  }
}

// These objects will contain the default value

// This code updates the image options in the PLOT config with the provided ones
function setImageOptions(o) {
  for (const [key, container] of Object.entries(config_spans)) {
    container.config_value = o[key];
  }
}
function unsetImageOptions() {
  setImageOptions({});
}

const set_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.set");
const unset_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.unset");
if (firstRun) {
  set_button.onclick = (e) => {
    for (const container of Object.values(config_spans)) {
      container.config_value = container.ui_value;
    }
  };
  unset_button.onclick = unsetImageOptions;
}

// We add a function to check if the clipboard is popped out
CONTAINER.isPoppedOut = () => {
  return CONTAINER.classList.contains("popped-out");
};

CLIPBOARD_HEADER.onmousedown = function (event) {
  if (event.target.matches("span.clipboard-value")) {
    console.log("We don't move!");
    return;
  }
  const start = {
    left: parseFloat(CONTAINER.style.left),
    top: parseFloat(CONTAINER.style.top),
    X: event.pageX,
    Y: event.pageY,
  };
  function moveAt(event, start) {
    const top = event.pageY - start.Y + start.top + "px";
    const left = event.pageX - start.X + start.left + "px";
    CLIPBOARD_HEADER.style.left = left;
    CONTAINER.style.left = left;
    CONTAINER.style.top = top;
  }

  // move our absolutely positioned ball under the pointer
  moveAt(event, start);
  function onMouseMove(event) {
    moveAt(event, start);
  }

  // We use this to remove the mousemove when clicking outside of the container
  const controller = new AbortController();

  // move the container on mousemove
  document.addEventListener("mousemove", onMouseMove, {
    signal: controller.signal,
  });
  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        cleanUp();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );

  function cleanUp() {
    console.log("cleaning up the plot move listener");
    controller.abort();
    CLIPBOARD_HEADER.onmouseup = null;
  }

  // (3) drop the ball, remove unneeded handlers
  CLIPBOARD_HEADER.onmouseup = cleanUp;
};

function sendToClipboard(blob) {
  if (!navigator.clipboard) {
    alert(
      "The Clipboard API does not seem to be available, make sure the Pluto notebook is being used from either localhost or an https source."
    );
  }
  navigator.clipboard
    .write([
      new ClipboardItem({
        // The key is determined dynamically based on the blob's type.
        [blob.type]: blob,
      }),
    ])
    .then(
      function () {
        console.log("Async: Copying to clipboard was successful!");
      },
      function (err) {
        console.error("Async: Could not copy text: ", err);
      }
    );
}

function copyImageToClipboard() {
  // We extract the image options from the provided parameters (if they exist)
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key. We also ignore format because the clipboard only supports png.
    if (val === undefined || key === "format") {
      continue;
    }
    config[key] = val;
  }
  Plotly.toImage(PLOT, config).then(function (dataUrl) {
    fetch(dataUrl)
      .then((res) => res.blob())
      .then((blob) => {
        const paste_receiver = document.querySelector('paste-receiver.plutoplotly')
        if (paste_receiver) {
          paste_receiver.attachImage(dataUrl, CONTAINER)
        }
        sendToClipboard(blob)
      });
  });
}

function saveImageToFile() {
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key.
    if (val === undefined) {
      continue;
    }
    config[key] = val;
  }
  Plotly.downloadImage(PLOT, config);
}

let container_rect = { width: 0, height: 0, top: 0, left: 0 };
function unpop_container(cl) {
  CONTAINER.classList.toggle("popped-out", false);
  CONTAINER.classList.toggle(cl, false);
  // We fix the height back to the value it had before popout, also setting the flag to signal that upon first resize we remove the fixed inline-style
  CONTAINER.style.height = container_rect.height + "px";
  remove_container_size = true;
  // We set the other fixed inline-styles to null
  CONTAINER.style.width = "";
  CONTAINER.style.top = "";
  CONTAINER.style.left = "";
  // We also remove the CLIPBOARD_HEADER
  CLIPBOARD_HEADER.style.width = "";
  CLIPBOARD_HEADER.style.left = "";
  // Finally we remove the hidden class to the header
  CLIPBOARD_HEADER.classList.toggle("hidden", true);
  return;
}
function popout_container(opts) {
  const cl = opts?.cl;
  const target_container_size = opts?.target_container_size ?? {};
  const target_plot_size = opts?.target_plot_size ?? {};
  if (CONTAINER.isPoppedOut()) {
    return unpop_container(cl);
  }
  CONTAINER.classList.toggle(cl, cl === undefined ? false : true);
  // We extract the current size of the container, save them and fix them
  const { width, height, top, left } = CONTAINER.getBoundingClientRect();
  container_rect = { width, height, top, left };
  // We save the current plot size before we pop as it will fill the screen
  const current_plot_size = {
    width: PLOT._fullLayout.width,
    height: PLOT._fullLayout.height,
  };
  // We have to save the pad data before popping so we can resize precisely
  const pad = {};
  pad.unpopped = getSizeData().container_pad;
  CONTAINER.classList.toggle("popped-out", true);
  pad.popped = getSizeData().container_pad;
  // We do top and left based on the current rect
  for (const key of ["top", "left"]) {
    const start_val = target_container_size[key] ?? container_rect[key];
    let offset = 0;
    for (const kind of ["padding", "border"]) {
      offset += pad.popped[kind][key] - pad.unpopped[kind][key];
    }
    CONTAINER.style[key] = start_val - offset + "px";
    if (key === "left") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  // We compute the width and height depending on eventual config data
  const csz = computeContainerSize({
    width:
      target_plot_size.width ??
      config_spans.width.config_value ??
      current_plot_size.width,
    height:
      target_plot_size.height ??
      config_spans.height.config_value ??
      current_plot_size.height,
  });
  for (const key of ["width", "height"]) {
    const val = target_container_size[key] ?? csz[key];
    CONTAINER.style[key] = val + "px";
    if (key === "width") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  CLIPBOARD_HEADER.classList.toggle("hidden", false);
  const controller = new AbortController();

  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        unpop_container();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );
}

CONTAINER.popOut = popout_container;

function DualClick(single_func, dbl_func) {
  let nclicks = 0;
  return function (...args) {
    nclicks += 1;
    if (nclicks > 1) {
      dbl_func(...args);
      nclicks = 0;
    } else {
      delay(300).then(() => {
        if (nclicks == 1) {
          single_func(...args);
        }
        nclicks = 0;
      });
    }
  };
}

// We remove the default download image button
plot_obj.config.modeBarButtonsToRemove = _.union(
  plot_obj.config.modeBarButtonsToRemove,
  ["toImage"]
);
// We add the custom button to the modebar
plot_obj.config.modeBarButtonsToAdd = _.union(
  plot_obj.config.modeBarButtonsToAdd,
  [
    {
      name: "Copy PNG to Clipboard",
      icon: {
        height: 520,
        width: 520,
        path: "M280 64h40c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128C0 92.7 28.7 64 64 64h40 9.6C121 27.5 153.3 0 192 0s71 27.5 78.4 64H280zM64 112c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16H320c8.8 0 16-7.2 16-16V128c0-8.8-7.2-16-16-16H304v24c0 13.3-10.7 24-24 24H192 104c-13.3 0-24-10.7-24-24V112H64zm128-8a24 24 0 1 0 0-48 24 24 0 1 0 0 48z",
      },
      direction: "up",
      click: DualClick(copyImageToClipboard, () => {
        popout_container();
      }),
    },
    {
      name: "Download Image",
      icon: Plotly.Icons.camera,
      direction: "up",
      click: DualClick(saveImageToFile, () => {
        popout_container({ cl: "filesave" });
      }),
    },
  ]
);

function getOffsetData(el) {
  let cs = window.getComputedStyle(el, null);
  const odata = {
    padding: {
      left: parseFloat(cs.paddingLeft),
      right: parseFloat(cs.paddingRight),
      top: parseFloat(cs.paddingTop),
      bottom: parseFloat(cs.paddingBottom),
      width: parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight),
      height: parseFloat(cs.paddingTop) + parseFloat(cs.paddingBottom),
    },
    border: {
      left: parseFloat(cs.borderLeftWidth),
      right: parseFloat(cs.borderRightWidth),
      top: parseFloat(cs.borderTopWidth),
      bottom: parseFloat(cs.borderBottomWidth),
      width: parseFloat(cs.borderLeftWidth) + parseFloat(cs.borderRightWidth),
      height: parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth),
    }
  };
  if (el === PLOT) {
    // For the PLOT we also want to take into account the offset
    odata.offset = {
      top: PLOT.offsetParent == CONTAINER ? PLOT.offsetTop : 0,
      left: PLOT.offsetParent == CONTAINER ? PLOT.offsetLeft : 0,
    }
  }
  return odata;
}
function getSizeData() {
  const data = {
    plot_pad: getOffsetData(PLOT),
    plot_rect: PLOT.getBoundingClientRect(),
    container_pad: getOffsetData(CONTAINER),
    container_rect: CONTAINER.getBoundingClientRect(),
  };
  return data;
}
function computeContainerSize({ width, height }, sizeData = getSizeData()) {
  const computed_size = computePlotSize(sizeData);
  const offsets = computed_size.offsets;

  const plot_data = {
    width: width ?? computed_size.width,
    height: height ?? computed_size.height,
  };

  return {
    width: (width ?? computed_size.width) + offsets.width,
    height: (height ?? computed_size.height) + offsets.height,
    noChange: width == computed_size.width && height == computed_size.height,
  }
}

// This function will change the container size so that the resulting plot will be matching the provided specs
function changeContainerSize({ width, height }, sizeData = getSizeData()) {
  if (!CONTAINER.isPoppedOut()) {
    console.log("Tried to change container size when not popped, ignoring");
    return;
  }

  const csz = computeContainerSize({ width, height }, sizeData);

  if (csz.noChange) {
    console.log("Size is the same as current, ignoring");
    return
  }
  // We are now going to set he width and height of the container
  for (const key of ["width", "height"]) {
    CONTAINER.style[key] = csz[key] + "px";
  }
}
// We now create the function that will update the plot based on the values specified
function updateFromHeader() {
  const header_data = {
    height: config_spans.height.ui_value,
    width: config_spans.width.ui_value,
  };
  changeContainerSize(header_data);
}
// We assign this function to the onblur event of width and height
if (firstRun) {
  for (const container of Object.values(config_spans)) {
    container.ui_span.onblur = (e) => {
      container.ui_value = container.ui_span.textContent;
      updateFromHeader();
    };
  }
}
// This function computes the plot size to use for relayout as a function of the container size
function computePlotSize(data = getSizeData()) {
  // Remove Padding
  const { container_pad, plot_pad, container_rect } = data;
  const offsets = {
    width:
      plot_pad.padding.width +
      plot_pad.border.width +
      plot_pad.offset.left +
      container_pad.padding.width +
      container_pad.border.width,
    height:
      plot_pad.padding.height +
      plot_pad.border.height +
      plot_pad.offset.top +
      container_pad.padding.height +
      container_pad.border.height,
  };
  const sz = {
    width: Math.round(container_rect.width - offsets.width),
    height: Math.round(container_rect.height - offsets.height),
    offsets,
  };
  return sz;
}

// Create the resizeObserver to make the plot even more responsive! :magic:
const resizeObserver = new ResizeObserver((entries) => {
  const sizeData = getSizeData();
  const {container_rect, container_pad} = sizeData;
  let plot_size = computePlotSize(sizeData);
  // We save the height in the PLOT object
  PLOT.container_height = container_rect.height;
  // We deal with some stuff if the container is poppped
  CLIPBOARD_HEADER.style.width = container_rect.width + "px";
  CLIPBOARD_HEADER.style.left = container_rect.left + "px";
  config_spans.height.ui_value = plot_size.height;
  config_spans.width.ui_value = plot_size.width;
  /* 
		The addition of the invalid argument `plutoresize` seems to fix the problem with calling `relayout` simply with `{autosize: true}` as update breaking mouse relayout events tracking. 
		See https://github.com/plotly/plotly.js/issues/6156 for details
		*/
  let config = {
    // If this is popped out, we ignore the original width/height
    width: (CONTAINER.isPoppedOut() ? undefined : original_width) ?? plot_size.width,
    height: (CONTAINER.isPoppedOut() ? undefined : original_height) ?? plot_size.height,
    plutoresize: true,
  };
  Plotly.relayout(PLOT, config).then(() => {
    if (remove_container_size && !CONTAINER.isPoppedOut()) {
      // This is needed to avoid the first resize upon plot creation to already be without a fixed height
      CONTAINER.style.height = "";
      CONTAINER.style.width = "";
      remove_container_size = false;
    }
  });
});

resizeObserver.observe(CONTAINER);


Plotly.react(PLOT, plot_obj).then(() => {
	// Assign the Plotly event listeners
	for (const [key, listener_vec] of Object.entries(plotly_listeners)) {
		for (const listener of listener_vec) {
			PLOT.on(key, listener)
		}
	}
	// Assign the JS event listeners
	for (const [key, listener_vec] of Object.entries(js_listeners)) {
		for (const listener of listener_vec) {
			PLOT.addEventListener(key, listener, {
				signal: controller.signal
			})
		}
	}
}
)


invalidation.then(() => {
	// Remove all plotly listeners
	PLOT.removeAllListeners()
	// Remove all JS listeners
	controller.abort()
	// Remove the resizeObserver
	resizeObserver.disconnect()
})



		return CONTAINER
	</script>
</div> 
	<div>	<script id='plot_2'>
		// We start by putting all the variable interpolation here at the beginning
		// We have to convert all typedarrays in the layout to normal arrays. See Issue #25
		// We use lodash for this for compactness
		function removeTypedArray(o) {
			return _.isTypedArray(o) ? Array.from(o) :
			_.isPlainObject(o) ? _.mapValues(o, removeTypedArray) : 
			o
		}

		// Publish the plot object to JS
		let plot_obj = _.update(/* See the documentation for AbstractPlutoDingetjes.Display.published_to_js */ getPublishedObject("c6e0de0c-3901-11f0-234e-bd09c571f662/cc789608a7b2df16"), "layout", removeTypedArray)
		// Get the plotly listeners
		const plotly_listeners = {}
		// Get the JS listeners
		const js_listeners = {}
		// Deal with eventual custom classes
		let custom_classlist = []


		// Load the plotly library
		let Plotly = undefined
		try {
			let _mod = await import("./plotlyjs/plotlyjs-2.26.2.min.js")
			Plotly = _mod.default
		} catch (e) {
			console.log("Local load failed, trying with the web esm.sh version")
			let _mod = await import("https://esm.sh/plotly.js-dist-min@2.26.2/es2022/plotly.js-dist-min.mjs")
			Plotly = _mod.default
		}

		// Check if we have to force local mathjax font cache
		if (false && window?.MathJax?.config?.svg?.fontCache === 'global') {
			window.MathJax.config.svg.fontCache = 'local'
		}

		// Flag to check if this cell was  manually ran or reactively ran
const firstRun = this ? false : true
const CONTAINER = this ?? html`<div class='plutoplotly-container'>`
const PLOT = CONTAINER.querySelector('.js-plotly-plot') ?? CONTAINER.appendChild(html`<div>`)
const parent = CONTAINER.parentElement
// We use a controller to remove event listeners upon invalidation
const controller = new AbortController()
// We have to add this to keep supporting @bind with the old API using PLOT
PLOT.addEventListener('input', (e) => {
	CONTAINER.value = PLOT.value
	if (e.bubbles) {
		return
	}
	CONTAINER.dispatchEvent(new CustomEvent('input'))
}, { signal: controller.signal })

	// This create the style subdiv on first run
	firstRun && CONTAINER.appendChild(html`
	<style>
	.plutoplotly-container {
		width: 100%;
		height: 100%;
		min-height: 0;
		min-width: 0;
	}
	.plutoplotly-container .js-plotly-plot .plotly div {
		margin: 0 auto; // This centers the plot
	}
	.plutoplotly-container.popped-out {
		overflow: auto;
		z-index: 1000;
		position: fixed;
		resize: both;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		border-top-left-radius: 0px;
		border-top-right-radius: 0px;
	}
	.plutoplotly-clipboard-header {
		display: flex;
		flex-flow: row wrap;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-top-left-radius: 12px;
		border-top-right-radius: 12px;
		position: fixed;
		z-index: 1001;
		cursor: move;
		transform: translate(0px, -100%);
		padding: 5px;
	}
	.plutoplotly-clipboard-header span {
		display: inline-block;
		flex: 1
	}
	.plutoplotly-clipboard-header.hidden {
		display: none;
	}
	.clipboard-span {
		position: relative;
	}
	.clipboard-value {
		padding-right: 5px;
		padding-left: 2px;
		cursor: text;
	}
	.clipboard-span.format {
		display: none;
	}
	.clipboard-span.filename {
		flex: 0 0 100%;
		text-align: center;
		border-top: 3px solid var(--kbd-border-color);
		margin-top: 5px;
		display: none;
	}
	.plutoplotly-container.filesave .clipboard-span.filename {
		display: inline-block;
	}
	.clipboard-value.filename {
		margin-left: 3px;
		text-align: left;
		min-width: min(60%, min-content);
	}
	.plutoplotly-container.filesave .clipboard-span.format {
		display: inline-flex;
	}
	.clipboard-span.format .label {
		flex: 0 0 0;
	}
	.clipboard-value.format {
		position: relative;
		flex: 1 0 auto;
		min-width: 30px;
		margin-right: 10px;
	}
	div.format-options {
		display: inline-flex;
		flex-flow: column;
		position: absolute;
		background: var(--main-bg-color);
		border-radius: 12px;
		padding-left: 3px;
		z-index: 2000;
	}
	div.format-options:hover {
		cursor: pointer;
		border: 3px solid var(--kbd-border-color);
		padding: 3px;
		transform: translate(-3px, -6px);
	}
	div.format-options .format-option {
		display: none;
	}
	div.format-options:hover .format-option {
		display: inline-block;
	}
	.format-option:not(.selected) {
		margin-top: 3px;
	}
	div.format-options .format-option.selected {
		order: -1;
		display: inline-block;
	}
	.format-option:hover {
		background-color: var(--kbd-border-color);
	}
	span.config-value {
		font-weight: normal;
		color: var(--pluto-output-color);
		display: none;
		position: absolute;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		transform: translate(0px, calc(-100% - 10px));
		padding: 5px;
	}
	.label {
		user-select: none;
	}
	.label:hover span.config-value {
		display: inline-block;
		min-width: 150px;
	}
	.clipboard-span.matching-config .label {
		color: var(--cm-macro-color);
		font-weight: bold;
	}
	.clipboard-span.different-config .label {
		color: var(--cm-tag-color);
		font-weight: bold;
	}
</style>
`)

let original_height = plot_obj.layout.height
let original_width = plot_obj.layout.width
// For the height we have to also put a fixed value in case the plot is put on a non-fixed-size container (like the default wrapper)
// We define a variable to check whether we still have to remove the fixed height
let remove_container_size = firstRun
let container_height = original_height ?? PLOT.container_height ?? 400
CONTAINER.style.height = container_height + 'px'

// We create a Promise version of setTimeout
function delay(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

// We import interact for dragging/resizing
const { default: interact } = await import('https://esm.sh/interactjs@1.10.19')


function getImageOptions() {
  const o = plot_obj.config.toImageButtonOptions ?? {};
  return {
    format: o.format ?? "png",
    width: o.width ?? original_width,
    height: o.height ?? original_height,
    scale: o.scale ?? 1,
    filename: o.filename ?? "newplot",
  };
}

const CLIPBOARD_HEADER =
  CONTAINER.querySelector(".plutoplotly-clipboard-header") ??
  CONTAINER.insertAdjacentElement(
    "afterbegin",
    html`<div class="plutoplotly-clipboard-header hidden">
      <span class="clipboard-span format"
        ><span class="label">Format:</span
        ><span class="clipboard-value format"></span
      ></span>
      <span class="clipboard-span width"
        ><span class="label">Width:</span
        ><span class="clipboard-value width"></span>px</span
      >
      <span class="clipboard-span height"
        ><span class="label">Height:</span
        ><span class="clipboard-value height"></span>px</span
      >
      <span class="clipboard-span scale"
        ><span class="label">Scale:</span
        ><span class="clipboard-value scale"></span
      ></span>
      <button class="clipboard-span set">Set</button>
      <button class="clipboard-span unset">Unset</button>
      <span class="clipboard-span filename"
        ><span class="label">Filename:</span
        ><span class="clipboard-value filename"></span
      ></span>
    </div>`
  );

function checkConfigSync(container) {
  const valid_classes = [
    "missing-config",
    "matching-config",
    "different-config",
  ];
  function setClass(cl) {
    for (const name of valid_classes) {
      container.classList.toggle(name, name == cl);
    }
  }
  // We use the custom getters we'll set up in the container
  const { ui_value, config_value, config_span, key } = container;
  if (config_value === undefined) {
    setClass("missing-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> is not present in the config.`;
  } else if (ui_value == config_value) {
    setClass("matching-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has the same value in the config and in the header.`;
  } else {
    setClass("different-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has a different value (<em>${config_value}</em>) in the config.`;
  }
  // Add info about setting and unsetting
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click on the label <em><b>once</b></em> to set the current UI value in the config.`
  );
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click <em><b>twice</b></em> to remove this key from the config.`
  );
}

const valid_formats = ["png", "svg", "webp", "jpeg", "full-json"];
function initializeUIValueSpan(span, key, value) {
  const container = span.closest(".clipboard-span");
  span.contentEditable = key === "format" ? "false" : "true";
  let parse = (x) => x;
  let update = (x) => (span.textContent = x);
  if (key === "width" || key === "height") {
    parse = (x) => Math.round(parseFloat(x));
  } else if (key === "scale") {
    parse = parseFloat;
  } else if (key === "format") {
    // We remove contentEditable
    span.contentEditable = "false";
    // Here we first add the subspans for each option
    const opts_div = span.appendChild(html`<div class="format-options"></div>`);
    for (const fmt of valid_formats) {
      const opt = opts_div.appendChild(
        html`<span class="format-option ${fmt}">${fmt}</span>`
      );
      opt.onclick = (e) => {
        span.value = opt.textContent;
      };
    }
    parse = (x) => {
      return valid_formats.includes(x) ? x : localValue;
    };
    update = (x) => {
      for (const opt of opts_div.children) {
        opt.classList.toggle("selected", opt.textContent === x);
      }
    };
  } else {
    // We only have filename here
  }
  let localValue;
  Object.defineProperty(span, "value", {
    get: () => {
      return localValue;
    },
    set: (val) => {
      if (val !== "") {
        localValue = parse(val);
      }
      update(localValue);
      checkConfigSync(container);
    },
  });
  // We also assign a listener so that the editable is blurred when enter is pressed
  span.onkeydown = (e) => {
    if (e.keyCode === 13) {
      e.preventDefault();
      span.blur();
    }
  };
  span.value = value;
}

function initializeConfigValueSpan(span, key) {
  // Here we mostly want to define the setter and getter
  const container = span.closest(".clipboard-span");
  Object.defineProperty(span, "value", {
    get: () => {
      return plot_obj.config.toImageButtonOptions[key];
    },
    set: (val) => {
      // if undefined is passed, we remove the entry from the options
      if (val === undefined) {
        delete plot_obj.config.toImageButtonOptions[key];
      } else {
        plot_obj.config.toImageButtonOptions[key] = val;
      }
      checkConfigSync(container);
    },
  });
}

const config_spans = {};
for (const [key, value] of Object.entries(getImageOptions())) {
  const container = CLIPBOARD_HEADER.querySelector(`.clipboard-span.${key}`);
  const label = container.querySelector(".label");
  // We give the label a function that on single click will set the current value and with double click will unset it
  label.onclick = DualClick(
    () => {
      container.config_value = container.ui_value;
    },
    (e) => {
      console.log("e", e);
      e.preventDefault();
      container.config_value = undefined;
    }
  );
  const ui_value_span = container.querySelector(".clipboard-value");
  const config_value_span =
    container.querySelector(".config-value") ??
    label.insertAdjacentElement(
      "afterbegin",
      html`<span class="config-value"></span>`
    );
  // Assing the two spans as properties of the containing span
  container.ui_span = ui_value_span;
  container.config_span = config_value_span;
  container.key = key;
  config_spans[key] = container;
  if (firstRun) {
    plot_obj.config.toImageButtonOptions =
      plot_obj.config.toImageButtonOptions ?? {};
    // We do the initialization of the value span
    initializeUIValueSpan(ui_value_span, key, value);
    // Then we initialize the config value
    initializeConfigValueSpan(config_value_span, key);
    // We put some convenience getters/setters
    // ui_value forward
    Object.defineProperty(container, "ui_value", {
      get: () => ui_value_span.value,
      set: (val) => {
        ui_value_span.value = val;
      },
    });
    // config_value forward
    Object.defineProperty(container, "config_value", {
      get: () => config_value_span.value,
      set: (val) => {
        config_value_span.value = val;
      },
    });
  }
}

// These objects will contain the default value

// This code updates the image options in the PLOT config with the provided ones
function setImageOptions(o) {
  for (const [key, container] of Object.entries(config_spans)) {
    container.config_value = o[key];
  }
}
function unsetImageOptions() {
  setImageOptions({});
}

const set_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.set");
const unset_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.unset");
if (firstRun) {
  set_button.onclick = (e) => {
    for (const container of Object.values(config_spans)) {
      container.config_value = container.ui_value;
    }
  };
  unset_button.onclick = unsetImageOptions;
}

// We add a function to check if the clipboard is popped out
CONTAINER.isPoppedOut = () => {
  return CONTAINER.classList.contains("popped-out");
};

CLIPBOARD_HEADER.onmousedown = function (event) {
  if (event.target.matches("span.clipboard-value")) {
    console.log("We don't move!");
    return;
  }
  const start = {
    left: parseFloat(CONTAINER.style.left),
    top: parseFloat(CONTAINER.style.top),
    X: event.pageX,
    Y: event.pageY,
  };
  function moveAt(event, start) {
    const top = event.pageY - start.Y + start.top + "px";
    const left = event.pageX - start.X + start.left + "px";
    CLIPBOARD_HEADER.style.left = left;
    CONTAINER.style.left = left;
    CONTAINER.style.top = top;
  }

  // move our absolutely positioned ball under the pointer
  moveAt(event, start);
  function onMouseMove(event) {
    moveAt(event, start);
  }

  // We use this to remove the mousemove when clicking outside of the container
  const controller = new AbortController();

  // move the container on mousemove
  document.addEventListener("mousemove", onMouseMove, {
    signal: controller.signal,
  });
  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        cleanUp();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );

  function cleanUp() {
    console.log("cleaning up the plot move listener");
    controller.abort();
    CLIPBOARD_HEADER.onmouseup = null;
  }

  // (3) drop the ball, remove unneeded handlers
  CLIPBOARD_HEADER.onmouseup = cleanUp;
};

function sendToClipboard(blob) {
  if (!navigator.clipboard) {
    alert(
      "The Clipboard API does not seem to be available, make sure the Pluto notebook is being used from either localhost or an https source."
    );
  }
  navigator.clipboard
    .write([
      new ClipboardItem({
        // The key is determined dynamically based on the blob's type.
        [blob.type]: blob,
      }),
    ])
    .then(
      function () {
        console.log("Async: Copying to clipboard was successful!");
      },
      function (err) {
        console.error("Async: Could not copy text: ", err);
      }
    );
}

function copyImageToClipboard() {
  // We extract the image options from the provided parameters (if they exist)
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key. We also ignore format because the clipboard only supports png.
    if (val === undefined || key === "format") {
      continue;
    }
    config[key] = val;
  }
  Plotly.toImage(PLOT, config).then(function (dataUrl) {
    fetch(dataUrl)
      .then((res) => res.blob())
      .then((blob) => {
        const paste_receiver = document.querySelector('paste-receiver.plutoplotly')
        if (paste_receiver) {
          paste_receiver.attachImage(dataUrl, CONTAINER)
        }
        sendToClipboard(blob)
      });
  });
}

function saveImageToFile() {
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key.
    if (val === undefined) {
      continue;
    }
    config[key] = val;
  }
  Plotly.downloadImage(PLOT, config);
}

let container_rect = { width: 0, height: 0, top: 0, left: 0 };
function unpop_container(cl) {
  CONTAINER.classList.toggle("popped-out", false);
  CONTAINER.classList.toggle(cl, false);
  // We fix the height back to the value it had before popout, also setting the flag to signal that upon first resize we remove the fixed inline-style
  CONTAINER.style.height = container_rect.height + "px";
  remove_container_size = true;
  // We set the other fixed inline-styles to null
  CONTAINER.style.width = "";
  CONTAINER.style.top = "";
  CONTAINER.style.left = "";
  // We also remove the CLIPBOARD_HEADER
  CLIPBOARD_HEADER.style.width = "";
  CLIPBOARD_HEADER.style.left = "";
  // Finally we remove the hidden class to the header
  CLIPBOARD_HEADER.classList.toggle("hidden", true);
  return;
}
function popout_container(opts) {
  const cl = opts?.cl;
  const target_container_size = opts?.target_container_size ?? {};
  const target_plot_size = opts?.target_plot_size ?? {};
  if (CONTAINER.isPoppedOut()) {
    return unpop_container(cl);
  }
  CONTAINER.classList.toggle(cl, cl === undefined ? false : true);
  // We extract the current size of the container, save them and fix them
  const { width, height, top, left } = CONTAINER.getBoundingClientRect();
  container_rect = { width, height, top, left };
  // We save the current plot size before we pop as it will fill the screen
  const current_plot_size = {
    width: PLOT._fullLayout.width,
    height: PLOT._fullLayout.height,
  };
  // We have to save the pad data before popping so we can resize precisely
  const pad = {};
  pad.unpopped = getSizeData().container_pad;
  CONTAINER.classList.toggle("popped-out", true);
  pad.popped = getSizeData().container_pad;
  // We do top and left based on the current rect
  for (const key of ["top", "left"]) {
    const start_val = target_container_size[key] ?? container_rect[key];
    let offset = 0;
    for (const kind of ["padding", "border"]) {
      offset += pad.popped[kind][key] - pad.unpopped[kind][key];
    }
    CONTAINER.style[key] = start_val - offset + "px";
    if (key === "left") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  // We compute the width and height depending on eventual config data
  const csz = computeContainerSize({
    width:
      target_plot_size.width ??
      config_spans.width.config_value ??
      current_plot_size.width,
    height:
      target_plot_size.height ??
      config_spans.height.config_value ??
      current_plot_size.height,
  });
  for (const key of ["width", "height"]) {
    const val = target_container_size[key] ?? csz[key];
    CONTAINER.style[key] = val + "px";
    if (key === "width") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  CLIPBOARD_HEADER.classList.toggle("hidden", false);
  const controller = new AbortController();

  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        unpop_container();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );
}

CONTAINER.popOut = popout_container;

function DualClick(single_func, dbl_func) {
  let nclicks = 0;
  return function (...args) {
    nclicks += 1;
    if (nclicks > 1) {
      dbl_func(...args);
      nclicks = 0;
    } else {
      delay(300).then(() => {
        if (nclicks == 1) {
          single_func(...args);
        }
        nclicks = 0;
      });
    }
  };
}

// We remove the default download image button
plot_obj.config.modeBarButtonsToRemove = _.union(
  plot_obj.config.modeBarButtonsToRemove,
  ["toImage"]
);
// We add the custom button to the modebar
plot_obj.config.modeBarButtonsToAdd = _.union(
  plot_obj.config.modeBarButtonsToAdd,
  [
    {
      name: "Copy PNG to Clipboard",
      icon: {
        height: 520,
        width: 520,
        path: "M280 64h40c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128C0 92.7 28.7 64 64 64h40 9.6C121 27.5 153.3 0 192 0s71 27.5 78.4 64H280zM64 112c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16H320c8.8 0 16-7.2 16-16V128c0-8.8-7.2-16-16-16H304v24c0 13.3-10.7 24-24 24H192 104c-13.3 0-24-10.7-24-24V112H64zm128-8a24 24 0 1 0 0-48 24 24 0 1 0 0 48z",
      },
      direction: "up",
      click: DualClick(copyImageToClipboard, () => {
        popout_container();
      }),
    },
    {
      name: "Download Image",
      icon: Plotly.Icons.camera,
      direction: "up",
      click: DualClick(saveImageToFile, () => {
        popout_container({ cl: "filesave" });
      }),
    },
  ]
);

function getOffsetData(el) {
  let cs = window.getComputedStyle(el, null);
  const odata = {
    padding: {
      left: parseFloat(cs.paddingLeft),
      right: parseFloat(cs.paddingRight),
      top: parseFloat(cs.paddingTop),
      bottom: parseFloat(cs.paddingBottom),
      width: parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight),
      height: parseFloat(cs.paddingTop) + parseFloat(cs.paddingBottom),
    },
    border: {
      left: parseFloat(cs.borderLeftWidth),
      right: parseFloat(cs.borderRightWidth),
      top: parseFloat(cs.borderTopWidth),
      bottom: parseFloat(cs.borderBottomWidth),
      width: parseFloat(cs.borderLeftWidth) + parseFloat(cs.borderRightWidth),
      height: parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth),
    }
  };
  if (el === PLOT) {
    // For the PLOT we also want to take into account the offset
    odata.offset = {
      top: PLOT.offsetParent == CONTAINER ? PLOT.offsetTop : 0,
      left: PLOT.offsetParent == CONTAINER ? PLOT.offsetLeft : 0,
    }
  }
  return odata;
}
function getSizeData() {
  const data = {
    plot_pad: getOffsetData(PLOT),
    plot_rect: PLOT.getBoundingClientRect(),
    container_pad: getOffsetData(CONTAINER),
    container_rect: CONTAINER.getBoundingClientRect(),
  };
  return data;
}
function computeContainerSize({ width, height }, sizeData = getSizeData()) {
  const computed_size = computePlotSize(sizeData);
  const offsets = computed_size.offsets;

  const plot_data = {
    width: width ?? computed_size.width,
    height: height ?? computed_size.height,
  };

  return {
    width: (width ?? computed_size.width) + offsets.width,
    height: (height ?? computed_size.height) + offsets.height,
    noChange: width == computed_size.width && height == computed_size.height,
  }
}

// This function will change the container size so that the resulting plot will be matching the provided specs
function changeContainerSize({ width, height }, sizeData = getSizeData()) {
  if (!CONTAINER.isPoppedOut()) {
    console.log("Tried to change container size when not popped, ignoring");
    return;
  }

  const csz = computeContainerSize({ width, height }, sizeData);

  if (csz.noChange) {
    console.log("Size is the same as current, ignoring");
    return
  }
  // We are now going to set he width and height of the container
  for (const key of ["width", "height"]) {
    CONTAINER.style[key] = csz[key] + "px";
  }
}
// We now create the function that will update the plot based on the values specified
function updateFromHeader() {
  const header_data = {
    height: config_spans.height.ui_value,
    width: config_spans.width.ui_value,
  };
  changeContainerSize(header_data);
}
// We assign this function to the onblur event of width and height
if (firstRun) {
  for (const container of Object.values(config_spans)) {
    container.ui_span.onblur = (e) => {
      container.ui_value = container.ui_span.textContent;
      updateFromHeader();
    };
  }
}
// This function computes the plot size to use for relayout as a function of the container size
function computePlotSize(data = getSizeData()) {
  // Remove Padding
  const { container_pad, plot_pad, container_rect } = data;
  const offsets = {
    width:
      plot_pad.padding.width +
      plot_pad.border.width +
      plot_pad.offset.left +
      container_pad.padding.width +
      container_pad.border.width,
    height:
      plot_pad.padding.height +
      plot_pad.border.height +
      plot_pad.offset.top +
      container_pad.padding.height +
      container_pad.border.height,
  };
  const sz = {
    width: Math.round(container_rect.width - offsets.width),
    height: Math.round(container_rect.height - offsets.height),
    offsets,
  };
  return sz;
}

// Create the resizeObserver to make the plot even more responsive! :magic:
const resizeObserver = new ResizeObserver((entries) => {
  const sizeData = getSizeData();
  const {container_rect, container_pad} = sizeData;
  let plot_size = computePlotSize(sizeData);
  // We save the height in the PLOT object
  PLOT.container_height = container_rect.height;
  // We deal with some stuff if the container is poppped
  CLIPBOARD_HEADER.style.width = container_rect.width + "px";
  CLIPBOARD_HEADER.style.left = container_rect.left + "px";
  config_spans.height.ui_value = plot_size.height;
  config_spans.width.ui_value = plot_size.width;
  /* 
		The addition of the invalid argument `plutoresize` seems to fix the problem with calling `relayout` simply with `{autosize: true}` as update breaking mouse relayout events tracking. 
		See https://github.com/plotly/plotly.js/issues/6156 for details
		*/
  let config = {
    // If this is popped out, we ignore the original width/height
    width: (CONTAINER.isPoppedOut() ? undefined : original_width) ?? plot_size.width,
    height: (CONTAINER.isPoppedOut() ? undefined : original_height) ?? plot_size.height,
    plutoresize: true,
  };
  Plotly.relayout(PLOT, config).then(() => {
    if (remove_container_size && !CONTAINER.isPoppedOut()) {
      // This is needed to avoid the first resize upon plot creation to already be without a fixed height
      CONTAINER.style.height = "";
      CONTAINER.style.width = "";
      remove_container_size = false;
    }
  });
});

resizeObserver.observe(CONTAINER);


Plotly.react(PLOT, plot_obj).then(() => {
	// Assign the Plotly event listeners
	for (const [key, listener_vec] of Object.entries(plotly_listeners)) {
		for (const listener of listener_vec) {
			PLOT.on(key, listener)
		}
	}
	// Assign the JS event listeners
	for (const [key, listener_vec] of Object.entries(js_listeners)) {
		for (const listener of listener_vec) {
			PLOT.addEventListener(key, listener, {
				signal: controller.signal
			})
		}
	}
}
)


invalidation.then(() => {
	// Remove all plotly listeners
	PLOT.removeAllListeners()
	// Remove all JS listeners
	controller.abort()
	// Remove the resizeObserver
	resizeObserver.disconnect()
})



		return CONTAINER
	</script>
</div>
	<div style = "width: 50px;">No usable ace</div>
	<div>	<script id='plot_3'>
		// We start by putting all the variable interpolation here at the beginning
		// We have to convert all typedarrays in the layout to normal arrays. See Issue #25
		// We use lodash for this for compactness
		function removeTypedArray(o) {
			return _.isTypedArray(o) ? Array.from(o) :
			_.isPlainObject(o) ? _.mapValues(o, removeTypedArray) : 
			o
		}

		// Publish the plot object to JS
		let plot_obj = _.update(/* See the documentation for AbstractPlutoDingetjes.Display.published_to_js */ getPublishedObject("c6e0de0c-3901-11f0-234e-bd09c571f662/985b842d3ecfdc58"), "layout", removeTypedArray)
		// Get the plotly listeners
		const plotly_listeners = {}
		// Get the JS listeners
		const js_listeners = {}
		// Deal with eventual custom classes
		let custom_classlist = []


		// Load the plotly library
		let Plotly = undefined
		try {
			let _mod = await import("./plotlyjs/plotlyjs-2.26.2.min.js")
			Plotly = _mod.default
		} catch (e) {
			console.log("Local load failed, trying with the web esm.sh version")
			let _mod = await import("https://esm.sh/plotly.js-dist-min@2.26.2/es2022/plotly.js-dist-min.mjs")
			Plotly = _mod.default
		}

		// Check if we have to force local mathjax font cache
		if (false && window?.MathJax?.config?.svg?.fontCache === 'global') {
			window.MathJax.config.svg.fontCache = 'local'
		}

		// Flag to check if this cell was  manually ran or reactively ran
const firstRun = this ? false : true
const CONTAINER = this ?? html`<div class='plutoplotly-container'>`
const PLOT = CONTAINER.querySelector('.js-plotly-plot') ?? CONTAINER.appendChild(html`<div>`)
const parent = CONTAINER.parentElement
// We use a controller to remove event listeners upon invalidation
const controller = new AbortController()
// We have to add this to keep supporting @bind with the old API using PLOT
PLOT.addEventListener('input', (e) => {
	CONTAINER.value = PLOT.value
	if (e.bubbles) {
		return
	}
	CONTAINER.dispatchEvent(new CustomEvent('input'))
}, { signal: controller.signal })

	// This create the style subdiv on first run
	firstRun && CONTAINER.appendChild(html`
	<style>
	.plutoplotly-container {
		width: 100%;
		height: 100%;
		min-height: 0;
		min-width: 0;
	}
	.plutoplotly-container .js-plotly-plot .plotly div {
		margin: 0 auto; // This centers the plot
	}
	.plutoplotly-container.popped-out {
		overflow: auto;
		z-index: 1000;
		position: fixed;
		resize: both;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		border-top-left-radius: 0px;
		border-top-right-radius: 0px;
	}
	.plutoplotly-clipboard-header {
		display: flex;
		flex-flow: row wrap;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-top-left-radius: 12px;
		border-top-right-radius: 12px;
		position: fixed;
		z-index: 1001;
		cursor: move;
		transform: translate(0px, -100%);
		padding: 5px;
	}
	.plutoplotly-clipboard-header span {
		display: inline-block;
		flex: 1
	}
	.plutoplotly-clipboard-header.hidden {
		display: none;
	}
	.clipboard-span {
		position: relative;
	}
	.clipboard-value {
		padding-right: 5px;
		padding-left: 2px;
		cursor: text;
	}
	.clipboard-span.format {
		display: none;
	}
	.clipboard-span.filename {
		flex: 0 0 100%;
		text-align: center;
		border-top: 3px solid var(--kbd-border-color);
		margin-top: 5px;
		display: none;
	}
	.plutoplotly-container.filesave .clipboard-span.filename {
		display: inline-block;
	}
	.clipboard-value.filename {
		margin-left: 3px;
		text-align: left;
		min-width: min(60%, min-content);
	}
	.plutoplotly-container.filesave .clipboard-span.format {
		display: inline-flex;
	}
	.clipboard-span.format .label {
		flex: 0 0 0;
	}
	.clipboard-value.format {
		position: relative;
		flex: 1 0 auto;
		min-width: 30px;
		margin-right: 10px;
	}
	div.format-options {
		display: inline-flex;
		flex-flow: column;
		position: absolute;
		background: var(--main-bg-color);
		border-radius: 12px;
		padding-left: 3px;
		z-index: 2000;
	}
	div.format-options:hover {
		cursor: pointer;
		border: 3px solid var(--kbd-border-color);
		padding: 3px;
		transform: translate(-3px, -6px);
	}
	div.format-options .format-option {
		display: none;
	}
	div.format-options:hover .format-option {
		display: inline-block;
	}
	.format-option:not(.selected) {
		margin-top: 3px;
	}
	div.format-options .format-option.selected {
		order: -1;
		display: inline-block;
	}
	.format-option:hover {
		background-color: var(--kbd-border-color);
	}
	span.config-value {
		font-weight: normal;
		color: var(--pluto-output-color);
		display: none;
		position: absolute;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		transform: translate(0px, calc(-100% - 10px));
		padding: 5px;
	}
	.label {
		user-select: none;
	}
	.label:hover span.config-value {
		display: inline-block;
		min-width: 150px;
	}
	.clipboard-span.matching-config .label {
		color: var(--cm-macro-color);
		font-weight: bold;
	}
	.clipboard-span.different-config .label {
		color: var(--cm-tag-color);
		font-weight: bold;
	}
</style>
`)

let original_height = plot_obj.layout.height
let original_width = plot_obj.layout.width
// For the height we have to also put a fixed value in case the plot is put on a non-fixed-size container (like the default wrapper)
// We define a variable to check whether we still have to remove the fixed height
let remove_container_size = firstRun
let container_height = original_height ?? PLOT.container_height ?? 400
CONTAINER.style.height = container_height + 'px'

// We create a Promise version of setTimeout
function delay(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

// We import interact for dragging/resizing
const { default: interact } = await import('https://esm.sh/interactjs@1.10.19')


function getImageOptions() {
  const o = plot_obj.config.toImageButtonOptions ?? {};
  return {
    format: o.format ?? "png",
    width: o.width ?? original_width,
    height: o.height ?? original_height,
    scale: o.scale ?? 1,
    filename: o.filename ?? "newplot",
  };
}

const CLIPBOARD_HEADER =
  CONTAINER.querySelector(".plutoplotly-clipboard-header") ??
  CONTAINER.insertAdjacentElement(
    "afterbegin",
    html`<div class="plutoplotly-clipboard-header hidden">
      <span class="clipboard-span format"
        ><span class="label">Format:</span
        ><span class="clipboard-value format"></span
      ></span>
      <span class="clipboard-span width"
        ><span class="label">Width:</span
        ><span class="clipboard-value width"></span>px</span
      >
      <span class="clipboard-span height"
        ><span class="label">Height:</span
        ><span class="clipboard-value height"></span>px</span
      >
      <span class="clipboard-span scale"
        ><span class="label">Scale:</span
        ><span class="clipboard-value scale"></span
      ></span>
      <button class="clipboard-span set">Set</button>
      <button class="clipboard-span unset">Unset</button>
      <span class="clipboard-span filename"
        ><span class="label">Filename:</span
        ><span class="clipboard-value filename"></span
      ></span>
    </div>`
  );

function checkConfigSync(container) {
  const valid_classes = [
    "missing-config",
    "matching-config",
    "different-config",
  ];
  function setClass(cl) {
    for (const name of valid_classes) {
      container.classList.toggle(name, name == cl);
    }
  }
  // We use the custom getters we'll set up in the container
  const { ui_value, config_value, config_span, key } = container;
  if (config_value === undefined) {
    setClass("missing-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> is not present in the config.`;
  } else if (ui_value == config_value) {
    setClass("matching-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has the same value in the config and in the header.`;
  } else {
    setClass("different-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has a different value (<em>${config_value}</em>) in the config.`;
  }
  // Add info about setting and unsetting
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click on the label <em><b>once</b></em> to set the current UI value in the config.`
  );
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click <em><b>twice</b></em> to remove this key from the config.`
  );
}

const valid_formats = ["png", "svg", "webp", "jpeg", "full-json"];
function initializeUIValueSpan(span, key, value) {
  const container = span.closest(".clipboard-span");
  span.contentEditable = key === "format" ? "false" : "true";
  let parse = (x) => x;
  let update = (x) => (span.textContent = x);
  if (key === "width" || key === "height") {
    parse = (x) => Math.round(parseFloat(x));
  } else if (key === "scale") {
    parse = parseFloat;
  } else if (key === "format") {
    // We remove contentEditable
    span.contentEditable = "false";
    // Here we first add the subspans for each option
    const opts_div = span.appendChild(html`<div class="format-options"></div>`);
    for (const fmt of valid_formats) {
      const opt = opts_div.appendChild(
        html`<span class="format-option ${fmt}">${fmt}</span>`
      );
      opt.onclick = (e) => {
        span.value = opt.textContent;
      };
    }
    parse = (x) => {
      return valid_formats.includes(x) ? x : localValue;
    };
    update = (x) => {
      for (const opt of opts_div.children) {
        opt.classList.toggle("selected", opt.textContent === x);
      }
    };
  } else {
    // We only have filename here
  }
  let localValue;
  Object.defineProperty(span, "value", {
    get: () => {
      return localValue;
    },
    set: (val) => {
      if (val !== "") {
        localValue = parse(val);
      }
      update(localValue);
      checkConfigSync(container);
    },
  });
  // We also assign a listener so that the editable is blurred when enter is pressed
  span.onkeydown = (e) => {
    if (e.keyCode === 13) {
      e.preventDefault();
      span.blur();
    }
  };
  span.value = value;
}

function initializeConfigValueSpan(span, key) {
  // Here we mostly want to define the setter and getter
  const container = span.closest(".clipboard-span");
  Object.defineProperty(span, "value", {
    get: () => {
      return plot_obj.config.toImageButtonOptions[key];
    },
    set: (val) => {
      // if undefined is passed, we remove the entry from the options
      if (val === undefined) {
        delete plot_obj.config.toImageButtonOptions[key];
      } else {
        plot_obj.config.toImageButtonOptions[key] = val;
      }
      checkConfigSync(container);
    },
  });
}

const config_spans = {};
for (const [key, value] of Object.entries(getImageOptions())) {
  const container = CLIPBOARD_HEADER.querySelector(`.clipboard-span.${key}`);
  const label = container.querySelector(".label");
  // We give the label a function that on single click will set the current value and with double click will unset it
  label.onclick = DualClick(
    () => {
      container.config_value = container.ui_value;
    },
    (e) => {
      console.log("e", e);
      e.preventDefault();
      container.config_value = undefined;
    }
  );
  const ui_value_span = container.querySelector(".clipboard-value");
  const config_value_span =
    container.querySelector(".config-value") ??
    label.insertAdjacentElement(
      "afterbegin",
      html`<span class="config-value"></span>`
    );
  // Assing the two spans as properties of the containing span
  container.ui_span = ui_value_span;
  container.config_span = config_value_span;
  container.key = key;
  config_spans[key] = container;
  if (firstRun) {
    plot_obj.config.toImageButtonOptions =
      plot_obj.config.toImageButtonOptions ?? {};
    // We do the initialization of the value span
    initializeUIValueSpan(ui_value_span, key, value);
    // Then we initialize the config value
    initializeConfigValueSpan(config_value_span, key);
    // We put some convenience getters/setters
    // ui_value forward
    Object.defineProperty(container, "ui_value", {
      get: () => ui_value_span.value,
      set: (val) => {
        ui_value_span.value = val;
      },
    });
    // config_value forward
    Object.defineProperty(container, "config_value", {
      get: () => config_value_span.value,
      set: (val) => {
        config_value_span.value = val;
      },
    });
  }
}

// These objects will contain the default value

// This code updates the image options in the PLOT config with the provided ones
function setImageOptions(o) {
  for (const [key, container] of Object.entries(config_spans)) {
    container.config_value = o[key];
  }
}
function unsetImageOptions() {
  setImageOptions({});
}

const set_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.set");
const unset_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.unset");
if (firstRun) {
  set_button.onclick = (e) => {
    for (const container of Object.values(config_spans)) {
      container.config_value = container.ui_value;
    }
  };
  unset_button.onclick = unsetImageOptions;
}

// We add a function to check if the clipboard is popped out
CONTAINER.isPoppedOut = () => {
  return CONTAINER.classList.contains("popped-out");
};

CLIPBOARD_HEADER.onmousedown = function (event) {
  if (event.target.matches("span.clipboard-value")) {
    console.log("We don't move!");
    return;
  }
  const start = {
    left: parseFloat(CONTAINER.style.left),
    top: parseFloat(CONTAINER.style.top),
    X: event.pageX,
    Y: event.pageY,
  };
  function moveAt(event, start) {
    const top = event.pageY - start.Y + start.top + "px";
    const left = event.pageX - start.X + start.left + "px";
    CLIPBOARD_HEADER.style.left = left;
    CONTAINER.style.left = left;
    CONTAINER.style.top = top;
  }

  // move our absolutely positioned ball under the pointer
  moveAt(event, start);
  function onMouseMove(event) {
    moveAt(event, start);
  }

  // We use this to remove the mousemove when clicking outside of the container
  const controller = new AbortController();

  // move the container on mousemove
  document.addEventListener("mousemove", onMouseMove, {
    signal: controller.signal,
  });
  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        cleanUp();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );

  function cleanUp() {
    console.log("cleaning up the plot move listener");
    controller.abort();
    CLIPBOARD_HEADER.onmouseup = null;
  }

  // (3) drop the ball, remove unneeded handlers
  CLIPBOARD_HEADER.onmouseup = cleanUp;
};

function sendToClipboard(blob) {
  if (!navigator.clipboard) {
    alert(
      "The Clipboard API does not seem to be available, make sure the Pluto notebook is being used from either localhost or an https source."
    );
  }
  navigator.clipboard
    .write([
      new ClipboardItem({
        // The key is determined dynamically based on the blob's type.
        [blob.type]: blob,
      }),
    ])
    .then(
      function () {
        console.log("Async: Copying to clipboard was successful!");
      },
      function (err) {
        console.error("Async: Could not copy text: ", err);
      }
    );
}

function copyImageToClipboard() {
  // We extract the image options from the provided parameters (if they exist)
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key. We also ignore format because the clipboard only supports png.
    if (val === undefined || key === "format") {
      continue;
    }
    config[key] = val;
  }
  Plotly.toImage(PLOT, config).then(function (dataUrl) {
    fetch(dataUrl)
      .then((res) => res.blob())
      .then((blob) => {
        const paste_receiver = document.querySelector('paste-receiver.plutoplotly')
        if (paste_receiver) {
          paste_receiver.attachImage(dataUrl, CONTAINER)
        }
        sendToClipboard(blob)
      });
  });
}

function saveImageToFile() {
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key.
    if (val === undefined) {
      continue;
    }
    config[key] = val;
  }
  Plotly.downloadImage(PLOT, config);
}

let container_rect = { width: 0, height: 0, top: 0, left: 0 };
function unpop_container(cl) {
  CONTAINER.classList.toggle("popped-out", false);
  CONTAINER.classList.toggle(cl, false);
  // We fix the height back to the value it had before popout, also setting the flag to signal that upon first resize we remove the fixed inline-style
  CONTAINER.style.height = container_rect.height + "px";
  remove_container_size = true;
  // We set the other fixed inline-styles to null
  CONTAINER.style.width = "";
  CONTAINER.style.top = "";
  CONTAINER.style.left = "";
  // We also remove the CLIPBOARD_HEADER
  CLIPBOARD_HEADER.style.width = "";
  CLIPBOARD_HEADER.style.left = "";
  // Finally we remove the hidden class to the header
  CLIPBOARD_HEADER.classList.toggle("hidden", true);
  return;
}
function popout_container(opts) {
  const cl = opts?.cl;
  const target_container_size = opts?.target_container_size ?? {};
  const target_plot_size = opts?.target_plot_size ?? {};
  if (CONTAINER.isPoppedOut()) {
    return unpop_container(cl);
  }
  CONTAINER.classList.toggle(cl, cl === undefined ? false : true);
  // We extract the current size of the container, save them and fix them
  const { width, height, top, left } = CONTAINER.getBoundingClientRect();
  container_rect = { width, height, top, left };
  // We save the current plot size before we pop as it will fill the screen
  const current_plot_size = {
    width: PLOT._fullLayout.width,
    height: PLOT._fullLayout.height,
  };
  // We have to save the pad data before popping so we can resize precisely
  const pad = {};
  pad.unpopped = getSizeData().container_pad;
  CONTAINER.classList.toggle("popped-out", true);
  pad.popped = getSizeData().container_pad;
  // We do top and left based on the current rect
  for (const key of ["top", "left"]) {
    const start_val = target_container_size[key] ?? container_rect[key];
    let offset = 0;
    for (const kind of ["padding", "border"]) {
      offset += pad.popped[kind][key] - pad.unpopped[kind][key];
    }
    CONTAINER.style[key] = start_val - offset + "px";
    if (key === "left") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  // We compute the width and height depending on eventual config data
  const csz = computeContainerSize({
    width:
      target_plot_size.width ??
      config_spans.width.config_value ??
      current_plot_size.width,
    height:
      target_plot_size.height ??
      config_spans.height.config_value ??
      current_plot_size.height,
  });
  for (const key of ["width", "height"]) {
    const val = target_container_size[key] ?? csz[key];
    CONTAINER.style[key] = val + "px";
    if (key === "width") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  CLIPBOARD_HEADER.classList.toggle("hidden", false);
  const controller = new AbortController();

  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        unpop_container();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );
}

CONTAINER.popOut = popout_container;

function DualClick(single_func, dbl_func) {
  let nclicks = 0;
  return function (...args) {
    nclicks += 1;
    if (nclicks > 1) {
      dbl_func(...args);
      nclicks = 0;
    } else {
      delay(300).then(() => {
        if (nclicks == 1) {
          single_func(...args);
        }
        nclicks = 0;
      });
    }
  };
}

// We remove the default download image button
plot_obj.config.modeBarButtonsToRemove = _.union(
  plot_obj.config.modeBarButtonsToRemove,
  ["toImage"]
);
// We add the custom button to the modebar
plot_obj.config.modeBarButtonsToAdd = _.union(
  plot_obj.config.modeBarButtonsToAdd,
  [
    {
      name: "Copy PNG to Clipboard",
      icon: {
        height: 520,
        width: 520,
        path: "M280 64h40c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128C0 92.7 28.7 64 64 64h40 9.6C121 27.5 153.3 0 192 0s71 27.5 78.4 64H280zM64 112c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16H320c8.8 0 16-7.2 16-16V128c0-8.8-7.2-16-16-16H304v24c0 13.3-10.7 24-24 24H192 104c-13.3 0-24-10.7-24-24V112H64zm128-8a24 24 0 1 0 0-48 24 24 0 1 0 0 48z",
      },
      direction: "up",
      click: DualClick(copyImageToClipboard, () => {
        popout_container();
      }),
    },
    {
      name: "Download Image",
      icon: Plotly.Icons.camera,
      direction: "up",
      click: DualClick(saveImageToFile, () => {
        popout_container({ cl: "filesave" });
      }),
    },
  ]
);

function getOffsetData(el) {
  let cs = window.getComputedStyle(el, null);
  const odata = {
    padding: {
      left: parseFloat(cs.paddingLeft),
      right: parseFloat(cs.paddingRight),
      top: parseFloat(cs.paddingTop),
      bottom: parseFloat(cs.paddingBottom),
      width: parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight),
      height: parseFloat(cs.paddingTop) + parseFloat(cs.paddingBottom),
    },
    border: {
      left: parseFloat(cs.borderLeftWidth),
      right: parseFloat(cs.borderRightWidth),
      top: parseFloat(cs.borderTopWidth),
      bottom: parseFloat(cs.borderBottomWidth),
      width: parseFloat(cs.borderLeftWidth) + parseFloat(cs.borderRightWidth),
      height: parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth),
    }
  };
  if (el === PLOT) {
    // For the PLOT we also want to take into account the offset
    odata.offset = {
      top: PLOT.offsetParent == CONTAINER ? PLOT.offsetTop : 0,
      left: PLOT.offsetParent == CONTAINER ? PLOT.offsetLeft : 0,
    }
  }
  return odata;
}
function getSizeData() {
  const data = {
    plot_pad: getOffsetData(PLOT),
    plot_rect: PLOT.getBoundingClientRect(),
    container_pad: getOffsetData(CONTAINER),
    container_rect: CONTAINER.getBoundingClientRect(),
  };
  return data;
}
function computeContainerSize({ width, height }, sizeData = getSizeData()) {
  const computed_size = computePlotSize(sizeData);
  const offsets = computed_size.offsets;

  const plot_data = {
    width: width ?? computed_size.width,
    height: height ?? computed_size.height,
  };

  return {
    width: (width ?? computed_size.width) + offsets.width,
    height: (height ?? computed_size.height) + offsets.height,
    noChange: width == computed_size.width && height == computed_size.height,
  }
}

// This function will change the container size so that the resulting plot will be matching the provided specs
function changeContainerSize({ width, height }, sizeData = getSizeData()) {
  if (!CONTAINER.isPoppedOut()) {
    console.log("Tried to change container size when not popped, ignoring");
    return;
  }

  const csz = computeContainerSize({ width, height }, sizeData);

  if (csz.noChange) {
    console.log("Size is the same as current, ignoring");
    return
  }
  // We are now going to set he width and height of the container
  for (const key of ["width", "height"]) {
    CONTAINER.style[key] = csz[key] + "px";
  }
}
// We now create the function that will update the plot based on the values specified
function updateFromHeader() {
  const header_data = {
    height: config_spans.height.ui_value,
    width: config_spans.width.ui_value,
  };
  changeContainerSize(header_data);
}
// We assign this function to the onblur event of width and height
if (firstRun) {
  for (const container of Object.values(config_spans)) {
    container.ui_span.onblur = (e) => {
      container.ui_value = container.ui_span.textContent;
      updateFromHeader();
    };
  }
}
// This function computes the plot size to use for relayout as a function of the container size
function computePlotSize(data = getSizeData()) {
  // Remove Padding
  const { container_pad, plot_pad, container_rect } = data;
  const offsets = {
    width:
      plot_pad.padding.width +
      plot_pad.border.width +
      plot_pad.offset.left +
      container_pad.padding.width +
      container_pad.border.width,
    height:
      plot_pad.padding.height +
      plot_pad.border.height +
      plot_pad.offset.top +
      container_pad.padding.height +
      container_pad.border.height,
  };
  const sz = {
    width: Math.round(container_rect.width - offsets.width),
    height: Math.round(container_rect.height - offsets.height),
    offsets,
  };
  return sz;
}

// Create the resizeObserver to make the plot even more responsive! :magic:
const resizeObserver = new ResizeObserver((entries) => {
  const sizeData = getSizeData();
  const {container_rect, container_pad} = sizeData;
  let plot_size = computePlotSize(sizeData);
  // We save the height in the PLOT object
  PLOT.container_height = container_rect.height;
  // We deal with some stuff if the container is poppped
  CLIPBOARD_HEADER.style.width = container_rect.width + "px";
  CLIPBOARD_HEADER.style.left = container_rect.left + "px";
  config_spans.height.ui_value = plot_size.height;
  config_spans.width.ui_value = plot_size.width;
  /* 
		The addition of the invalid argument `plutoresize` seems to fix the problem with calling `relayout` simply with `{autosize: true}` as update breaking mouse relayout events tracking. 
		See https://github.com/plotly/plotly.js/issues/6156 for details
		*/
  let config = {
    // If this is popped out, we ignore the original width/height
    width: (CONTAINER.isPoppedOut() ? undefined : original_width) ?? plot_size.width,
    height: (CONTAINER.isPoppedOut() ? undefined : original_height) ?? plot_size.height,
    plutoresize: true,
  };
  Plotly.relayout(PLOT, config).then(() => {
    if (remove_container_size && !CONTAINER.isPoppedOut()) {
      // This is needed to avoid the first resize upon plot creation to already be without a fixed height
      CONTAINER.style.height = "";
      CONTAINER.style.width = "";
      remove_container_size = false;
    }
  });
});

resizeObserver.observe(CONTAINER);


Plotly.react(PLOT, plot_obj).then(() => {
	// Assign the Plotly event listeners
	for (const [key, listener_vec] of Object.entries(plotly_listeners)) {
		for (const listener of listener_vec) {
			PLOT.on(key, listener)
		}
	}
	// Assign the JS event listeners
	for (const [key, listener_vec] of Object.entries(js_listeners)) {
		for (const listener of listener_vec) {
			PLOT.addEventListener(key, listener, {
				signal: controller.signal
			})
		}
	}
}
)


invalidation.then(() => {
	// Remove all plotly listeners
	PLOT.removeAllListeners()
	// Remove all JS listeners
	controller.abort()
	// Remove the resizeObserver
	resizeObserver.disconnect()
})



		return CONTAINER
	</script>
</div> 
	<div>	<script id='plot_4'>
		// We start by putting all the variable interpolation here at the beginning
		// We have to convert all typedarrays in the layout to normal arrays. See Issue #25
		// We use lodash for this for compactness
		function removeTypedArray(o) {
			return _.isTypedArray(o) ? Array.from(o) :
			_.isPlainObject(o) ? _.mapValues(o, removeTypedArray) : 
			o
		}

		// Publish the plot object to JS
		let plot_obj = _.update(/* See the documentation for AbstractPlutoDingetjes.Display.published_to_js */ getPublishedObject("c6e0de0c-3901-11f0-234e-bd09c571f662/d508a1aa913b68d"), "layout", removeTypedArray)
		// Get the plotly listeners
		const plotly_listeners = {}
		// Get the JS listeners
		const js_listeners = {}
		// Deal with eventual custom classes
		let custom_classlist = []


		// Load the plotly library
		let Plotly = undefined
		try {
			let _mod = await import("./plotlyjs/plotlyjs-2.26.2.min.js")
			Plotly = _mod.default
		} catch (e) {
			console.log("Local load failed, trying with the web esm.sh version")
			let _mod = await import("https://esm.sh/plotly.js-dist-min@2.26.2/es2022/plotly.js-dist-min.mjs")
			Plotly = _mod.default
		}

		// Check if we have to force local mathjax font cache
		if (false && window?.MathJax?.config?.svg?.fontCache === 'global') {
			window.MathJax.config.svg.fontCache = 'local'
		}

		// Flag to check if this cell was  manually ran or reactively ran
const firstRun = this ? false : true
const CONTAINER = this ?? html`<div class='plutoplotly-container'>`
const PLOT = CONTAINER.querySelector('.js-plotly-plot') ?? CONTAINER.appendChild(html`<div>`)
const parent = CONTAINER.parentElement
// We use a controller to remove event listeners upon invalidation
const controller = new AbortController()
// We have to add this to keep supporting @bind with the old API using PLOT
PLOT.addEventListener('input', (e) => {
	CONTAINER.value = PLOT.value
	if (e.bubbles) {
		return
	}
	CONTAINER.dispatchEvent(new CustomEvent('input'))
}, { signal: controller.signal })

	// This create the style subdiv on first run
	firstRun && CONTAINER.appendChild(html`
	<style>
	.plutoplotly-container {
		width: 100%;
		height: 100%;
		min-height: 0;
		min-width: 0;
	}
	.plutoplotly-container .js-plotly-plot .plotly div {
		margin: 0 auto; // This centers the plot
	}
	.plutoplotly-container.popped-out {
		overflow: auto;
		z-index: 1000;
		position: fixed;
		resize: both;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		border-top-left-radius: 0px;
		border-top-right-radius: 0px;
	}
	.plutoplotly-clipboard-header {
		display: flex;
		flex-flow: row wrap;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-top-left-radius: 12px;
		border-top-right-radius: 12px;
		position: fixed;
		z-index: 1001;
		cursor: move;
		transform: translate(0px, -100%);
		padding: 5px;
	}
	.plutoplotly-clipboard-header span {
		display: inline-block;
		flex: 1
	}
	.plutoplotly-clipboard-header.hidden {
		display: none;
	}
	.clipboard-span {
		position: relative;
	}
	.clipboard-value {
		padding-right: 5px;
		padding-left: 2px;
		cursor: text;
	}
	.clipboard-span.format {
		display: none;
	}
	.clipboard-span.filename {
		flex: 0 0 100%;
		text-align: center;
		border-top: 3px solid var(--kbd-border-color);
		margin-top: 5px;
		display: none;
	}
	.plutoplotly-container.filesave .clipboard-span.filename {
		display: inline-block;
	}
	.clipboard-value.filename {
		margin-left: 3px;
		text-align: left;
		min-width: min(60%, min-content);
	}
	.plutoplotly-container.filesave .clipboard-span.format {
		display: inline-flex;
	}
	.clipboard-span.format .label {
		flex: 0 0 0;
	}
	.clipboard-value.format {
		position: relative;
		flex: 1 0 auto;
		min-width: 30px;
		margin-right: 10px;
	}
	div.format-options {
		display: inline-flex;
		flex-flow: column;
		position: absolute;
		background: var(--main-bg-color);
		border-radius: 12px;
		padding-left: 3px;
		z-index: 2000;
	}
	div.format-options:hover {
		cursor: pointer;
		border: 3px solid var(--kbd-border-color);
		padding: 3px;
		transform: translate(-3px, -6px);
	}
	div.format-options .format-option {
		display: none;
	}
	div.format-options:hover .format-option {
		display: inline-block;
	}
	.format-option:not(.selected) {
		margin-top: 3px;
	}
	div.format-options .format-option.selected {
		order: -1;
		display: inline-block;
	}
	.format-option:hover {
		background-color: var(--kbd-border-color);
	}
	span.config-value {
		font-weight: normal;
		color: var(--pluto-output-color);
		display: none;
		position: absolute;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		transform: translate(0px, calc(-100% - 10px));
		padding: 5px;
	}
	.label {
		user-select: none;
	}
	.label:hover span.config-value {
		display: inline-block;
		min-width: 150px;
	}
	.clipboard-span.matching-config .label {
		color: var(--cm-macro-color);
		font-weight: bold;
	}
	.clipboard-span.different-config .label {
		color: var(--cm-tag-color);
		font-weight: bold;
	}
</style>
`)

let original_height = plot_obj.layout.height
let original_width = plot_obj.layout.width
// For the height we have to also put a fixed value in case the plot is put on a non-fixed-size container (like the default wrapper)
// We define a variable to check whether we still have to remove the fixed height
let remove_container_size = firstRun
let container_height = original_height ?? PLOT.container_height ?? 400
CONTAINER.style.height = container_height + 'px'

// We create a Promise version of setTimeout
function delay(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

// We import interact for dragging/resizing
const { default: interact } = await import('https://esm.sh/interactjs@1.10.19')


function getImageOptions() {
  const o = plot_obj.config.toImageButtonOptions ?? {};
  return {
    format: o.format ?? "png",
    width: o.width ?? original_width,
    height: o.height ?? original_height,
    scale: o.scale ?? 1,
    filename: o.filename ?? "newplot",
  };
}

const CLIPBOARD_HEADER =
  CONTAINER.querySelector(".plutoplotly-clipboard-header") ??
  CONTAINER.insertAdjacentElement(
    "afterbegin",
    html`<div class="plutoplotly-clipboard-header hidden">
      <span class="clipboard-span format"
        ><span class="label">Format:</span
        ><span class="clipboard-value format"></span
      ></span>
      <span class="clipboard-span width"
        ><span class="label">Width:</span
        ><span class="clipboard-value width"></span>px</span
      >
      <span class="clipboard-span height"
        ><span class="label">Height:</span
        ><span class="clipboard-value height"></span>px</span
      >
      <span class="clipboard-span scale"
        ><span class="label">Scale:</span
        ><span class="clipboard-value scale"></span
      ></span>
      <button class="clipboard-span set">Set</button>
      <button class="clipboard-span unset">Unset</button>
      <span class="clipboard-span filename"
        ><span class="label">Filename:</span
        ><span class="clipboard-value filename"></span
      ></span>
    </div>`
  );

function checkConfigSync(container) {
  const valid_classes = [
    "missing-config",
    "matching-config",
    "different-config",
  ];
  function setClass(cl) {
    for (const name of valid_classes) {
      container.classList.toggle(name, name == cl);
    }
  }
  // We use the custom getters we'll set up in the container
  const { ui_value, config_value, config_span, key } = container;
  if (config_value === undefined) {
    setClass("missing-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> is not present in the config.`;
  } else if (ui_value == config_value) {
    setClass("matching-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has the same value in the config and in the header.`;
  } else {
    setClass("different-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has a different value (<em>${config_value}</em>) in the config.`;
  }
  // Add info about setting and unsetting
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click on the label <em><b>once</b></em> to set the current UI value in the config.`
  );
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click <em><b>twice</b></em> to remove this key from the config.`
  );
}

const valid_formats = ["png", "svg", "webp", "jpeg", "full-json"];
function initializeUIValueSpan(span, key, value) {
  const container = span.closest(".clipboard-span");
  span.contentEditable = key === "format" ? "false" : "true";
  let parse = (x) => x;
  let update = (x) => (span.textContent = x);
  if (key === "width" || key === "height") {
    parse = (x) => Math.round(parseFloat(x));
  } else if (key === "scale") {
    parse = parseFloat;
  } else if (key === "format") {
    // We remove contentEditable
    span.contentEditable = "false";
    // Here we first add the subspans for each option
    const opts_div = span.appendChild(html`<div class="format-options"></div>`);
    for (const fmt of valid_formats) {
      const opt = opts_div.appendChild(
        html`<span class="format-option ${fmt}">${fmt}</span>`
      );
      opt.onclick = (e) => {
        span.value = opt.textContent;
      };
    }
    parse = (x) => {
      return valid_formats.includes(x) ? x : localValue;
    };
    update = (x) => {
      for (const opt of opts_div.children) {
        opt.classList.toggle("selected", opt.textContent === x);
      }
    };
  } else {
    // We only have filename here
  }
  let localValue;
  Object.defineProperty(span, "value", {
    get: () => {
      return localValue;
    },
    set: (val) => {
      if (val !== "") {
        localValue = parse(val);
      }
      update(localValue);
      checkConfigSync(container);
    },
  });
  // We also assign a listener so that the editable is blurred when enter is pressed
  span.onkeydown = (e) => {
    if (e.keyCode === 13) {
      e.preventDefault();
      span.blur();
    }
  };
  span.value = value;
}

function initializeConfigValueSpan(span, key) {
  // Here we mostly want to define the setter and getter
  const container = span.closest(".clipboard-span");
  Object.defineProperty(span, "value", {
    get: () => {
      return plot_obj.config.toImageButtonOptions[key];
    },
    set: (val) => {
      // if undefined is passed, we remove the entry from the options
      if (val === undefined) {
        delete plot_obj.config.toImageButtonOptions[key];
      } else {
        plot_obj.config.toImageButtonOptions[key] = val;
      }
      checkConfigSync(container);
    },
  });
}

const config_spans = {};
for (const [key, value] of Object.entries(getImageOptions())) {
  const container = CLIPBOARD_HEADER.querySelector(`.clipboard-span.${key}`);
  const label = container.querySelector(".label");
  // We give the label a function that on single click will set the current value and with double click will unset it
  label.onclick = DualClick(
    () => {
      container.config_value = container.ui_value;
    },
    (e) => {
      console.log("e", e);
      e.preventDefault();
      container.config_value = undefined;
    }
  );
  const ui_value_span = container.querySelector(".clipboard-value");
  const config_value_span =
    container.querySelector(".config-value") ??
    label.insertAdjacentElement(
      "afterbegin",
      html`<span class="config-value"></span>`
    );
  // Assing the two spans as properties of the containing span
  container.ui_span = ui_value_span;
  container.config_span = config_value_span;
  container.key = key;
  config_spans[key] = container;
  if (firstRun) {
    plot_obj.config.toImageButtonOptions =
      plot_obj.config.toImageButtonOptions ?? {};
    // We do the initialization of the value span
    initializeUIValueSpan(ui_value_span, key, value);
    // Then we initialize the config value
    initializeConfigValueSpan(config_value_span, key);
    // We put some convenience getters/setters
    // ui_value forward
    Object.defineProperty(container, "ui_value", {
      get: () => ui_value_span.value,
      set: (val) => {
        ui_value_span.value = val;
      },
    });
    // config_value forward
    Object.defineProperty(container, "config_value", {
      get: () => config_value_span.value,
      set: (val) => {
        config_value_span.value = val;
      },
    });
  }
}

// These objects will contain the default value

// This code updates the image options in the PLOT config with the provided ones
function setImageOptions(o) {
  for (const [key, container] of Object.entries(config_spans)) {
    container.config_value = o[key];
  }
}
function unsetImageOptions() {
  setImageOptions({});
}

const set_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.set");
const unset_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.unset");
if (firstRun) {
  set_button.onclick = (e) => {
    for (const container of Object.values(config_spans)) {
      container.config_value = container.ui_value;
    }
  };
  unset_button.onclick = unsetImageOptions;
}

// We add a function to check if the clipboard is popped out
CONTAINER.isPoppedOut = () => {
  return CONTAINER.classList.contains("popped-out");
};

CLIPBOARD_HEADER.onmousedown = function (event) {
  if (event.target.matches("span.clipboard-value")) {
    console.log("We don't move!");
    return;
  }
  const start = {
    left: parseFloat(CONTAINER.style.left),
    top: parseFloat(CONTAINER.style.top),
    X: event.pageX,
    Y: event.pageY,
  };
  function moveAt(event, start) {
    const top = event.pageY - start.Y + start.top + "px";
    const left = event.pageX - start.X + start.left + "px";
    CLIPBOARD_HEADER.style.left = left;
    CONTAINER.style.left = left;
    CONTAINER.style.top = top;
  }

  // move our absolutely positioned ball under the pointer
  moveAt(event, start);
  function onMouseMove(event) {
    moveAt(event, start);
  }

  // We use this to remove the mousemove when clicking outside of the container
  const controller = new AbortController();

  // move the container on mousemove
  document.addEventListener("mousemove", onMouseMove, {
    signal: controller.signal,
  });
  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        cleanUp();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );

  function cleanUp() {
    console.log("cleaning up the plot move listener");
    controller.abort();
    CLIPBOARD_HEADER.onmouseup = null;
  }

  // (3) drop the ball, remove unneeded handlers
  CLIPBOARD_HEADER.onmouseup = cleanUp;
};

function sendToClipboard(blob) {
  if (!navigator.clipboard) {
    alert(
      "The Clipboard API does not seem to be available, make sure the Pluto notebook is being used from either localhost or an https source."
    );
  }
  navigator.clipboard
    .write([
      new ClipboardItem({
        // The key is determined dynamically based on the blob's type.
        [blob.type]: blob,
      }),
    ])
    .then(
      function () {
        console.log("Async: Copying to clipboard was successful!");
      },
      function (err) {
        console.error("Async: Could not copy text: ", err);
      }
    );
}

function copyImageToClipboard() {
  // We extract the image options from the provided parameters (if they exist)
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key. We also ignore format because the clipboard only supports png.
    if (val === undefined || key === "format") {
      continue;
    }
    config[key] = val;
  }
  Plotly.toImage(PLOT, config).then(function (dataUrl) {
    fetch(dataUrl)
      .then((res) => res.blob())
      .then((blob) => {
        const paste_receiver = document.querySelector('paste-receiver.plutoplotly')
        if (paste_receiver) {
          paste_receiver.attachImage(dataUrl, CONTAINER)
        }
        sendToClipboard(blob)
      });
  });
}

function saveImageToFile() {
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key.
    if (val === undefined) {
      continue;
    }
    config[key] = val;
  }
  Plotly.downloadImage(PLOT, config);
}

let container_rect = { width: 0, height: 0, top: 0, left: 0 };
function unpop_container(cl) {
  CONTAINER.classList.toggle("popped-out", false);
  CONTAINER.classList.toggle(cl, false);
  // We fix the height back to the value it had before popout, also setting the flag to signal that upon first resize we remove the fixed inline-style
  CONTAINER.style.height = container_rect.height + "px";
  remove_container_size = true;
  // We set the other fixed inline-styles to null
  CONTAINER.style.width = "";
  CONTAINER.style.top = "";
  CONTAINER.style.left = "";
  // We also remove the CLIPBOARD_HEADER
  CLIPBOARD_HEADER.style.width = "";
  CLIPBOARD_HEADER.style.left = "";
  // Finally we remove the hidden class to the header
  CLIPBOARD_HEADER.classList.toggle("hidden", true);
  return;
}
function popout_container(opts) {
  const cl = opts?.cl;
  const target_container_size = opts?.target_container_size ?? {};
  const target_plot_size = opts?.target_plot_size ?? {};
  if (CONTAINER.isPoppedOut()) {
    return unpop_container(cl);
  }
  CONTAINER.classList.toggle(cl, cl === undefined ? false : true);
  // We extract the current size of the container, save them and fix them
  const { width, height, top, left } = CONTAINER.getBoundingClientRect();
  container_rect = { width, height, top, left };
  // We save the current plot size before we pop as it will fill the screen
  const current_plot_size = {
    width: PLOT._fullLayout.width,
    height: PLOT._fullLayout.height,
  };
  // We have to save the pad data before popping so we can resize precisely
  const pad = {};
  pad.unpopped = getSizeData().container_pad;
  CONTAINER.classList.toggle("popped-out", true);
  pad.popped = getSizeData().container_pad;
  // We do top and left based on the current rect
  for (const key of ["top", "left"]) {
    const start_val = target_container_size[key] ?? container_rect[key];
    let offset = 0;
    for (const kind of ["padding", "border"]) {
      offset += pad.popped[kind][key] - pad.unpopped[kind][key];
    }
    CONTAINER.style[key] = start_val - offset + "px";
    if (key === "left") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  // We compute the width and height depending on eventual config data
  const csz = computeContainerSize({
    width:
      target_plot_size.width ??
      config_spans.width.config_value ??
      current_plot_size.width,
    height:
      target_plot_size.height ??
      config_spans.height.config_value ??
      current_plot_size.height,
  });
  for (const key of ["width", "height"]) {
    const val = target_container_size[key] ?? csz[key];
    CONTAINER.style[key] = val + "px";
    if (key === "width") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  CLIPBOARD_HEADER.classList.toggle("hidden", false);
  const controller = new AbortController();

  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        unpop_container();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );
}

CONTAINER.popOut = popout_container;

function DualClick(single_func, dbl_func) {
  let nclicks = 0;
  return function (...args) {
    nclicks += 1;
    if (nclicks > 1) {
      dbl_func(...args);
      nclicks = 0;
    } else {
      delay(300).then(() => {
        if (nclicks == 1) {
          single_func(...args);
        }
        nclicks = 0;
      });
    }
  };
}

// We remove the default download image button
plot_obj.config.modeBarButtonsToRemove = _.union(
  plot_obj.config.modeBarButtonsToRemove,
  ["toImage"]
);
// We add the custom button to the modebar
plot_obj.config.modeBarButtonsToAdd = _.union(
  plot_obj.config.modeBarButtonsToAdd,
  [
    {
      name: "Copy PNG to Clipboard",
      icon: {
        height: 520,
        width: 520,
        path: "M280 64h40c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128C0 92.7 28.7 64 64 64h40 9.6C121 27.5 153.3 0 192 0s71 27.5 78.4 64H280zM64 112c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16H320c8.8 0 16-7.2 16-16V128c0-8.8-7.2-16-16-16H304v24c0 13.3-10.7 24-24 24H192 104c-13.3 0-24-10.7-24-24V112H64zm128-8a24 24 0 1 0 0-48 24 24 0 1 0 0 48z",
      },
      direction: "up",
      click: DualClick(copyImageToClipboard, () => {
        popout_container();
      }),
    },
    {
      name: "Download Image",
      icon: Plotly.Icons.camera,
      direction: "up",
      click: DualClick(saveImageToFile, () => {
        popout_container({ cl: "filesave" });
      }),
    },
  ]
);

function getOffsetData(el) {
  let cs = window.getComputedStyle(el, null);
  const odata = {
    padding: {
      left: parseFloat(cs.paddingLeft),
      right: parseFloat(cs.paddingRight),
      top: parseFloat(cs.paddingTop),
      bottom: parseFloat(cs.paddingBottom),
      width: parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight),
      height: parseFloat(cs.paddingTop) + parseFloat(cs.paddingBottom),
    },
    border: {
      left: parseFloat(cs.borderLeftWidth),
      right: parseFloat(cs.borderRightWidth),
      top: parseFloat(cs.borderTopWidth),
      bottom: parseFloat(cs.borderBottomWidth),
      width: parseFloat(cs.borderLeftWidth) + parseFloat(cs.borderRightWidth),
      height: parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth),
    }
  };
  if (el === PLOT) {
    // For the PLOT we also want to take into account the offset
    odata.offset = {
      top: PLOT.offsetParent == CONTAINER ? PLOT.offsetTop : 0,
      left: PLOT.offsetParent == CONTAINER ? PLOT.offsetLeft : 0,
    }
  }
  return odata;
}
function getSizeData() {
  const data = {
    plot_pad: getOffsetData(PLOT),
    plot_rect: PLOT.getBoundingClientRect(),
    container_pad: getOffsetData(CONTAINER),
    container_rect: CONTAINER.getBoundingClientRect(),
  };
  return data;
}
function computeContainerSize({ width, height }, sizeData = getSizeData()) {
  const computed_size = computePlotSize(sizeData);
  const offsets = computed_size.offsets;

  const plot_data = {
    width: width ?? computed_size.width,
    height: height ?? computed_size.height,
  };

  return {
    width: (width ?? computed_size.width) + offsets.width,
    height: (height ?? computed_size.height) + offsets.height,
    noChange: width == computed_size.width && height == computed_size.height,
  }
}

// This function will change the container size so that the resulting plot will be matching the provided specs
function changeContainerSize({ width, height }, sizeData = getSizeData()) {
  if (!CONTAINER.isPoppedOut()) {
    console.log("Tried to change container size when not popped, ignoring");
    return;
  }

  const csz = computeContainerSize({ width, height }, sizeData);

  if (csz.noChange) {
    console.log("Size is the same as current, ignoring");
    return
  }
  // We are now going to set he width and height of the container
  for (const key of ["width", "height"]) {
    CONTAINER.style[key] = csz[key] + "px";
  }
}
// We now create the function that will update the plot based on the values specified
function updateFromHeader() {
  const header_data = {
    height: config_spans.height.ui_value,
    width: config_spans.width.ui_value,
  };
  changeContainerSize(header_data);
}
// We assign this function to the onblur event of width and height
if (firstRun) {
  for (const container of Object.values(config_spans)) {
    container.ui_span.onblur = (e) => {
      container.ui_value = container.ui_span.textContent;
      updateFromHeader();
    };
  }
}
// This function computes the plot size to use for relayout as a function of the container size
function computePlotSize(data = getSizeData()) {
  // Remove Padding
  const { container_pad, plot_pad, container_rect } = data;
  const offsets = {
    width:
      plot_pad.padding.width +
      plot_pad.border.width +
      plot_pad.offset.left +
      container_pad.padding.width +
      container_pad.border.width,
    height:
      plot_pad.padding.height +
      plot_pad.border.height +
      plot_pad.offset.top +
      container_pad.padding.height +
      container_pad.border.height,
  };
  const sz = {
    width: Math.round(container_rect.width - offsets.width),
    height: Math.round(container_rect.height - offsets.height),
    offsets,
  };
  return sz;
}

// Create the resizeObserver to make the plot even more responsive! :magic:
const resizeObserver = new ResizeObserver((entries) => {
  const sizeData = getSizeData();
  const {container_rect, container_pad} = sizeData;
  let plot_size = computePlotSize(sizeData);
  // We save the height in the PLOT object
  PLOT.container_height = container_rect.height;
  // We deal with some stuff if the container is poppped
  CLIPBOARD_HEADER.style.width = container_rect.width + "px";
  CLIPBOARD_HEADER.style.left = container_rect.left + "px";
  config_spans.height.ui_value = plot_size.height;
  config_spans.width.ui_value = plot_size.width;
  /* 
		The addition of the invalid argument `plutoresize` seems to fix the problem with calling `relayout` simply with `{autosize: true}` as update breaking mouse relayout events tracking. 
		See https://github.com/plotly/plotly.js/issues/6156 for details
		*/
  let config = {
    // If this is popped out, we ignore the original width/height
    width: (CONTAINER.isPoppedOut() ? undefined : original_width) ?? plot_size.width,
    height: (CONTAINER.isPoppedOut() ? undefined : original_height) ?? plot_size.height,
    plutoresize: true,
  };
  Plotly.relayout(PLOT, config).then(() => {
    if (remove_container_size && !CONTAINER.isPoppedOut()) {
      // This is needed to avoid the first resize upon plot creation to already be without a fixed height
      CONTAINER.style.height = "";
      CONTAINER.style.width = "";
      remove_container_size = false;
    }
  });
});

resizeObserver.observe(CONTAINER);


Plotly.react(PLOT, plot_obj).then(() => {
	// Assign the Plotly event listeners
	for (const [key, listener_vec] of Object.entries(plotly_listeners)) {
		for (const listener of listener_vec) {
			PLOT.on(key, listener)
		}
	}
	// Assign the JS event listeners
	for (const [key, listener_vec] of Object.entries(js_listeners)) {
		for (const listener of listener_vec) {
			PLOT.addEventListener(key, listener, {
				signal: controller.signal
			})
		}
	}
}
)


invalidation.then(() => {
	// Remove all plotly listeners
	PLOT.removeAllListeners()
	// Remove all JS listeners
	controller.abort()
	// Remove the resizeObserver
	resizeObserver.disconnect()
})



		return CONTAINER
	</script>
</div>
</div>
mimetext/htmlrootassigneelast_run_timestampA)N°persist_js_state·has_pluto_hook_features§cell_id$82284c63-2306-4469-9b1a-a5ec87037e79depends_on_disabled_cells§runtime&ipublished_object_keys5c6e0de0c-3901-11f0-234e-bd09c571f662/c2f9f46c95453d024c6e0de0c-3901-11f0-234e-bd09c571f662/d508a1aa913b68d5c6e0de0c-3901-11f0-234e-bd09c571f662/cc789608a7b2df165c6e0de0c-3901-11f0-234e-bd09c571f662/985b842d3ecfdc58depends_on_skipped_cells§errored$5b32bbc7-dc34-4fc3-bacc-92e55f26a98cqueued¤logsrunning¦outputbody7.860627f0mimetext/plainrootassigneelast_run_timestampA-JApersist_js_state·has_pluto_hook_features§cell_id$5b32bbc7-dc34-4fc3-bacc-92e55f26a98cdepends_on_disabled_cells§runtime &2.published_object_keysdepends_on_skipped_cells§errored$c8be6951-b6ec-4444-8c7f-ca5db6681571queued¤logsrunning¦outputbody0makegridsquare (generic function with 2 methods)mimetext/plainrootassigneelast_run_timestampA/ persist_js_state·has_pluto_hook_features§cell_id$c8be6951-b6ec-4444-8c7f-ca5db6681571depends_on_disabled_cells§runtime gpublished_object_keysdepends_on_skipped_cells§errored$887de995-04e8-4d84-88d7-ad096a5747dfqueued¤logsrunning¦outputbodyY<div class="markdown"><p>Example trajectories after training for 1000 episodes</p>
</div>mimetext/htmlrootassigneelast_run_timestampA1(Zpersist_js_state·has_pluto_hook_features§cell_id$887de995-04e8-4d84-88d7-ad096a5747dfdepends_on_disabled_cells§runtime dpublished_object_keysdepends_on_skipped_cells§errored$3ee31af5-b19c-49dc-8fbf-f07e93d1f0c5queued¤logsrunning¦outputbody١<div class="markdown"><h3>Figure 5.2b:</h3>
<p>Recreation of Figure 5.2 using an ϵ-soft MC control with <span class="tex">$\epsilon &#61; 0.1$</span></p>
</div>mimetext/htmlrootassigneelast_run_timestampA"'jpersist_js_state·has_pluto_hook_features§cell_id$3ee31af5-b19c-49dc-8fbf-f07e93d1f0c5depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$ffd1e39d-e66b-40a3-8ad1-c9480d371fe8queued¤logsrunning¦outputbody<div class="markdown"><h5>Results Summary</h5>
<p>Each environment has 7300 and 12875 states respectively, so Monte Carlo Exploring starts would need to sample at least this many episodes to have a non zero probability of coverage.  Surprisingly, even after just 1000 episodes of training the results are quite an improvement over the random policy with the mean finish time of about 30 steps for both.  Although at the high end, some episodes still take over 100 steps to complete &#40;still much better than the random policy&#41;.  If we allow training for 10-100 million episodes, which is necessary to get a reasonable sample size for each state, then the results are much improved with episode step lengths from 11 to 18 for track 1 and 9 to 16 for track2.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA"+=հpersist_js_state·has_pluto_hook_features§cell_id$ffd1e39d-e66b-40a3-8ad1-c9480d371fe8depends_on_disabled_cells§runtime Vpublished_object_keysdepends_on_skipped_cells§errored$13cc524c-d983-44f4-8731-0595249fb888queued¤logsrunning¦outputbody/monte_carlo_ES (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA%persist_js_state·has_pluto_hook_features§cell_id$13cc524c-d983-44f4-8731-0595249fb888depends_on_disabled_cells§runtime D~published_object_keysdepends_on_skipped_cells§errored$8faca500-b80d-4b50-88b6-683d18a1286bqueued¤logsrunning¦outputbodyelements-0.254243text/plain0.91244text/plaintypeTupleobjectid8788401422089bb3mime!application/vnd.pluto.tree+objectrootassigneelast_run_timestampA*persist_js_state·has_pluto_hook_features§cell_id$8faca500-b80d-4b50-88b6-683d18a1286bdepends_on_disabled_cells§runtimeopublished_object_keysdepends_on_skipped_cells§errored$755be8f1-9d9e-4afd-8a70-07fab78e4333queued¤logsrunning¦outputbody-<div class="markdown"><h5>Track 2</h5>
</div>mimetext/htmlrootassigneelast_run_timestampA"+]persist_js_state·has_pluto_hook_features§cell_id$755be8f1-9d9e-4afd-8a70-07fab78e4333depends_on_disabled_cells§runtime Tpublished_object_keysdepends_on_skipped_cells§errored$01683e11-a368-45bc-abbc-bbd5c94d7b22queued¤logsrunning¦outputbody+plot_value (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA%ϰpersist_js_state·has_pluto_hook_features§cell_id$01683e11-a368-45bc-abbc-bbd5c94d7b22depends_on_disabled_cells§runtime /ȵpublished_object_keysdepends_on_skipped_cells§errored$5e2420fb-b2cc-49fc-91e3-3de80fba698bqueued¤logsrunning¦outputbody(runrace (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA/Ӓpersist_js_state·has_pluto_hook_features§cell_id$5e2420fb-b2cc-49fc-91e3-3de80fba698bdepends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$1e6f7e5e-c5ce-479c-abbb-6c388c254626queued¤logsrunning¦outputbody)updateV! (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA)g	persist_js_state·has_pluto_hook_features§cell_id$1e6f7e5e-c5ce-479c-abbb-6c388c254626depends_on_disabled_cells§runtime 9 µpublished_object_keysdepends_on_skipped_cells§errored$5e012ead-b4f9-45a9-979d-88b0b1086263queued¤logsrunning¦outputbodyelementsprefixFloat32elements0.0text/plain0.0text/plain1.0text/plain1.0text/plain1.0text/plain1.0text/plain1.0text/plain1.0text/plain	1.0text/plainmored1.0text/plaintypeArrayprefix_shortobjectid19fc08302fa52c8b!application/vnd.pluto.tree+object2×1 Matrix{Float32}:
 1.0
 0.0text/plainprefixFloat32elements0.0text/plain0.0text/plain8.0text/plain0.0text/plain0.0text/plain0.0text/plain0.0text/plain0.0text/plain	0.0text/plainmored0.0text/plaintypeArrayprefix_shortobjectid28d9ec024d60f38f!application/vnd.pluto.tree+objecttypeTupleobjectid41645d3d17ae1bfmime!application/vnd.pluto.tree+objectrootassigneelast_run_timestampA.{apersist_js_state·has_pluto_hook_features§cell_id$5e012ead-b4f9-45a9-979d-88b0b1086263depends_on_disabled_cells§runtime#published_object_keysdepends_on_skipped_cells§errored$a0eb6939-11bb-458d-bee3-9ed763819f62queued¤logsrunning¦outputbodyB<div class="markdown"><h4>Racetrack Visualization Code</h4>
</div>mimetext/htmlrootassigneelast_run_timestampA"*	persist_js_state·has_pluto_hook_features§cell_id$a0eb6939-11bb-458d-bee3-9ed763819f62depends_on_disabled_cells§runtime (published_object_keysdepends_on_skipped_cells§errored$21d248f5-edad-4614-8c1c-ae330f9e5a18queued¤logsrunning¦outputbodymimetext/plainrootassigneelast_run_timestampA$ܹpersist_js_state·has_pluto_hook_features§cell_id$21d248f5-edad-4614-8c1c-ae330f9e5a18depends_on_disabled_cells§runtime /=cpublished_object_keysdepends_on_skipped_cells§errored$a68b4965-c392-47e5-9b29-93e7ada9990aqueued¤logsrunning¦outputbody,plot_fig5_1 (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA)znpersist_js_state·has_pluto_hook_features§cell_id$a68b4965-c392-47e5-9b29-93e7ada9990adepends_on_disabled_cells§runtime+sǵpublished_object_keysdepends_on_skipped_cells§errored$d766d44e-3684-497c-814e-8f71740cb232queued¤logsrunning¦outputbody<div class="markdown"><h3><strong>Figure 5.1</strong>:</h3>
<p>Approximate state-value functions for the blackjack policy that sticks only on 20 or 21, computed by Monte Carlo policy evaluation</p>
</div>mimetext/htmlrootassigneelast_run_timestampA"&I#persist_js_state·has_pluto_hook_features§cell_id$d766d44e-3684-497c-814e-8f71740cb232depends_on_disabled_cells§runtime D]published_object_keysdepends_on_skipped_cells§errored$0dfd7afb-127c-4afd-8374-3c9a20a9ee76queued¤logsrunning¦outputbody2π_racetrack_rand (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA0EWpersist_js_state·has_pluto_hook_features§cell_id$0dfd7afb-127c-4afd-8374-3c9a20a9ee76depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$bf33230e-342b-4486-89ac-9667438de503queued¤logsrunning¦outputbody<div class="markdown"><blockquote>
<h3><em>Exercise 5.8</em></h3>
<p>The results with Example 5.5 and shown in Figure 5.4 used a first-visit MC method.  Suppose that instead an every-visit MC method was used on the same problem.  Would the variance of the estimator still be infinite?  Why or why not?</p>
</blockquote>
<p>The state value estimate can be computed by summing terms for all of the episode lengths just like for the first visit method.  Each episode has a reward of &#43;1 from the terminal transition and we only need to consider episodes that take the left action.  <span class="tex">$\frac&#123;\pi&#40;A_t|S_t&#41;&#125;&#123;b&#40;A_t|S_t&#41;&#125; &#61; 2$</span> for all cases, so the importance sampling ratio is just <span class="tex">$2^T$</span> where T is the total length of that episode.  The probabilities for each episode length is unchanged from Example 5.5 and is just 0.1 times 0.9 times the number of steps preceeding the terminal step.  Compared to the calculation in Example 5.5, the expected value calculation must also have the importance sampling ratio terms for all of N visits in the length N episode instead of just the first one:</p>
<p>Length 1 episode</p>
<p class="tex">$$\frac&#123;1&#125;&#123;2&#125; \cdot 0.1 \cdot &#40;2&#41;^2$$</p>
<p>Length 2 episode, the term representing X is now an average of every visit along the trajectory.  The probability of the trajectory is unchanged from before.</p>
<p class="tex">$$\frac&#123;1&#125;&#123;2&#125; \cdot 0.9 \cdot \frac&#123;1&#125;&#123;2&#125; \cdot 0.1 \left &#40; \frac&#123;2^2 &#43; 2&#125;&#123;2&#125; \right&#41;^2$$</p>
<p>Length 3 episode</p>
<p class="tex">$$\frac&#123;1&#125;&#123;2&#125; \cdot 0.9 \cdot \frac&#123;1&#125;&#123;2&#125; \cdot 0.9 \cdot \frac&#123;1&#125;&#123;2&#125; \cdot 0.1 \left &#40; \frac&#123;2^3 &#43; 2^2 &#43; 2&#125;&#123;3&#125; \right&#41;^2$$</p>
<p>Length N episode</p>
<p class="tex">$$&#61;0.1 \left &#40; \frac&#123;1&#125;&#123;2&#125; \right &#41; ^N 0.9^&#123;N-1&#125; \left &#40; \frac&#123;\sum_&#123;i&#61;1&#125;^N 2^i&#125;&#123;N&#125; \right &#41; ^2$$</p>
<p>So the expected value is the sum of these terms for every possible episode length:</p>
</div>mimetext/htmlrootassigneelast_run_timestampA"(persist_js_state·has_pluto_hook_features§cell_id$bf33230e-342b-4486-89ac-9667438de503depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$826139cc-b52e-11ec-0d47-25ab689851fdqueued¤logsrunning¦outputbody<div class="markdown"><h1>Chapter 5: Monte Carlo Methods</h1>
<p>In this chapter we will use a sampling technique that does not require complete knowledge of the environment, only the ability to interact with it.  We will focus on episodic tasks so that the sampled returns are always well defined.  Unlike the dynamic programming methods from before, these techniques will estimate the value functions rather than computing them directly.  With enough samples, these techniques will also converge to the correct solution.</p>
<h2>5.1 Monte Carlo Prediction</h2>
<p>First we consider using Monte Carlo methods to learn the state-value function for a given policy.  The most obvious way to estimate this is to simply average the returns observed after vising a particular state.  If we save the trajectories of an agent interacting with an MDP, we can keep track of how many times an agent visits a state.  In the technique called <em>first visit MC</em> we look at the returns accumulated after the first visit to a state in that episode only making a single update. It is also possible to update the state value for every visit that occurs in an episode, but the theoretical properties for <em>first visit MC</em> are more widely studied.  Both techniques, however, can be shown to converge as the number of visits goes to infinity.  Below is code implementing Monte Carlo prediction using <em>every visit MC</em> and an in place update of the average</p>
</div>mimetext/htmlrootassigneelast_run_timestampA"&9persist_js_state·has_pluto_hook_features§cell_id$826139cc-b52e-11ec-0d47-25ab689851fddepends_on_disabled_cells§runtime spublished_object_keysdepends_on_skipped_cells§errored$0bd705cb-ad38-4cbb-b8fc-7e0617635282queued¤logsrunning¦outputbodyك<div class="markdown"><h3>Optimal Blackjack Policy Found with Off-policy MC control &#40;behavior policy is random&#41;</h3>
</div>mimetext/htmlrootassigneelast_run_timestampA")Rpersist_js_state·has_pluto_hook_features§cell_id$0bd705cb-ad38-4cbb-b8fc-7e0617635282depends_on_disabled_cells§runtime $published_object_keysdepends_on_skipped_cells§errored$43f9b824-fd56-4d56-84c3-23e2a3a37178queued¤logsrunning¦outputbody0.99608f0mimetext/plainrootassigneelast_run_timestampA+qpersist_js_state·has_pluto_hook_features§cell_id$43f9b824-fd56-4d56-84c3-23e2a3a37178depends_on_disabled_cells§runtimeft_published_object_keysdepends_on_skipped_cells§errored$b39d1ea0-86a2-4215-ae73-e4492f3f2f00queued¤logsrunning¦outputbodyc<div class="markdown"><h3>Example 5.4: Off-policy Estimation of a Blackjack State Value</h3>
</div>mimetext/htmlrootassigneelast_run_timestampA"("persist_js_state·has_pluto_hook_features§cell_id$b39d1ea0-86a2-4215-ae73-e4492f3f2f00depends_on_disabled_cells§runtime ĵpublished_object_keysdepends_on_skipped_cells§errored$a307e780-996a-485f-af59-b44982dfceb4queued¤logsrunning¦outputbody,rendertrack (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA/Dpersist_js_state·has_pluto_hook_features§cell_id$a307e780-996a-485f-af59-b44982dfceb4depends_on_disabled_cells§runtime (published_object_keysdepends_on_skipped_cells§errored$b040f245-b2d6-4ec6-aa7f-511c54aabd0dqueued¤logsrunning¦outputbody <div class="markdown"><table><tr><th align="right"></th><th align="center"><span class="tex">$\pi_*$</span> &#40;Black &#61; Stick, White &#61; Hit&#41;</th><th align="center"><span class="tex">$v_*$</span></th></tr><tr><td align="right">Usable ace</td><td align="center">	<script id='plot_1'>
		// We start by putting all the variable interpolation here at the beginning
		// We have to convert all typedarrays in the layout to normal arrays. See Issue #25
		// We use lodash for this for compactness
		function removeTypedArray(o) {
			return _.isTypedArray(o) ? Array.from(o) :
			_.isPlainObject(o) ? _.mapValues(o, removeTypedArray) : 
			o
		}

		// Publish the plot object to JS
		let plot_obj = _.update(/* See the documentation for AbstractPlutoDingetjes.Display.published_to_js */ getPublishedObject("c6e0de0c-3901-11f0-234e-bd09c571f662/70ef6091712c9d41"), "layout", removeTypedArray)
		// Get the plotly listeners
		const plotly_listeners = {}
		// Get the JS listeners
		const js_listeners = {}
		// Deal with eventual custom classes
		let custom_classlist = []


		// Load the plotly library
		let Plotly = undefined
		try {
			let _mod = await import("./plotlyjs/plotlyjs-2.26.2.min.js")
			Plotly = _mod.default
		} catch (e) {
			console.log("Local load failed, trying with the web esm.sh version")
			let _mod = await import("https://esm.sh/plotly.js-dist-min@2.26.2/es2022/plotly.js-dist-min.mjs")
			Plotly = _mod.default
		}

		// Check if we have to force local mathjax font cache
		if (false && window?.MathJax?.config?.svg?.fontCache === 'global') {
			window.MathJax.config.svg.fontCache = 'local'
		}

		// Flag to check if this cell was  manually ran or reactively ran
const firstRun = this ? false : true
const CONTAINER = this ?? html`<div class='plutoplotly-container'>`
const PLOT = CONTAINER.querySelector('.js-plotly-plot') ?? CONTAINER.appendChild(html`<div>`)
const parent = CONTAINER.parentElement
// We use a controller to remove event listeners upon invalidation
const controller = new AbortController()
// We have to add this to keep supporting @bind with the old API using PLOT
PLOT.addEventListener('input', (e) => {
	CONTAINER.value = PLOT.value
	if (e.bubbles) {
		return
	}
	CONTAINER.dispatchEvent(new CustomEvent('input'))
}, { signal: controller.signal })

	// This create the style subdiv on first run
	firstRun && CONTAINER.appendChild(html`
	<style>
	.plutoplotly-container {
		width: 100%;
		height: 100%;
		min-height: 0;
		min-width: 0;
	}
	.plutoplotly-container .js-plotly-plot .plotly div {
		margin: 0 auto; // This centers the plot
	}
	.plutoplotly-container.popped-out {
		overflow: auto;
		z-index: 1000;
		position: fixed;
		resize: both;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		border-top-left-radius: 0px;
		border-top-right-radius: 0px;
	}
	.plutoplotly-clipboard-header {
		display: flex;
		flex-flow: row wrap;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-top-left-radius: 12px;
		border-top-right-radius: 12px;
		position: fixed;
		z-index: 1001;
		cursor: move;
		transform: translate(0px, -100%);
		padding: 5px;
	}
	.plutoplotly-clipboard-header span {
		display: inline-block;
		flex: 1
	}
	.plutoplotly-clipboard-header.hidden {
		display: none;
	}
	.clipboard-span {
		position: relative;
	}
	.clipboard-value {
		padding-right: 5px;
		padding-left: 2px;
		cursor: text;
	}
	.clipboard-span.format {
		display: none;
	}
	.clipboard-span.filename {
		flex: 0 0 100%;
		text-align: center;
		border-top: 3px solid var(--kbd-border-color);
		margin-top: 5px;
		display: none;
	}
	.plutoplotly-container.filesave .clipboard-span.filename {
		display: inline-block;
	}
	.clipboard-value.filename {
		margin-left: 3px;
		text-align: left;
		min-width: min(60%, min-content);
	}
	.plutoplotly-container.filesave .clipboard-span.format {
		display: inline-flex;
	}
	.clipboard-span.format .label {
		flex: 0 0 0;
	}
	.clipboard-value.format {
		position: relative;
		flex: 1 0 auto;
		min-width: 30px;
		margin-right: 10px;
	}
	div.format-options {
		display: inline-flex;
		flex-flow: column;
		position: absolute;
		background: var(--main-bg-color);
		border-radius: 12px;
		padding-left: 3px;
		z-index: 2000;
	}
	div.format-options:hover {
		cursor: pointer;
		border: 3px solid var(--kbd-border-color);
		padding: 3px;
		transform: translate(-3px, -6px);
	}
	div.format-options .format-option {
		display: none;
	}
	div.format-options:hover .format-option {
		display: inline-block;
	}
	.format-option:not(.selected) {
		margin-top: 3px;
	}
	div.format-options .format-option.selected {
		order: -1;
		display: inline-block;
	}
	.format-option:hover {
		background-color: var(--kbd-border-color);
	}
	span.config-value {
		font-weight: normal;
		color: var(--pluto-output-color);
		display: none;
		position: absolute;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		transform: translate(0px, calc(-100% - 10px));
		padding: 5px;
	}
	.label {
		user-select: none;
	}
	.label:hover span.config-value {
		display: inline-block;
		min-width: 150px;
	}
	.clipboard-span.matching-config .label {
		color: var(--cm-macro-color);
		font-weight: bold;
	}
	.clipboard-span.different-config .label {
		color: var(--cm-tag-color);
		font-weight: bold;
	}
</style>
`)

let original_height = plot_obj.layout.height
let original_width = plot_obj.layout.width
// For the height we have to also put a fixed value in case the plot is put on a non-fixed-size container (like the default wrapper)
// We define a variable to check whether we still have to remove the fixed height
let remove_container_size = firstRun
let container_height = original_height ?? PLOT.container_height ?? 400
CONTAINER.style.height = container_height + 'px'

// We create a Promise version of setTimeout
function delay(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

// We import interact for dragging/resizing
const { default: interact } = await import('https://esm.sh/interactjs@1.10.19')


function getImageOptions() {
  const o = plot_obj.config.toImageButtonOptions ?? {};
  return {
    format: o.format ?? "png",
    width: o.width ?? original_width,
    height: o.height ?? original_height,
    scale: o.scale ?? 1,
    filename: o.filename ?? "newplot",
  };
}

const CLIPBOARD_HEADER =
  CONTAINER.querySelector(".plutoplotly-clipboard-header") ??
  CONTAINER.insertAdjacentElement(
    "afterbegin",
    html`<div class="plutoplotly-clipboard-header hidden">
      <span class="clipboard-span format"
        ><span class="label">Format:</span
        ><span class="clipboard-value format"></span
      ></span>
      <span class="clipboard-span width"
        ><span class="label">Width:</span
        ><span class="clipboard-value width"></span>px</span
      >
      <span class="clipboard-span height"
        ><span class="label">Height:</span
        ><span class="clipboard-value height"></span>px</span
      >
      <span class="clipboard-span scale"
        ><span class="label">Scale:</span
        ><span class="clipboard-value scale"></span
      ></span>
      <button class="clipboard-span set">Set</button>
      <button class="clipboard-span unset">Unset</button>
      <span class="clipboard-span filename"
        ><span class="label">Filename:</span
        ><span class="clipboard-value filename"></span
      ></span>
    </div>`
  );

function checkConfigSync(container) {
  const valid_classes = [
    "missing-config",
    "matching-config",
    "different-config",
  ];
  function setClass(cl) {
    for (const name of valid_classes) {
      container.classList.toggle(name, name == cl);
    }
  }
  // We use the custom getters we'll set up in the container
  const { ui_value, config_value, config_span, key } = container;
  if (config_value === undefined) {
    setClass("missing-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> is not present in the config.`;
  } else if (ui_value == config_value) {
    setClass("matching-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has the same value in the config and in the header.`;
  } else {
    setClass("different-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has a different value (<em>${config_value}</em>) in the config.`;
  }
  // Add info about setting and unsetting
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click on the label <em><b>once</b></em> to set the current UI value in the config.`
  );
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click <em><b>twice</b></em> to remove this key from the config.`
  );
}

const valid_formats = ["png", "svg", "webp", "jpeg", "full-json"];
function initializeUIValueSpan(span, key, value) {
  const container = span.closest(".clipboard-span");
  span.contentEditable = key === "format" ? "false" : "true";
  let parse = (x) => x;
  let update = (x) => (span.textContent = x);
  if (key === "width" || key === "height") {
    parse = (x) => Math.round(parseFloat(x));
  } else if (key === "scale") {
    parse = parseFloat;
  } else if (key === "format") {
    // We remove contentEditable
    span.contentEditable = "false";
    // Here we first add the subspans for each option
    const opts_div = span.appendChild(html`<div class="format-options"></div>`);
    for (const fmt of valid_formats) {
      const opt = opts_div.appendChild(
        html`<span class="format-option ${fmt}">${fmt}</span>`
      );
      opt.onclick = (e) => {
        span.value = opt.textContent;
      };
    }
    parse = (x) => {
      return valid_formats.includes(x) ? x : localValue;
    };
    update = (x) => {
      for (const opt of opts_div.children) {
        opt.classList.toggle("selected", opt.textContent === x);
      }
    };
  } else {
    // We only have filename here
  }
  let localValue;
  Object.defineProperty(span, "value", {
    get: () => {
      return localValue;
    },
    set: (val) => {
      if (val !== "") {
        localValue = parse(val);
      }
      update(localValue);
      checkConfigSync(container);
    },
  });
  // We also assign a listener so that the editable is blurred when enter is pressed
  span.onkeydown = (e) => {
    if (e.keyCode === 13) {
      e.preventDefault();
      span.blur();
    }
  };
  span.value = value;
}

function initializeConfigValueSpan(span, key) {
  // Here we mostly want to define the setter and getter
  const container = span.closest(".clipboard-span");
  Object.defineProperty(span, "value", {
    get: () => {
      return plot_obj.config.toImageButtonOptions[key];
    },
    set: (val) => {
      // if undefined is passed, we remove the entry from the options
      if (val === undefined) {
        delete plot_obj.config.toImageButtonOptions[key];
      } else {
        plot_obj.config.toImageButtonOptions[key] = val;
      }
      checkConfigSync(container);
    },
  });
}

const config_spans = {};
for (const [key, value] of Object.entries(getImageOptions())) {
  const container = CLIPBOARD_HEADER.querySelector(`.clipboard-span.${key}`);
  const label = container.querySelector(".label");
  // We give the label a function that on single click will set the current value and with double click will unset it
  label.onclick = DualClick(
    () => {
      container.config_value = container.ui_value;
    },
    (e) => {
      console.log("e", e);
      e.preventDefault();
      container.config_value = undefined;
    }
  );
  const ui_value_span = container.querySelector(".clipboard-value");
  const config_value_span =
    container.querySelector(".config-value") ??
    label.insertAdjacentElement(
      "afterbegin",
      html`<span class="config-value"></span>`
    );
  // Assing the two spans as properties of the containing span
  container.ui_span = ui_value_span;
  container.config_span = config_value_span;
  container.key = key;
  config_spans[key] = container;
  if (firstRun) {
    plot_obj.config.toImageButtonOptions =
      plot_obj.config.toImageButtonOptions ?? {};
    // We do the initialization of the value span
    initializeUIValueSpan(ui_value_span, key, value);
    // Then we initialize the config value
    initializeConfigValueSpan(config_value_span, key);
    // We put some convenience getters/setters
    // ui_value forward
    Object.defineProperty(container, "ui_value", {
      get: () => ui_value_span.value,
      set: (val) => {
        ui_value_span.value = val;
      },
    });
    // config_value forward
    Object.defineProperty(container, "config_value", {
      get: () => config_value_span.value,
      set: (val) => {
        config_value_span.value = val;
      },
    });
  }
}

// These objects will contain the default value

// This code updates the image options in the PLOT config with the provided ones
function setImageOptions(o) {
  for (const [key, container] of Object.entries(config_spans)) {
    container.config_value = o[key];
  }
}
function unsetImageOptions() {
  setImageOptions({});
}

const set_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.set");
const unset_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.unset");
if (firstRun) {
  set_button.onclick = (e) => {
    for (const container of Object.values(config_spans)) {
      container.config_value = container.ui_value;
    }
  };
  unset_button.onclick = unsetImageOptions;
}

// We add a function to check if the clipboard is popped out
CONTAINER.isPoppedOut = () => {
  return CONTAINER.classList.contains("popped-out");
};

CLIPBOARD_HEADER.onmousedown = function (event) {
  if (event.target.matches("span.clipboard-value")) {
    console.log("We don't move!");
    return;
  }
  const start = {
    left: parseFloat(CONTAINER.style.left),
    top: parseFloat(CONTAINER.style.top),
    X: event.pageX,
    Y: event.pageY,
  };
  function moveAt(event, start) {
    const top = event.pageY - start.Y + start.top + "px";
    const left = event.pageX - start.X + start.left + "px";
    CLIPBOARD_HEADER.style.left = left;
    CONTAINER.style.left = left;
    CONTAINER.style.top = top;
  }

  // move our absolutely positioned ball under the pointer
  moveAt(event, start);
  function onMouseMove(event) {
    moveAt(event, start);
  }

  // We use this to remove the mousemove when clicking outside of the container
  const controller = new AbortController();

  // move the container on mousemove
  document.addEventListener("mousemove", onMouseMove, {
    signal: controller.signal,
  });
  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        cleanUp();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );

  function cleanUp() {
    console.log("cleaning up the plot move listener");
    controller.abort();
    CLIPBOARD_HEADER.onmouseup = null;
  }

  // (3) drop the ball, remove unneeded handlers
  CLIPBOARD_HEADER.onmouseup = cleanUp;
};

function sendToClipboard(blob) {
  if (!navigator.clipboard) {
    alert(
      "The Clipboard API does not seem to be available, make sure the Pluto notebook is being used from either localhost or an https source."
    );
  }
  navigator.clipboard
    .write([
      new ClipboardItem({
        // The key is determined dynamically based on the blob's type.
        [blob.type]: blob,
      }),
    ])
    .then(
      function () {
        console.log("Async: Copying to clipboard was successful!");
      },
      function (err) {
        console.error("Async: Could not copy text: ", err);
      }
    );
}

function copyImageToClipboard() {
  // We extract the image options from the provided parameters (if they exist)
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key. We also ignore format because the clipboard only supports png.
    if (val === undefined || key === "format") {
      continue;
    }
    config[key] = val;
  }
  Plotly.toImage(PLOT, config).then(function (dataUrl) {
    fetch(dataUrl)
      .then((res) => res.blob())
      .then((blob) => {
        const paste_receiver = document.querySelector('paste-receiver.plutoplotly')
        if (paste_receiver) {
          paste_receiver.attachImage(dataUrl, CONTAINER)
        }
        sendToClipboard(blob)
      });
  });
}

function saveImageToFile() {
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key.
    if (val === undefined) {
      continue;
    }
    config[key] = val;
  }
  Plotly.downloadImage(PLOT, config);
}

let container_rect = { width: 0, height: 0, top: 0, left: 0 };
function unpop_container(cl) {
  CONTAINER.classList.toggle("popped-out", false);
  CONTAINER.classList.toggle(cl, false);
  // We fix the height back to the value it had before popout, also setting the flag to signal that upon first resize we remove the fixed inline-style
  CONTAINER.style.height = container_rect.height + "px";
  remove_container_size = true;
  // We set the other fixed inline-styles to null
  CONTAINER.style.width = "";
  CONTAINER.style.top = "";
  CONTAINER.style.left = "";
  // We also remove the CLIPBOARD_HEADER
  CLIPBOARD_HEADER.style.width = "";
  CLIPBOARD_HEADER.style.left = "";
  // Finally we remove the hidden class to the header
  CLIPBOARD_HEADER.classList.toggle("hidden", true);
  return;
}
function popout_container(opts) {
  const cl = opts?.cl;
  const target_container_size = opts?.target_container_size ?? {};
  const target_plot_size = opts?.target_plot_size ?? {};
  if (CONTAINER.isPoppedOut()) {
    return unpop_container(cl);
  }
  CONTAINER.classList.toggle(cl, cl === undefined ? false : true);
  // We extract the current size of the container, save them and fix them
  const { width, height, top, left } = CONTAINER.getBoundingClientRect();
  container_rect = { width, height, top, left };
  // We save the current plot size before we pop as it will fill the screen
  const current_plot_size = {
    width: PLOT._fullLayout.width,
    height: PLOT._fullLayout.height,
  };
  // We have to save the pad data before popping so we can resize precisely
  const pad = {};
  pad.unpopped = getSizeData().container_pad;
  CONTAINER.classList.toggle("popped-out", true);
  pad.popped = getSizeData().container_pad;
  // We do top and left based on the current rect
  for (const key of ["top", "left"]) {
    const start_val = target_container_size[key] ?? container_rect[key];
    let offset = 0;
    for (const kind of ["padding", "border"]) {
      offset += pad.popped[kind][key] - pad.unpopped[kind][key];
    }
    CONTAINER.style[key] = start_val - offset + "px";
    if (key === "left") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  // We compute the width and height depending on eventual config data
  const csz = computeContainerSize({
    width:
      target_plot_size.width ??
      config_spans.width.config_value ??
      current_plot_size.width,
    height:
      target_plot_size.height ??
      config_spans.height.config_value ??
      current_plot_size.height,
  });
  for (const key of ["width", "height"]) {
    const val = target_container_size[key] ?? csz[key];
    CONTAINER.style[key] = val + "px";
    if (key === "width") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  CLIPBOARD_HEADER.classList.toggle("hidden", false);
  const controller = new AbortController();

  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        unpop_container();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );
}

CONTAINER.popOut = popout_container;

function DualClick(single_func, dbl_func) {
  let nclicks = 0;
  return function (...args) {
    nclicks += 1;
    if (nclicks > 1) {
      dbl_func(...args);
      nclicks = 0;
    } else {
      delay(300).then(() => {
        if (nclicks == 1) {
          single_func(...args);
        }
        nclicks = 0;
      });
    }
  };
}

// We remove the default download image button
plot_obj.config.modeBarButtonsToRemove = _.union(
  plot_obj.config.modeBarButtonsToRemove,
  ["toImage"]
);
// We add the custom button to the modebar
plot_obj.config.modeBarButtonsToAdd = _.union(
  plot_obj.config.modeBarButtonsToAdd,
  [
    {
      name: "Copy PNG to Clipboard",
      icon: {
        height: 520,
        width: 520,
        path: "M280 64h40c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128C0 92.7 28.7 64 64 64h40 9.6C121 27.5 153.3 0 192 0s71 27.5 78.4 64H280zM64 112c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16H320c8.8 0 16-7.2 16-16V128c0-8.8-7.2-16-16-16H304v24c0 13.3-10.7 24-24 24H192 104c-13.3 0-24-10.7-24-24V112H64zm128-8a24 24 0 1 0 0-48 24 24 0 1 0 0 48z",
      },
      direction: "up",
      click: DualClick(copyImageToClipboard, () => {
        popout_container();
      }),
    },
    {
      name: "Download Image",
      icon: Plotly.Icons.camera,
      direction: "up",
      click: DualClick(saveImageToFile, () => {
        popout_container({ cl: "filesave" });
      }),
    },
  ]
);

function getOffsetData(el) {
  let cs = window.getComputedStyle(el, null);
  const odata = {
    padding: {
      left: parseFloat(cs.paddingLeft),
      right: parseFloat(cs.paddingRight),
      top: parseFloat(cs.paddingTop),
      bottom: parseFloat(cs.paddingBottom),
      width: parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight),
      height: parseFloat(cs.paddingTop) + parseFloat(cs.paddingBottom),
    },
    border: {
      left: parseFloat(cs.borderLeftWidth),
      right: parseFloat(cs.borderRightWidth),
      top: parseFloat(cs.borderTopWidth),
      bottom: parseFloat(cs.borderBottomWidth),
      width: parseFloat(cs.borderLeftWidth) + parseFloat(cs.borderRightWidth),
      height: parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth),
    }
  };
  if (el === PLOT) {
    // For the PLOT we also want to take into account the offset
    odata.offset = {
      top: PLOT.offsetParent == CONTAINER ? PLOT.offsetTop : 0,
      left: PLOT.offsetParent == CONTAINER ? PLOT.offsetLeft : 0,
    }
  }
  return odata;
}
function getSizeData() {
  const data = {
    plot_pad: getOffsetData(PLOT),
    plot_rect: PLOT.getBoundingClientRect(),
    container_pad: getOffsetData(CONTAINER),
    container_rect: CONTAINER.getBoundingClientRect(),
  };
  return data;
}
function computeContainerSize({ width, height }, sizeData = getSizeData()) {
  const computed_size = computePlotSize(sizeData);
  const offsets = computed_size.offsets;

  const plot_data = {
    width: width ?? computed_size.width,
    height: height ?? computed_size.height,
  };

  return {
    width: (width ?? computed_size.width) + offsets.width,
    height: (height ?? computed_size.height) + offsets.height,
    noChange: width == computed_size.width && height == computed_size.height,
  }
}

// This function will change the container size so that the resulting plot will be matching the provided specs
function changeContainerSize({ width, height }, sizeData = getSizeData()) {
  if (!CONTAINER.isPoppedOut()) {
    console.log("Tried to change container size when not popped, ignoring");
    return;
  }

  const csz = computeContainerSize({ width, height }, sizeData);

  if (csz.noChange) {
    console.log("Size is the same as current, ignoring");
    return
  }
  // We are now going to set he width and height of the container
  for (const key of ["width", "height"]) {
    CONTAINER.style[key] = csz[key] + "px";
  }
}
// We now create the function that will update the plot based on the values specified
function updateFromHeader() {
  const header_data = {
    height: config_spans.height.ui_value,
    width: config_spans.width.ui_value,
  };
  changeContainerSize(header_data);
}
// We assign this function to the onblur event of width and height
if (firstRun) {
  for (const container of Object.values(config_spans)) {
    container.ui_span.onblur = (e) => {
      container.ui_value = container.ui_span.textContent;
      updateFromHeader();
    };
  }
}
// This function computes the plot size to use for relayout as a function of the container size
function computePlotSize(data = getSizeData()) {
  // Remove Padding
  const { container_pad, plot_pad, container_rect } = data;
  const offsets = {
    width:
      plot_pad.padding.width +
      plot_pad.border.width +
      plot_pad.offset.left +
      container_pad.padding.width +
      container_pad.border.width,
    height:
      plot_pad.padding.height +
      plot_pad.border.height +
      plot_pad.offset.top +
      container_pad.padding.height +
      container_pad.border.height,
  };
  const sz = {
    width: Math.round(container_rect.width - offsets.width),
    height: Math.round(container_rect.height - offsets.height),
    offsets,
  };
  return sz;
}

// Create the resizeObserver to make the plot even more responsive! :magic:
const resizeObserver = new ResizeObserver((entries) => {
  const sizeData = getSizeData();
  const {container_rect, container_pad} = sizeData;
  let plot_size = computePlotSize(sizeData);
  // We save the height in the PLOT object
  PLOT.container_height = container_rect.height;
  // We deal with some stuff if the container is poppped
  CLIPBOARD_HEADER.style.width = container_rect.width + "px";
  CLIPBOARD_HEADER.style.left = container_rect.left + "px";
  config_spans.height.ui_value = plot_size.height;
  config_spans.width.ui_value = plot_size.width;
  /* 
		The addition of the invalid argument `plutoresize` seems to fix the problem with calling `relayout` simply with `{autosize: true}` as update breaking mouse relayout events tracking. 
		See https://github.com/plotly/plotly.js/issues/6156 for details
		*/
  let config = {
    // If this is popped out, we ignore the original width/height
    width: (CONTAINER.isPoppedOut() ? undefined : original_width) ?? plot_size.width,
    height: (CONTAINER.isPoppedOut() ? undefined : original_height) ?? plot_size.height,
    plutoresize: true,
  };
  Plotly.relayout(PLOT, config).then(() => {
    if (remove_container_size && !CONTAINER.isPoppedOut()) {
      // This is needed to avoid the first resize upon plot creation to already be without a fixed height
      CONTAINER.style.height = "";
      CONTAINER.style.width = "";
      remove_container_size = false;
    }
  });
});

resizeObserver.observe(CONTAINER);


Plotly.react(PLOT, plot_obj).then(() => {
	// Assign the Plotly event listeners
	for (const [key, listener_vec] of Object.entries(plotly_listeners)) {
		for (const listener of listener_vec) {
			PLOT.on(key, listener)
		}
	}
	// Assign the JS event listeners
	for (const [key, listener_vec] of Object.entries(js_listeners)) {
		for (const listener of listener_vec) {
			PLOT.addEventListener(key, listener, {
				signal: controller.signal
			})
		}
	}
}
)


invalidation.then(() => {
	// Remove all plotly listeners
	PLOT.removeAllListeners()
	// Remove all JS listeners
	controller.abort()
	// Remove the resizeObserver
	resizeObserver.disconnect()
})



		return CONTAINER
	</script>
</td><td align="center">	<script id='plot_2'>
		// We start by putting all the variable interpolation here at the beginning
		// We have to convert all typedarrays in the layout to normal arrays. See Issue #25
		// We use lodash for this for compactness
		function removeTypedArray(o) {
			return _.isTypedArray(o) ? Array.from(o) :
			_.isPlainObject(o) ? _.mapValues(o, removeTypedArray) : 
			o
		}

		// Publish the plot object to JS
		let plot_obj = _.update(/* See the documentation for AbstractPlutoDingetjes.Display.published_to_js */ getPublishedObject("c6e0de0c-3901-11f0-234e-bd09c571f662/cfb9dac3af175b34"), "layout", removeTypedArray)
		// Get the plotly listeners
		const plotly_listeners = {}
		// Get the JS listeners
		const js_listeners = {}
		// Deal with eventual custom classes
		let custom_classlist = []


		// Load the plotly library
		let Plotly = undefined
		try {
			let _mod = await import("./plotlyjs/plotlyjs-2.26.2.min.js")
			Plotly = _mod.default
		} catch (e) {
			console.log("Local load failed, trying with the web esm.sh version")
			let _mod = await import("https://esm.sh/plotly.js-dist-min@2.26.2/es2022/plotly.js-dist-min.mjs")
			Plotly = _mod.default
		}

		// Check if we have to force local mathjax font cache
		if (false && window?.MathJax?.config?.svg?.fontCache === 'global') {
			window.MathJax.config.svg.fontCache = 'local'
		}

		// Flag to check if this cell was  manually ran or reactively ran
const firstRun = this ? false : true
const CONTAINER = this ?? html`<div class='plutoplotly-container'>`
const PLOT = CONTAINER.querySelector('.js-plotly-plot') ?? CONTAINER.appendChild(html`<div>`)
const parent = CONTAINER.parentElement
// We use a controller to remove event listeners upon invalidation
const controller = new AbortController()
// We have to add this to keep supporting @bind with the old API using PLOT
PLOT.addEventListener('input', (e) => {
	CONTAINER.value = PLOT.value
	if (e.bubbles) {
		return
	}
	CONTAINER.dispatchEvent(new CustomEvent('input'))
}, { signal: controller.signal })

	// This create the style subdiv on first run
	firstRun && CONTAINER.appendChild(html`
	<style>
	.plutoplotly-container {
		width: 100%;
		height: 100%;
		min-height: 0;
		min-width: 0;
	}
	.plutoplotly-container .js-plotly-plot .plotly div {
		margin: 0 auto; // This centers the plot
	}
	.plutoplotly-container.popped-out {
		overflow: auto;
		z-index: 1000;
		position: fixed;
		resize: both;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		border-top-left-radius: 0px;
		border-top-right-radius: 0px;
	}
	.plutoplotly-clipboard-header {
		display: flex;
		flex-flow: row wrap;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-top-left-radius: 12px;
		border-top-right-radius: 12px;
		position: fixed;
		z-index: 1001;
		cursor: move;
		transform: translate(0px, -100%);
		padding: 5px;
	}
	.plutoplotly-clipboard-header span {
		display: inline-block;
		flex: 1
	}
	.plutoplotly-clipboard-header.hidden {
		display: none;
	}
	.clipboard-span {
		position: relative;
	}
	.clipboard-value {
		padding-right: 5px;
		padding-left: 2px;
		cursor: text;
	}
	.clipboard-span.format {
		display: none;
	}
	.clipboard-span.filename {
		flex: 0 0 100%;
		text-align: center;
		border-top: 3px solid var(--kbd-border-color);
		margin-top: 5px;
		display: none;
	}
	.plutoplotly-container.filesave .clipboard-span.filename {
		display: inline-block;
	}
	.clipboard-value.filename {
		margin-left: 3px;
		text-align: left;
		min-width: min(60%, min-content);
	}
	.plutoplotly-container.filesave .clipboard-span.format {
		display: inline-flex;
	}
	.clipboard-span.format .label {
		flex: 0 0 0;
	}
	.clipboard-value.format {
		position: relative;
		flex: 1 0 auto;
		min-width: 30px;
		margin-right: 10px;
	}
	div.format-options {
		display: inline-flex;
		flex-flow: column;
		position: absolute;
		background: var(--main-bg-color);
		border-radius: 12px;
		padding-left: 3px;
		z-index: 2000;
	}
	div.format-options:hover {
		cursor: pointer;
		border: 3px solid var(--kbd-border-color);
		padding: 3px;
		transform: translate(-3px, -6px);
	}
	div.format-options .format-option {
		display: none;
	}
	div.format-options:hover .format-option {
		display: inline-block;
	}
	.format-option:not(.selected) {
		margin-top: 3px;
	}
	div.format-options .format-option.selected {
		order: -1;
		display: inline-block;
	}
	.format-option:hover {
		background-color: var(--kbd-border-color);
	}
	span.config-value {
		font-weight: normal;
		color: var(--pluto-output-color);
		display: none;
		position: absolute;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		transform: translate(0px, calc(-100% - 10px));
		padding: 5px;
	}
	.label {
		user-select: none;
	}
	.label:hover span.config-value {
		display: inline-block;
		min-width: 150px;
	}
	.clipboard-span.matching-config .label {
		color: var(--cm-macro-color);
		font-weight: bold;
	}
	.clipboard-span.different-config .label {
		color: var(--cm-tag-color);
		font-weight: bold;
	}
</style>
`)

let original_height = plot_obj.layout.height
let original_width = plot_obj.layout.width
// For the height we have to also put a fixed value in case the plot is put on a non-fixed-size container (like the default wrapper)
// We define a variable to check whether we still have to remove the fixed height
let remove_container_size = firstRun
let container_height = original_height ?? PLOT.container_height ?? 400
CONTAINER.style.height = container_height + 'px'

// We create a Promise version of setTimeout
function delay(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

// We import interact for dragging/resizing
const { default: interact } = await import('https://esm.sh/interactjs@1.10.19')


function getImageOptions() {
  const o = plot_obj.config.toImageButtonOptions ?? {};
  return {
    format: o.format ?? "png",
    width: o.width ?? original_width,
    height: o.height ?? original_height,
    scale: o.scale ?? 1,
    filename: o.filename ?? "newplot",
  };
}

const CLIPBOARD_HEADER =
  CONTAINER.querySelector(".plutoplotly-clipboard-header") ??
  CONTAINER.insertAdjacentElement(
    "afterbegin",
    html`<div class="plutoplotly-clipboard-header hidden">
      <span class="clipboard-span format"
        ><span class="label">Format:</span
        ><span class="clipboard-value format"></span
      ></span>
      <span class="clipboard-span width"
        ><span class="label">Width:</span
        ><span class="clipboard-value width"></span>px</span
      >
      <span class="clipboard-span height"
        ><span class="label">Height:</span
        ><span class="clipboard-value height"></span>px</span
      >
      <span class="clipboard-span scale"
        ><span class="label">Scale:</span
        ><span class="clipboard-value scale"></span
      ></span>
      <button class="clipboard-span set">Set</button>
      <button class="clipboard-span unset">Unset</button>
      <span class="clipboard-span filename"
        ><span class="label">Filename:</span
        ><span class="clipboard-value filename"></span
      ></span>
    </div>`
  );

function checkConfigSync(container) {
  const valid_classes = [
    "missing-config",
    "matching-config",
    "different-config",
  ];
  function setClass(cl) {
    for (const name of valid_classes) {
      container.classList.toggle(name, name == cl);
    }
  }
  // We use the custom getters we'll set up in the container
  const { ui_value, config_value, config_span, key } = container;
  if (config_value === undefined) {
    setClass("missing-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> is not present in the config.`;
  } else if (ui_value == config_value) {
    setClass("matching-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has the same value in the config and in the header.`;
  } else {
    setClass("different-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has a different value (<em>${config_value}</em>) in the config.`;
  }
  // Add info about setting and unsetting
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click on the label <em><b>once</b></em> to set the current UI value in the config.`
  );
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click <em><b>twice</b></em> to remove this key from the config.`
  );
}

const valid_formats = ["png", "svg", "webp", "jpeg", "full-json"];
function initializeUIValueSpan(span, key, value) {
  const container = span.closest(".clipboard-span");
  span.contentEditable = key === "format" ? "false" : "true";
  let parse = (x) => x;
  let update = (x) => (span.textContent = x);
  if (key === "width" || key === "height") {
    parse = (x) => Math.round(parseFloat(x));
  } else if (key === "scale") {
    parse = parseFloat;
  } else if (key === "format") {
    // We remove contentEditable
    span.contentEditable = "false";
    // Here we first add the subspans for each option
    const opts_div = span.appendChild(html`<div class="format-options"></div>`);
    for (const fmt of valid_formats) {
      const opt = opts_div.appendChild(
        html`<span class="format-option ${fmt}">${fmt}</span>`
      );
      opt.onclick = (e) => {
        span.value = opt.textContent;
      };
    }
    parse = (x) => {
      return valid_formats.includes(x) ? x : localValue;
    };
    update = (x) => {
      for (const opt of opts_div.children) {
        opt.classList.toggle("selected", opt.textContent === x);
      }
    };
  } else {
    // We only have filename here
  }
  let localValue;
  Object.defineProperty(span, "value", {
    get: () => {
      return localValue;
    },
    set: (val) => {
      if (val !== "") {
        localValue = parse(val);
      }
      update(localValue);
      checkConfigSync(container);
    },
  });
  // We also assign a listener so that the editable is blurred when enter is pressed
  span.onkeydown = (e) => {
    if (e.keyCode === 13) {
      e.preventDefault();
      span.blur();
    }
  };
  span.value = value;
}

function initializeConfigValueSpan(span, key) {
  // Here we mostly want to define the setter and getter
  const container = span.closest(".clipboard-span");
  Object.defineProperty(span, "value", {
    get: () => {
      return plot_obj.config.toImageButtonOptions[key];
    },
    set: (val) => {
      // if undefined is passed, we remove the entry from the options
      if (val === undefined) {
        delete plot_obj.config.toImageButtonOptions[key];
      } else {
        plot_obj.config.toImageButtonOptions[key] = val;
      }
      checkConfigSync(container);
    },
  });
}

const config_spans = {};
for (const [key, value] of Object.entries(getImageOptions())) {
  const container = CLIPBOARD_HEADER.querySelector(`.clipboard-span.${key}`);
  const label = container.querySelector(".label");
  // We give the label a function that on single click will set the current value and with double click will unset it
  label.onclick = DualClick(
    () => {
      container.config_value = container.ui_value;
    },
    (e) => {
      console.log("e", e);
      e.preventDefault();
      container.config_value = undefined;
    }
  );
  const ui_value_span = container.querySelector(".clipboard-value");
  const config_value_span =
    container.querySelector(".config-value") ??
    label.insertAdjacentElement(
      "afterbegin",
      html`<span class="config-value"></span>`
    );
  // Assing the two spans as properties of the containing span
  container.ui_span = ui_value_span;
  container.config_span = config_value_span;
  container.key = key;
  config_spans[key] = container;
  if (firstRun) {
    plot_obj.config.toImageButtonOptions =
      plot_obj.config.toImageButtonOptions ?? {};
    // We do the initialization of the value span
    initializeUIValueSpan(ui_value_span, key, value);
    // Then we initialize the config value
    initializeConfigValueSpan(config_value_span, key);
    // We put some convenience getters/setters
    // ui_value forward
    Object.defineProperty(container, "ui_value", {
      get: () => ui_value_span.value,
      set: (val) => {
        ui_value_span.value = val;
      },
    });
    // config_value forward
    Object.defineProperty(container, "config_value", {
      get: () => config_value_span.value,
      set: (val) => {
        config_value_span.value = val;
      },
    });
  }
}

// These objects will contain the default value

// This code updates the image options in the PLOT config with the provided ones
function setImageOptions(o) {
  for (const [key, container] of Object.entries(config_spans)) {
    container.config_value = o[key];
  }
}
function unsetImageOptions() {
  setImageOptions({});
}

const set_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.set");
const unset_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.unset");
if (firstRun) {
  set_button.onclick = (e) => {
    for (const container of Object.values(config_spans)) {
      container.config_value = container.ui_value;
    }
  };
  unset_button.onclick = unsetImageOptions;
}

// We add a function to check if the clipboard is popped out
CONTAINER.isPoppedOut = () => {
  return CONTAINER.classList.contains("popped-out");
};

CLIPBOARD_HEADER.onmousedown = function (event) {
  if (event.target.matches("span.clipboard-value")) {
    console.log("We don't move!");
    return;
  }
  const start = {
    left: parseFloat(CONTAINER.style.left),
    top: parseFloat(CONTAINER.style.top),
    X: event.pageX,
    Y: event.pageY,
  };
  function moveAt(event, start) {
    const top = event.pageY - start.Y + start.top + "px";
    const left = event.pageX - start.X + start.left + "px";
    CLIPBOARD_HEADER.style.left = left;
    CONTAINER.style.left = left;
    CONTAINER.style.top = top;
  }

  // move our absolutely positioned ball under the pointer
  moveAt(event, start);
  function onMouseMove(event) {
    moveAt(event, start);
  }

  // We use this to remove the mousemove when clicking outside of the container
  const controller = new AbortController();

  // move the container on mousemove
  document.addEventListener("mousemove", onMouseMove, {
    signal: controller.signal,
  });
  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        cleanUp();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );

  function cleanUp() {
    console.log("cleaning up the plot move listener");
    controller.abort();
    CLIPBOARD_HEADER.onmouseup = null;
  }

  // (3) drop the ball, remove unneeded handlers
  CLIPBOARD_HEADER.onmouseup = cleanUp;
};

function sendToClipboard(blob) {
  if (!navigator.clipboard) {
    alert(
      "The Clipboard API does not seem to be available, make sure the Pluto notebook is being used from either localhost or an https source."
    );
  }
  navigator.clipboard
    .write([
      new ClipboardItem({
        // The key is determined dynamically based on the blob's type.
        [blob.type]: blob,
      }),
    ])
    .then(
      function () {
        console.log("Async: Copying to clipboard was successful!");
      },
      function (err) {
        console.error("Async: Could not copy text: ", err);
      }
    );
}

function copyImageToClipboard() {
  // We extract the image options from the provided parameters (if they exist)
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key. We also ignore format because the clipboard only supports png.
    if (val === undefined || key === "format") {
      continue;
    }
    config[key] = val;
  }
  Plotly.toImage(PLOT, config).then(function (dataUrl) {
    fetch(dataUrl)
      .then((res) => res.blob())
      .then((blob) => {
        const paste_receiver = document.querySelector('paste-receiver.plutoplotly')
        if (paste_receiver) {
          paste_receiver.attachImage(dataUrl, CONTAINER)
        }
        sendToClipboard(blob)
      });
  });
}

function saveImageToFile() {
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key.
    if (val === undefined) {
      continue;
    }
    config[key] = val;
  }
  Plotly.downloadImage(PLOT, config);
}

let container_rect = { width: 0, height: 0, top: 0, left: 0 };
function unpop_container(cl) {
  CONTAINER.classList.toggle("popped-out", false);
  CONTAINER.classList.toggle(cl, false);
  // We fix the height back to the value it had before popout, also setting the flag to signal that upon first resize we remove the fixed inline-style
  CONTAINER.style.height = container_rect.height + "px";
  remove_container_size = true;
  // We set the other fixed inline-styles to null
  CONTAINER.style.width = "";
  CONTAINER.style.top = "";
  CONTAINER.style.left = "";
  // We also remove the CLIPBOARD_HEADER
  CLIPBOARD_HEADER.style.width = "";
  CLIPBOARD_HEADER.style.left = "";
  // Finally we remove the hidden class to the header
  CLIPBOARD_HEADER.classList.toggle("hidden", true);
  return;
}
function popout_container(opts) {
  const cl = opts?.cl;
  const target_container_size = opts?.target_container_size ?? {};
  const target_plot_size = opts?.target_plot_size ?? {};
  if (CONTAINER.isPoppedOut()) {
    return unpop_container(cl);
  }
  CONTAINER.classList.toggle(cl, cl === undefined ? false : true);
  // We extract the current size of the container, save them and fix them
  const { width, height, top, left } = CONTAINER.getBoundingClientRect();
  container_rect = { width, height, top, left };
  // We save the current plot size before we pop as it will fill the screen
  const current_plot_size = {
    width: PLOT._fullLayout.width,
    height: PLOT._fullLayout.height,
  };
  // We have to save the pad data before popping so we can resize precisely
  const pad = {};
  pad.unpopped = getSizeData().container_pad;
  CONTAINER.classList.toggle("popped-out", true);
  pad.popped = getSizeData().container_pad;
  // We do top and left based on the current rect
  for (const key of ["top", "left"]) {
    const start_val = target_container_size[key] ?? container_rect[key];
    let offset = 0;
    for (const kind of ["padding", "border"]) {
      offset += pad.popped[kind][key] - pad.unpopped[kind][key];
    }
    CONTAINER.style[key] = start_val - offset + "px";
    if (key === "left") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  // We compute the width and height depending on eventual config data
  const csz = computeContainerSize({
    width:
      target_plot_size.width ??
      config_spans.width.config_value ??
      current_plot_size.width,
    height:
      target_plot_size.height ??
      config_spans.height.config_value ??
      current_plot_size.height,
  });
  for (const key of ["width", "height"]) {
    const val = target_container_size[key] ?? csz[key];
    CONTAINER.style[key] = val + "px";
    if (key === "width") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  CLIPBOARD_HEADER.classList.toggle("hidden", false);
  const controller = new AbortController();

  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        unpop_container();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );
}

CONTAINER.popOut = popout_container;

function DualClick(single_func, dbl_func) {
  let nclicks = 0;
  return function (...args) {
    nclicks += 1;
    if (nclicks > 1) {
      dbl_func(...args);
      nclicks = 0;
    } else {
      delay(300).then(() => {
        if (nclicks == 1) {
          single_func(...args);
        }
        nclicks = 0;
      });
    }
  };
}

// We remove the default download image button
plot_obj.config.modeBarButtonsToRemove = _.union(
  plot_obj.config.modeBarButtonsToRemove,
  ["toImage"]
);
// We add the custom button to the modebar
plot_obj.config.modeBarButtonsToAdd = _.union(
  plot_obj.config.modeBarButtonsToAdd,
  [
    {
      name: "Copy PNG to Clipboard",
      icon: {
        height: 520,
        width: 520,
        path: "M280 64h40c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128C0 92.7 28.7 64 64 64h40 9.6C121 27.5 153.3 0 192 0s71 27.5 78.4 64H280zM64 112c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16H320c8.8 0 16-7.2 16-16V128c0-8.8-7.2-16-16-16H304v24c0 13.3-10.7 24-24 24H192 104c-13.3 0-24-10.7-24-24V112H64zm128-8a24 24 0 1 0 0-48 24 24 0 1 0 0 48z",
      },
      direction: "up",
      click: DualClick(copyImageToClipboard, () => {
        popout_container();
      }),
    },
    {
      name: "Download Image",
      icon: Plotly.Icons.camera,
      direction: "up",
      click: DualClick(saveImageToFile, () => {
        popout_container({ cl: "filesave" });
      }),
    },
  ]
);

function getOffsetData(el) {
  let cs = window.getComputedStyle(el, null);
  const odata = {
    padding: {
      left: parseFloat(cs.paddingLeft),
      right: parseFloat(cs.paddingRight),
      top: parseFloat(cs.paddingTop),
      bottom: parseFloat(cs.paddingBottom),
      width: parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight),
      height: parseFloat(cs.paddingTop) + parseFloat(cs.paddingBottom),
    },
    border: {
      left: parseFloat(cs.borderLeftWidth),
      right: parseFloat(cs.borderRightWidth),
      top: parseFloat(cs.borderTopWidth),
      bottom: parseFloat(cs.borderBottomWidth),
      width: parseFloat(cs.borderLeftWidth) + parseFloat(cs.borderRightWidth),
      height: parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth),
    }
  };
  if (el === PLOT) {
    // For the PLOT we also want to take into account the offset
    odata.offset = {
      top: PLOT.offsetParent == CONTAINER ? PLOT.offsetTop : 0,
      left: PLOT.offsetParent == CONTAINER ? PLOT.offsetLeft : 0,
    }
  }
  return odata;
}
function getSizeData() {
  const data = {
    plot_pad: getOffsetData(PLOT),
    plot_rect: PLOT.getBoundingClientRect(),
    container_pad: getOffsetData(CONTAINER),
    container_rect: CONTAINER.getBoundingClientRect(),
  };
  return data;
}
function computeContainerSize({ width, height }, sizeData = getSizeData()) {
  const computed_size = computePlotSize(sizeData);
  const offsets = computed_size.offsets;

  const plot_data = {
    width: width ?? computed_size.width,
    height: height ?? computed_size.height,
  };

  return {
    width: (width ?? computed_size.width) + offsets.width,
    height: (height ?? computed_size.height) + offsets.height,
    noChange: width == computed_size.width && height == computed_size.height,
  }
}

// This function will change the container size so that the resulting plot will be matching the provided specs
function changeContainerSize({ width, height }, sizeData = getSizeData()) {
  if (!CONTAINER.isPoppedOut()) {
    console.log("Tried to change container size when not popped, ignoring");
    return;
  }

  const csz = computeContainerSize({ width, height }, sizeData);

  if (csz.noChange) {
    console.log("Size is the same as current, ignoring");
    return
  }
  // We are now going to set he width and height of the container
  for (const key of ["width", "height"]) {
    CONTAINER.style[key] = csz[key] + "px";
  }
}
// We now create the function that will update the plot based on the values specified
function updateFromHeader() {
  const header_data = {
    height: config_spans.height.ui_value,
    width: config_spans.width.ui_value,
  };
  changeContainerSize(header_data);
}
// We assign this function to the onblur event of width and height
if (firstRun) {
  for (const container of Object.values(config_spans)) {
    container.ui_span.onblur = (e) => {
      container.ui_value = container.ui_span.textContent;
      updateFromHeader();
    };
  }
}
// This function computes the plot size to use for relayout as a function of the container size
function computePlotSize(data = getSizeData()) {
  // Remove Padding
  const { container_pad, plot_pad, container_rect } = data;
  const offsets = {
    width:
      plot_pad.padding.width +
      plot_pad.border.width +
      plot_pad.offset.left +
      container_pad.padding.width +
      container_pad.border.width,
    height:
      plot_pad.padding.height +
      plot_pad.border.height +
      plot_pad.offset.top +
      container_pad.padding.height +
      container_pad.border.height,
  };
  const sz = {
    width: Math.round(container_rect.width - offsets.width),
    height: Math.round(container_rect.height - offsets.height),
    offsets,
  };
  return sz;
}

// Create the resizeObserver to make the plot even more responsive! :magic:
const resizeObserver = new ResizeObserver((entries) => {
  const sizeData = getSizeData();
  const {container_rect, container_pad} = sizeData;
  let plot_size = computePlotSize(sizeData);
  // We save the height in the PLOT object
  PLOT.container_height = container_rect.height;
  // We deal with some stuff if the container is poppped
  CLIPBOARD_HEADER.style.width = container_rect.width + "px";
  CLIPBOARD_HEADER.style.left = container_rect.left + "px";
  config_spans.height.ui_value = plot_size.height;
  config_spans.width.ui_value = plot_size.width;
  /* 
		The addition of the invalid argument `plutoresize` seems to fix the problem with calling `relayout` simply with `{autosize: true}` as update breaking mouse relayout events tracking. 
		See https://github.com/plotly/plotly.js/issues/6156 for details
		*/
  let config = {
    // If this is popped out, we ignore the original width/height
    width: (CONTAINER.isPoppedOut() ? undefined : original_width) ?? plot_size.width,
    height: (CONTAINER.isPoppedOut() ? undefined : original_height) ?? plot_size.height,
    plutoresize: true,
  };
  Plotly.relayout(PLOT, config).then(() => {
    if (remove_container_size && !CONTAINER.isPoppedOut()) {
      // This is needed to avoid the first resize upon plot creation to already be without a fixed height
      CONTAINER.style.height = "";
      CONTAINER.style.width = "";
      remove_container_size = false;
    }
  });
});

resizeObserver.observe(CONTAINER);


Plotly.react(PLOT, plot_obj).then(() => {
	// Assign the Plotly event listeners
	for (const [key, listener_vec] of Object.entries(plotly_listeners)) {
		for (const listener of listener_vec) {
			PLOT.on(key, listener)
		}
	}
	// Assign the JS event listeners
	for (const [key, listener_vec] of Object.entries(js_listeners)) {
		for (const listener of listener_vec) {
			PLOT.addEventListener(key, listener, {
				signal: controller.signal
			})
		}
	}
}
)


invalidation.then(() => {
	// Remove all plotly listeners
	PLOT.removeAllListeners()
	// Remove all JS listeners
	controller.abort()
	// Remove the resizeObserver
	resizeObserver.disconnect()
})



		return CONTAINER
	</script>
</td></tr><tr><td align="right">No usable ace</td><td align="center">	<script id='plot_3'>
		// We start by putting all the variable interpolation here at the beginning
		// We have to convert all typedarrays in the layout to normal arrays. See Issue #25
		// We use lodash for this for compactness
		function removeTypedArray(o) {
			return _.isTypedArray(o) ? Array.from(o) :
			_.isPlainObject(o) ? _.mapValues(o, removeTypedArray) : 
			o
		}

		// Publish the plot object to JS
		let plot_obj = _.update(/* See the documentation for AbstractPlutoDingetjes.Display.published_to_js */ getPublishedObject("c6e0de0c-3901-11f0-234e-bd09c571f662/4632010f9ca3f26e"), "layout", removeTypedArray)
		// Get the plotly listeners
		const plotly_listeners = {}
		// Get the JS listeners
		const js_listeners = {}
		// Deal with eventual custom classes
		let custom_classlist = []


		// Load the plotly library
		let Plotly = undefined
		try {
			let _mod = await import("./plotlyjs/plotlyjs-2.26.2.min.js")
			Plotly = _mod.default
		} catch (e) {
			console.log("Local load failed, trying with the web esm.sh version")
			let _mod = await import("https://esm.sh/plotly.js-dist-min@2.26.2/es2022/plotly.js-dist-min.mjs")
			Plotly = _mod.default
		}

		// Check if we have to force local mathjax font cache
		if (false && window?.MathJax?.config?.svg?.fontCache === 'global') {
			window.MathJax.config.svg.fontCache = 'local'
		}

		// Flag to check if this cell was  manually ran or reactively ran
const firstRun = this ? false : true
const CONTAINER = this ?? html`<div class='plutoplotly-container'>`
const PLOT = CONTAINER.querySelector('.js-plotly-plot') ?? CONTAINER.appendChild(html`<div>`)
const parent = CONTAINER.parentElement
// We use a controller to remove event listeners upon invalidation
const controller = new AbortController()
// We have to add this to keep supporting @bind with the old API using PLOT
PLOT.addEventListener('input', (e) => {
	CONTAINER.value = PLOT.value
	if (e.bubbles) {
		return
	}
	CONTAINER.dispatchEvent(new CustomEvent('input'))
}, { signal: controller.signal })

	// This create the style subdiv on first run
	firstRun && CONTAINER.appendChild(html`
	<style>
	.plutoplotly-container {
		width: 100%;
		height: 100%;
		min-height: 0;
		min-width: 0;
	}
	.plutoplotly-container .js-plotly-plot .plotly div {
		margin: 0 auto; // This centers the plot
	}
	.plutoplotly-container.popped-out {
		overflow: auto;
		z-index: 1000;
		position: fixed;
		resize: both;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		border-top-left-radius: 0px;
		border-top-right-radius: 0px;
	}
	.plutoplotly-clipboard-header {
		display: flex;
		flex-flow: row wrap;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-top-left-radius: 12px;
		border-top-right-radius: 12px;
		position: fixed;
		z-index: 1001;
		cursor: move;
		transform: translate(0px, -100%);
		padding: 5px;
	}
	.plutoplotly-clipboard-header span {
		display: inline-block;
		flex: 1
	}
	.plutoplotly-clipboard-header.hidden {
		display: none;
	}
	.clipboard-span {
		position: relative;
	}
	.clipboard-value {
		padding-right: 5px;
		padding-left: 2px;
		cursor: text;
	}
	.clipboard-span.format {
		display: none;
	}
	.clipboard-span.filename {
		flex: 0 0 100%;
		text-align: center;
		border-top: 3px solid var(--kbd-border-color);
		margin-top: 5px;
		display: none;
	}
	.plutoplotly-container.filesave .clipboard-span.filename {
		display: inline-block;
	}
	.clipboard-value.filename {
		margin-left: 3px;
		text-align: left;
		min-width: min(60%, min-content);
	}
	.plutoplotly-container.filesave .clipboard-span.format {
		display: inline-flex;
	}
	.clipboard-span.format .label {
		flex: 0 0 0;
	}
	.clipboard-value.format {
		position: relative;
		flex: 1 0 auto;
		min-width: 30px;
		margin-right: 10px;
	}
	div.format-options {
		display: inline-flex;
		flex-flow: column;
		position: absolute;
		background: var(--main-bg-color);
		border-radius: 12px;
		padding-left: 3px;
		z-index: 2000;
	}
	div.format-options:hover {
		cursor: pointer;
		border: 3px solid var(--kbd-border-color);
		padding: 3px;
		transform: translate(-3px, -6px);
	}
	div.format-options .format-option {
		display: none;
	}
	div.format-options:hover .format-option {
		display: inline-block;
	}
	.format-option:not(.selected) {
		margin-top: 3px;
	}
	div.format-options .format-option.selected {
		order: -1;
		display: inline-block;
	}
	.format-option:hover {
		background-color: var(--kbd-border-color);
	}
	span.config-value {
		font-weight: normal;
		color: var(--pluto-output-color);
		display: none;
		position: absolute;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		transform: translate(0px, calc(-100% - 10px));
		padding: 5px;
	}
	.label {
		user-select: none;
	}
	.label:hover span.config-value {
		display: inline-block;
		min-width: 150px;
	}
	.clipboard-span.matching-config .label {
		color: var(--cm-macro-color);
		font-weight: bold;
	}
	.clipboard-span.different-config .label {
		color: var(--cm-tag-color);
		font-weight: bold;
	}
</style>
`)

let original_height = plot_obj.layout.height
let original_width = plot_obj.layout.width
// For the height we have to also put a fixed value in case the plot is put on a non-fixed-size container (like the default wrapper)
// We define a variable to check whether we still have to remove the fixed height
let remove_container_size = firstRun
let container_height = original_height ?? PLOT.container_height ?? 400
CONTAINER.style.height = container_height + 'px'

// We create a Promise version of setTimeout
function delay(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

// We import interact for dragging/resizing
const { default: interact } = await import('https://esm.sh/interactjs@1.10.19')


function getImageOptions() {
  const o = plot_obj.config.toImageButtonOptions ?? {};
  return {
    format: o.format ?? "png",
    width: o.width ?? original_width,
    height: o.height ?? original_height,
    scale: o.scale ?? 1,
    filename: o.filename ?? "newplot",
  };
}

const CLIPBOARD_HEADER =
  CONTAINER.querySelector(".plutoplotly-clipboard-header") ??
  CONTAINER.insertAdjacentElement(
    "afterbegin",
    html`<div class="plutoplotly-clipboard-header hidden">
      <span class="clipboard-span format"
        ><span class="label">Format:</span
        ><span class="clipboard-value format"></span
      ></span>
      <span class="clipboard-span width"
        ><span class="label">Width:</span
        ><span class="clipboard-value width"></span>px</span
      >
      <span class="clipboard-span height"
        ><span class="label">Height:</span
        ><span class="clipboard-value height"></span>px</span
      >
      <span class="clipboard-span scale"
        ><span class="label">Scale:</span
        ><span class="clipboard-value scale"></span
      ></span>
      <button class="clipboard-span set">Set</button>
      <button class="clipboard-span unset">Unset</button>
      <span class="clipboard-span filename"
        ><span class="label">Filename:</span
        ><span class="clipboard-value filename"></span
      ></span>
    </div>`
  );

function checkConfigSync(container) {
  const valid_classes = [
    "missing-config",
    "matching-config",
    "different-config",
  ];
  function setClass(cl) {
    for (const name of valid_classes) {
      container.classList.toggle(name, name == cl);
    }
  }
  // We use the custom getters we'll set up in the container
  const { ui_value, config_value, config_span, key } = container;
  if (config_value === undefined) {
    setClass("missing-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> is not present in the config.`;
  } else if (ui_value == config_value) {
    setClass("matching-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has the same value in the config and in the header.`;
  } else {
    setClass("different-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has a different value (<em>${config_value}</em>) in the config.`;
  }
  // Add info about setting and unsetting
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click on the label <em><b>once</b></em> to set the current UI value in the config.`
  );
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click <em><b>twice</b></em> to remove this key from the config.`
  );
}

const valid_formats = ["png", "svg", "webp", "jpeg", "full-json"];
function initializeUIValueSpan(span, key, value) {
  const container = span.closest(".clipboard-span");
  span.contentEditable = key === "format" ? "false" : "true";
  let parse = (x) => x;
  let update = (x) => (span.textContent = x);
  if (key === "width" || key === "height") {
    parse = (x) => Math.round(parseFloat(x));
  } else if (key === "scale") {
    parse = parseFloat;
  } else if (key === "format") {
    // We remove contentEditable
    span.contentEditable = "false";
    // Here we first add the subspans for each option
    const opts_div = span.appendChild(html`<div class="format-options"></div>`);
    for (const fmt of valid_formats) {
      const opt = opts_div.appendChild(
        html`<span class="format-option ${fmt}">${fmt}</span>`
      );
      opt.onclick = (e) => {
        span.value = opt.textContent;
      };
    }
    parse = (x) => {
      return valid_formats.includes(x) ? x : localValue;
    };
    update = (x) => {
      for (const opt of opts_div.children) {
        opt.classList.toggle("selected", opt.textContent === x);
      }
    };
  } else {
    // We only have filename here
  }
  let localValue;
  Object.defineProperty(span, "value", {
    get: () => {
      return localValue;
    },
    set: (val) => {
      if (val !== "") {
        localValue = parse(val);
      }
      update(localValue);
      checkConfigSync(container);
    },
  });
  // We also assign a listener so that the editable is blurred when enter is pressed
  span.onkeydown = (e) => {
    if (e.keyCode === 13) {
      e.preventDefault();
      span.blur();
    }
  };
  span.value = value;
}

function initializeConfigValueSpan(span, key) {
  // Here we mostly want to define the setter and getter
  const container = span.closest(".clipboard-span");
  Object.defineProperty(span, "value", {
    get: () => {
      return plot_obj.config.toImageButtonOptions[key];
    },
    set: (val) => {
      // if undefined is passed, we remove the entry from the options
      if (val === undefined) {
        delete plot_obj.config.toImageButtonOptions[key];
      } else {
        plot_obj.config.toImageButtonOptions[key] = val;
      }
      checkConfigSync(container);
    },
  });
}

const config_spans = {};
for (const [key, value] of Object.entries(getImageOptions())) {
  const container = CLIPBOARD_HEADER.querySelector(`.clipboard-span.${key}`);
  const label = container.querySelector(".label");
  // We give the label a function that on single click will set the current value and with double click will unset it
  label.onclick = DualClick(
    () => {
      container.config_value = container.ui_value;
    },
    (e) => {
      console.log("e", e);
      e.preventDefault();
      container.config_value = undefined;
    }
  );
  const ui_value_span = container.querySelector(".clipboard-value");
  const config_value_span =
    container.querySelector(".config-value") ??
    label.insertAdjacentElement(
      "afterbegin",
      html`<span class="config-value"></span>`
    );
  // Assing the two spans as properties of the containing span
  container.ui_span = ui_value_span;
  container.config_span = config_value_span;
  container.key = key;
  config_spans[key] = container;
  if (firstRun) {
    plot_obj.config.toImageButtonOptions =
      plot_obj.config.toImageButtonOptions ?? {};
    // We do the initialization of the value span
    initializeUIValueSpan(ui_value_span, key, value);
    // Then we initialize the config value
    initializeConfigValueSpan(config_value_span, key);
    // We put some convenience getters/setters
    // ui_value forward
    Object.defineProperty(container, "ui_value", {
      get: () => ui_value_span.value,
      set: (val) => {
        ui_value_span.value = val;
      },
    });
    // config_value forward
    Object.defineProperty(container, "config_value", {
      get: () => config_value_span.value,
      set: (val) => {
        config_value_span.value = val;
      },
    });
  }
}

// These objects will contain the default value

// This code updates the image options in the PLOT config with the provided ones
function setImageOptions(o) {
  for (const [key, container] of Object.entries(config_spans)) {
    container.config_value = o[key];
  }
}
function unsetImageOptions() {
  setImageOptions({});
}

const set_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.set");
const unset_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.unset");
if (firstRun) {
  set_button.onclick = (e) => {
    for (const container of Object.values(config_spans)) {
      container.config_value = container.ui_value;
    }
  };
  unset_button.onclick = unsetImageOptions;
}

// We add a function to check if the clipboard is popped out
CONTAINER.isPoppedOut = () => {
  return CONTAINER.classList.contains("popped-out");
};

CLIPBOARD_HEADER.onmousedown = function (event) {
  if (event.target.matches("span.clipboard-value")) {
    console.log("We don't move!");
    return;
  }
  const start = {
    left: parseFloat(CONTAINER.style.left),
    top: parseFloat(CONTAINER.style.top),
    X: event.pageX,
    Y: event.pageY,
  };
  function moveAt(event, start) {
    const top = event.pageY - start.Y + start.top + "px";
    const left = event.pageX - start.X + start.left + "px";
    CLIPBOARD_HEADER.style.left = left;
    CONTAINER.style.left = left;
    CONTAINER.style.top = top;
  }

  // move our absolutely positioned ball under the pointer
  moveAt(event, start);
  function onMouseMove(event) {
    moveAt(event, start);
  }

  // We use this to remove the mousemove when clicking outside of the container
  const controller = new AbortController();

  // move the container on mousemove
  document.addEventListener("mousemove", onMouseMove, {
    signal: controller.signal,
  });
  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        cleanUp();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );

  function cleanUp() {
    console.log("cleaning up the plot move listener");
    controller.abort();
    CLIPBOARD_HEADER.onmouseup = null;
  }

  // (3) drop the ball, remove unneeded handlers
  CLIPBOARD_HEADER.onmouseup = cleanUp;
};

function sendToClipboard(blob) {
  if (!navigator.clipboard) {
    alert(
      "The Clipboard API does not seem to be available, make sure the Pluto notebook is being used from either localhost or an https source."
    );
  }
  navigator.clipboard
    .write([
      new ClipboardItem({
        // The key is determined dynamically based on the blob's type.
        [blob.type]: blob,
      }),
    ])
    .then(
      function () {
        console.log("Async: Copying to clipboard was successful!");
      },
      function (err) {
        console.error("Async: Could not copy text: ", err);
      }
    );
}

function copyImageToClipboard() {
  // We extract the image options from the provided parameters (if they exist)
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key. We also ignore format because the clipboard only supports png.
    if (val === undefined || key === "format") {
      continue;
    }
    config[key] = val;
  }
  Plotly.toImage(PLOT, config).then(function (dataUrl) {
    fetch(dataUrl)
      .then((res) => res.blob())
      .then((blob) => {
        const paste_receiver = document.querySelector('paste-receiver.plutoplotly')
        if (paste_receiver) {
          paste_receiver.attachImage(dataUrl, CONTAINER)
        }
        sendToClipboard(blob)
      });
  });
}

function saveImageToFile() {
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key.
    if (val === undefined) {
      continue;
    }
    config[key] = val;
  }
  Plotly.downloadImage(PLOT, config);
}

let container_rect = { width: 0, height: 0, top: 0, left: 0 };
function unpop_container(cl) {
  CONTAINER.classList.toggle("popped-out", false);
  CONTAINER.classList.toggle(cl, false);
  // We fix the height back to the value it had before popout, also setting the flag to signal that upon first resize we remove the fixed inline-style
  CONTAINER.style.height = container_rect.height + "px";
  remove_container_size = true;
  // We set the other fixed inline-styles to null
  CONTAINER.style.width = "";
  CONTAINER.style.top = "";
  CONTAINER.style.left = "";
  // We also remove the CLIPBOARD_HEADER
  CLIPBOARD_HEADER.style.width = "";
  CLIPBOARD_HEADER.style.left = "";
  // Finally we remove the hidden class to the header
  CLIPBOARD_HEADER.classList.toggle("hidden", true);
  return;
}
function popout_container(opts) {
  const cl = opts?.cl;
  const target_container_size = opts?.target_container_size ?? {};
  const target_plot_size = opts?.target_plot_size ?? {};
  if (CONTAINER.isPoppedOut()) {
    return unpop_container(cl);
  }
  CONTAINER.classList.toggle(cl, cl === undefined ? false : true);
  // We extract the current size of the container, save them and fix them
  const { width, height, top, left } = CONTAINER.getBoundingClientRect();
  container_rect = { width, height, top, left };
  // We save the current plot size before we pop as it will fill the screen
  const current_plot_size = {
    width: PLOT._fullLayout.width,
    height: PLOT._fullLayout.height,
  };
  // We have to save the pad data before popping so we can resize precisely
  const pad = {};
  pad.unpopped = getSizeData().container_pad;
  CONTAINER.classList.toggle("popped-out", true);
  pad.popped = getSizeData().container_pad;
  // We do top and left based on the current rect
  for (const key of ["top", "left"]) {
    const start_val = target_container_size[key] ?? container_rect[key];
    let offset = 0;
    for (const kind of ["padding", "border"]) {
      offset += pad.popped[kind][key] - pad.unpopped[kind][key];
    }
    CONTAINER.style[key] = start_val - offset + "px";
    if (key === "left") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  // We compute the width and height depending on eventual config data
  const csz = computeContainerSize({
    width:
      target_plot_size.width ??
      config_spans.width.config_value ??
      current_plot_size.width,
    height:
      target_plot_size.height ??
      config_spans.height.config_value ??
      current_plot_size.height,
  });
  for (const key of ["width", "height"]) {
    const val = target_container_size[key] ?? csz[key];
    CONTAINER.style[key] = val + "px";
    if (key === "width") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  CLIPBOARD_HEADER.classList.toggle("hidden", false);
  const controller = new AbortController();

  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        unpop_container();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );
}

CONTAINER.popOut = popout_container;

function DualClick(single_func, dbl_func) {
  let nclicks = 0;
  return function (...args) {
    nclicks += 1;
    if (nclicks > 1) {
      dbl_func(...args);
      nclicks = 0;
    } else {
      delay(300).then(() => {
        if (nclicks == 1) {
          single_func(...args);
        }
        nclicks = 0;
      });
    }
  };
}

// We remove the default download image button
plot_obj.config.modeBarButtonsToRemove = _.union(
  plot_obj.config.modeBarButtonsToRemove,
  ["toImage"]
);
// We add the custom button to the modebar
plot_obj.config.modeBarButtonsToAdd = _.union(
  plot_obj.config.modeBarButtonsToAdd,
  [
    {
      name: "Copy PNG to Clipboard",
      icon: {
        height: 520,
        width: 520,
        path: "M280 64h40c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128C0 92.7 28.7 64 64 64h40 9.6C121 27.5 153.3 0 192 0s71 27.5 78.4 64H280zM64 112c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16H320c8.8 0 16-7.2 16-16V128c0-8.8-7.2-16-16-16H304v24c0 13.3-10.7 24-24 24H192 104c-13.3 0-24-10.7-24-24V112H64zm128-8a24 24 0 1 0 0-48 24 24 0 1 0 0 48z",
      },
      direction: "up",
      click: DualClick(copyImageToClipboard, () => {
        popout_container();
      }),
    },
    {
      name: "Download Image",
      icon: Plotly.Icons.camera,
      direction: "up",
      click: DualClick(saveImageToFile, () => {
        popout_container({ cl: "filesave" });
      }),
    },
  ]
);

function getOffsetData(el) {
  let cs = window.getComputedStyle(el, null);
  const odata = {
    padding: {
      left: parseFloat(cs.paddingLeft),
      right: parseFloat(cs.paddingRight),
      top: parseFloat(cs.paddingTop),
      bottom: parseFloat(cs.paddingBottom),
      width: parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight),
      height: parseFloat(cs.paddingTop) + parseFloat(cs.paddingBottom),
    },
    border: {
      left: parseFloat(cs.borderLeftWidth),
      right: parseFloat(cs.borderRightWidth),
      top: parseFloat(cs.borderTopWidth),
      bottom: parseFloat(cs.borderBottomWidth),
      width: parseFloat(cs.borderLeftWidth) + parseFloat(cs.borderRightWidth),
      height: parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth),
    }
  };
  if (el === PLOT) {
    // For the PLOT we also want to take into account the offset
    odata.offset = {
      top: PLOT.offsetParent == CONTAINER ? PLOT.offsetTop : 0,
      left: PLOT.offsetParent == CONTAINER ? PLOT.offsetLeft : 0,
    }
  }
  return odata;
}
function getSizeData() {
  const data = {
    plot_pad: getOffsetData(PLOT),
    plot_rect: PLOT.getBoundingClientRect(),
    container_pad: getOffsetData(CONTAINER),
    container_rect: CONTAINER.getBoundingClientRect(),
  };
  return data;
}
function computeContainerSize({ width, height }, sizeData = getSizeData()) {
  const computed_size = computePlotSize(sizeData);
  const offsets = computed_size.offsets;

  const plot_data = {
    width: width ?? computed_size.width,
    height: height ?? computed_size.height,
  };

  return {
    width: (width ?? computed_size.width) + offsets.width,
    height: (height ?? computed_size.height) + offsets.height,
    noChange: width == computed_size.width && height == computed_size.height,
  }
}

// This function will change the container size so that the resulting plot will be matching the provided specs
function changeContainerSize({ width, height }, sizeData = getSizeData()) {
  if (!CONTAINER.isPoppedOut()) {
    console.log("Tried to change container size when not popped, ignoring");
    return;
  }

  const csz = computeContainerSize({ width, height }, sizeData);

  if (csz.noChange) {
    console.log("Size is the same as current, ignoring");
    return
  }
  // We are now going to set he width and height of the container
  for (const key of ["width", "height"]) {
    CONTAINER.style[key] = csz[key] + "px";
  }
}
// We now create the function that will update the plot based on the values specified
function updateFromHeader() {
  const header_data = {
    height: config_spans.height.ui_value,
    width: config_spans.width.ui_value,
  };
  changeContainerSize(header_data);
}
// We assign this function to the onblur event of width and height
if (firstRun) {
  for (const container of Object.values(config_spans)) {
    container.ui_span.onblur = (e) => {
      container.ui_value = container.ui_span.textContent;
      updateFromHeader();
    };
  }
}
// This function computes the plot size to use for relayout as a function of the container size
function computePlotSize(data = getSizeData()) {
  // Remove Padding
  const { container_pad, plot_pad, container_rect } = data;
  const offsets = {
    width:
      plot_pad.padding.width +
      plot_pad.border.width +
      plot_pad.offset.left +
      container_pad.padding.width +
      container_pad.border.width,
    height:
      plot_pad.padding.height +
      plot_pad.border.height +
      plot_pad.offset.top +
      container_pad.padding.height +
      container_pad.border.height,
  };
  const sz = {
    width: Math.round(container_rect.width - offsets.width),
    height: Math.round(container_rect.height - offsets.height),
    offsets,
  };
  return sz;
}

// Create the resizeObserver to make the plot even more responsive! :magic:
const resizeObserver = new ResizeObserver((entries) => {
  const sizeData = getSizeData();
  const {container_rect, container_pad} = sizeData;
  let plot_size = computePlotSize(sizeData);
  // We save the height in the PLOT object
  PLOT.container_height = container_rect.height;
  // We deal with some stuff if the container is poppped
  CLIPBOARD_HEADER.style.width = container_rect.width + "px";
  CLIPBOARD_HEADER.style.left = container_rect.left + "px";
  config_spans.height.ui_value = plot_size.height;
  config_spans.width.ui_value = plot_size.width;
  /* 
		The addition of the invalid argument `plutoresize` seems to fix the problem with calling `relayout` simply with `{autosize: true}` as update breaking mouse relayout events tracking. 
		See https://github.com/plotly/plotly.js/issues/6156 for details
		*/
  let config = {
    // If this is popped out, we ignore the original width/height
    width: (CONTAINER.isPoppedOut() ? undefined : original_width) ?? plot_size.width,
    height: (CONTAINER.isPoppedOut() ? undefined : original_height) ?? plot_size.height,
    plutoresize: true,
  };
  Plotly.relayout(PLOT, config).then(() => {
    if (remove_container_size && !CONTAINER.isPoppedOut()) {
      // This is needed to avoid the first resize upon plot creation to already be without a fixed height
      CONTAINER.style.height = "";
      CONTAINER.style.width = "";
      remove_container_size = false;
    }
  });
});

resizeObserver.observe(CONTAINER);


Plotly.react(PLOT, plot_obj).then(() => {
	// Assign the Plotly event listeners
	for (const [key, listener_vec] of Object.entries(plotly_listeners)) {
		for (const listener of listener_vec) {
			PLOT.on(key, listener)
		}
	}
	// Assign the JS event listeners
	for (const [key, listener_vec] of Object.entries(js_listeners)) {
		for (const listener of listener_vec) {
			PLOT.addEventListener(key, listener, {
				signal: controller.signal
			})
		}
	}
}
)


invalidation.then(() => {
	// Remove all plotly listeners
	PLOT.removeAllListeners()
	// Remove all JS listeners
	controller.abort()
	// Remove the resizeObserver
	resizeObserver.disconnect()
})



		return CONTAINER
	</script>
</td><td align="center">	<script id='plot_4'>
		// We start by putting all the variable interpolation here at the beginning
		// We have to convert all typedarrays in the layout to normal arrays. See Issue #25
		// We use lodash for this for compactness
		function removeTypedArray(o) {
			return _.isTypedArray(o) ? Array.from(o) :
			_.isPlainObject(o) ? _.mapValues(o, removeTypedArray) : 
			o
		}

		// Publish the plot object to JS
		let plot_obj = _.update(/* See the documentation for AbstractPlutoDingetjes.Display.published_to_js */ getPublishedObject("c6e0de0c-3901-11f0-234e-bd09c571f662/369509f17cc5b5a"), "layout", removeTypedArray)
		// Get the plotly listeners
		const plotly_listeners = {}
		// Get the JS listeners
		const js_listeners = {}
		// Deal with eventual custom classes
		let custom_classlist = []


		// Load the plotly library
		let Plotly = undefined
		try {
			let _mod = await import("./plotlyjs/plotlyjs-2.26.2.min.js")
			Plotly = _mod.default
		} catch (e) {
			console.log("Local load failed, trying with the web esm.sh version")
			let _mod = await import("https://esm.sh/plotly.js-dist-min@2.26.2/es2022/plotly.js-dist-min.mjs")
			Plotly = _mod.default
		}

		// Check if we have to force local mathjax font cache
		if (false && window?.MathJax?.config?.svg?.fontCache === 'global') {
			window.MathJax.config.svg.fontCache = 'local'
		}

		// Flag to check if this cell was  manually ran or reactively ran
const firstRun = this ? false : true
const CONTAINER = this ?? html`<div class='plutoplotly-container'>`
const PLOT = CONTAINER.querySelector('.js-plotly-plot') ?? CONTAINER.appendChild(html`<div>`)
const parent = CONTAINER.parentElement
// We use a controller to remove event listeners upon invalidation
const controller = new AbortController()
// We have to add this to keep supporting @bind with the old API using PLOT
PLOT.addEventListener('input', (e) => {
	CONTAINER.value = PLOT.value
	if (e.bubbles) {
		return
	}
	CONTAINER.dispatchEvent(new CustomEvent('input'))
}, { signal: controller.signal })

	// This create the style subdiv on first run
	firstRun && CONTAINER.appendChild(html`
	<style>
	.plutoplotly-container {
		width: 100%;
		height: 100%;
		min-height: 0;
		min-width: 0;
	}
	.plutoplotly-container .js-plotly-plot .plotly div {
		margin: 0 auto; // This centers the plot
	}
	.plutoplotly-container.popped-out {
		overflow: auto;
		z-index: 1000;
		position: fixed;
		resize: both;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		border-top-left-radius: 0px;
		border-top-right-radius: 0px;
	}
	.plutoplotly-clipboard-header {
		display: flex;
		flex-flow: row wrap;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-top-left-radius: 12px;
		border-top-right-radius: 12px;
		position: fixed;
		z-index: 1001;
		cursor: move;
		transform: translate(0px, -100%);
		padding: 5px;
	}
	.plutoplotly-clipboard-header span {
		display: inline-block;
		flex: 1
	}
	.plutoplotly-clipboard-header.hidden {
		display: none;
	}
	.clipboard-span {
		position: relative;
	}
	.clipboard-value {
		padding-right: 5px;
		padding-left: 2px;
		cursor: text;
	}
	.clipboard-span.format {
		display: none;
	}
	.clipboard-span.filename {
		flex: 0 0 100%;
		text-align: center;
		border-top: 3px solid var(--kbd-border-color);
		margin-top: 5px;
		display: none;
	}
	.plutoplotly-container.filesave .clipboard-span.filename {
		display: inline-block;
	}
	.clipboard-value.filename {
		margin-left: 3px;
		text-align: left;
		min-width: min(60%, min-content);
	}
	.plutoplotly-container.filesave .clipboard-span.format {
		display: inline-flex;
	}
	.clipboard-span.format .label {
		flex: 0 0 0;
	}
	.clipboard-value.format {
		position: relative;
		flex: 1 0 auto;
		min-width: 30px;
		margin-right: 10px;
	}
	div.format-options {
		display: inline-flex;
		flex-flow: column;
		position: absolute;
		background: var(--main-bg-color);
		border-radius: 12px;
		padding-left: 3px;
		z-index: 2000;
	}
	div.format-options:hover {
		cursor: pointer;
		border: 3px solid var(--kbd-border-color);
		padding: 3px;
		transform: translate(-3px, -6px);
	}
	div.format-options .format-option {
		display: none;
	}
	div.format-options:hover .format-option {
		display: inline-block;
	}
	.format-option:not(.selected) {
		margin-top: 3px;
	}
	div.format-options .format-option.selected {
		order: -1;
		display: inline-block;
	}
	.format-option:hover {
		background-color: var(--kbd-border-color);
	}
	span.config-value {
		font-weight: normal;
		color: var(--pluto-output-color);
		display: none;
		position: absolute;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		transform: translate(0px, calc(-100% - 10px));
		padding: 5px;
	}
	.label {
		user-select: none;
	}
	.label:hover span.config-value {
		display: inline-block;
		min-width: 150px;
	}
	.clipboard-span.matching-config .label {
		color: var(--cm-macro-color);
		font-weight: bold;
	}
	.clipboard-span.different-config .label {
		color: var(--cm-tag-color);
		font-weight: bold;
	}
</style>
`)

let original_height = plot_obj.layout.height
let original_width = plot_obj.layout.width
// For the height we have to also put a fixed value in case the plot is put on a non-fixed-size container (like the default wrapper)
// We define a variable to check whether we still have to remove the fixed height
let remove_container_size = firstRun
let container_height = original_height ?? PLOT.container_height ?? 400
CONTAINER.style.height = container_height + 'px'

// We create a Promise version of setTimeout
function delay(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

// We import interact for dragging/resizing
const { default: interact } = await import('https://esm.sh/interactjs@1.10.19')


function getImageOptions() {
  const o = plot_obj.config.toImageButtonOptions ?? {};
  return {
    format: o.format ?? "png",
    width: o.width ?? original_width,
    height: o.height ?? original_height,
    scale: o.scale ?? 1,
    filename: o.filename ?? "newplot",
  };
}

const CLIPBOARD_HEADER =
  CONTAINER.querySelector(".plutoplotly-clipboard-header") ??
  CONTAINER.insertAdjacentElement(
    "afterbegin",
    html`<div class="plutoplotly-clipboard-header hidden">
      <span class="clipboard-span format"
        ><span class="label">Format:</span
        ><span class="clipboard-value format"></span
      ></span>
      <span class="clipboard-span width"
        ><span class="label">Width:</span
        ><span class="clipboard-value width"></span>px</span
      >
      <span class="clipboard-span height"
        ><span class="label">Height:</span
        ><span class="clipboard-value height"></span>px</span
      >
      <span class="clipboard-span scale"
        ><span class="label">Scale:</span
        ><span class="clipboard-value scale"></span
      ></span>
      <button class="clipboard-span set">Set</button>
      <button class="clipboard-span unset">Unset</button>
      <span class="clipboard-span filename"
        ><span class="label">Filename:</span
        ><span class="clipboard-value filename"></span
      ></span>
    </div>`
  );

function checkConfigSync(container) {
  const valid_classes = [
    "missing-config",
    "matching-config",
    "different-config",
  ];
  function setClass(cl) {
    for (const name of valid_classes) {
      container.classList.toggle(name, name == cl);
    }
  }
  // We use the custom getters we'll set up in the container
  const { ui_value, config_value, config_span, key } = container;
  if (config_value === undefined) {
    setClass("missing-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> is not present in the config.`;
  } else if (ui_value == config_value) {
    setClass("matching-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has the same value in the config and in the header.`;
  } else {
    setClass("different-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has a different value (<em>${config_value}</em>) in the config.`;
  }
  // Add info about setting and unsetting
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click on the label <em><b>once</b></em> to set the current UI value in the config.`
  );
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click <em><b>twice</b></em> to remove this key from the config.`
  );
}

const valid_formats = ["png", "svg", "webp", "jpeg", "full-json"];
function initializeUIValueSpan(span, key, value) {
  const container = span.closest(".clipboard-span");
  span.contentEditable = key === "format" ? "false" : "true";
  let parse = (x) => x;
  let update = (x) => (span.textContent = x);
  if (key === "width" || key === "height") {
    parse = (x) => Math.round(parseFloat(x));
  } else if (key === "scale") {
    parse = parseFloat;
  } else if (key === "format") {
    // We remove contentEditable
    span.contentEditable = "false";
    // Here we first add the subspans for each option
    const opts_div = span.appendChild(html`<div class="format-options"></div>`);
    for (const fmt of valid_formats) {
      const opt = opts_div.appendChild(
        html`<span class="format-option ${fmt}">${fmt}</span>`
      );
      opt.onclick = (e) => {
        span.value = opt.textContent;
      };
    }
    parse = (x) => {
      return valid_formats.includes(x) ? x : localValue;
    };
    update = (x) => {
      for (const opt of opts_div.children) {
        opt.classList.toggle("selected", opt.textContent === x);
      }
    };
  } else {
    // We only have filename here
  }
  let localValue;
  Object.defineProperty(span, "value", {
    get: () => {
      return localValue;
    },
    set: (val) => {
      if (val !== "") {
        localValue = parse(val);
      }
      update(localValue);
      checkConfigSync(container);
    },
  });
  // We also assign a listener so that the editable is blurred when enter is pressed
  span.onkeydown = (e) => {
    if (e.keyCode === 13) {
      e.preventDefault();
      span.blur();
    }
  };
  span.value = value;
}

function initializeConfigValueSpan(span, key) {
  // Here we mostly want to define the setter and getter
  const container = span.closest(".clipboard-span");
  Object.defineProperty(span, "value", {
    get: () => {
      return plot_obj.config.toImageButtonOptions[key];
    },
    set: (val) => {
      // if undefined is passed, we remove the entry from the options
      if (val === undefined) {
        delete plot_obj.config.toImageButtonOptions[key];
      } else {
        plot_obj.config.toImageButtonOptions[key] = val;
      }
      checkConfigSync(container);
    },
  });
}

const config_spans = {};
for (const [key, value] of Object.entries(getImageOptions())) {
  const container = CLIPBOARD_HEADER.querySelector(`.clipboard-span.${key}`);
  const label = container.querySelector(".label");
  // We give the label a function that on single click will set the current value and with double click will unset it
  label.onclick = DualClick(
    () => {
      container.config_value = container.ui_value;
    },
    (e) => {
      console.log("e", e);
      e.preventDefault();
      container.config_value = undefined;
    }
  );
  const ui_value_span = container.querySelector(".clipboard-value");
  const config_value_span =
    container.querySelector(".config-value") ??
    label.insertAdjacentElement(
      "afterbegin",
      html`<span class="config-value"></span>`
    );
  // Assing the two spans as properties of the containing span
  container.ui_span = ui_value_span;
  container.config_span = config_value_span;
  container.key = key;
  config_spans[key] = container;
  if (firstRun) {
    plot_obj.config.toImageButtonOptions =
      plot_obj.config.toImageButtonOptions ?? {};
    // We do the initialization of the value span
    initializeUIValueSpan(ui_value_span, key, value);
    // Then we initialize the config value
    initializeConfigValueSpan(config_value_span, key);
    // We put some convenience getters/setters
    // ui_value forward
    Object.defineProperty(container, "ui_value", {
      get: () => ui_value_span.value,
      set: (val) => {
        ui_value_span.value = val;
      },
    });
    // config_value forward
    Object.defineProperty(container, "config_value", {
      get: () => config_value_span.value,
      set: (val) => {
        config_value_span.value = val;
      },
    });
  }
}

// These objects will contain the default value

// This code updates the image options in the PLOT config with the provided ones
function setImageOptions(o) {
  for (const [key, container] of Object.entries(config_spans)) {
    container.config_value = o[key];
  }
}
function unsetImageOptions() {
  setImageOptions({});
}

const set_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.set");
const unset_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.unset");
if (firstRun) {
  set_button.onclick = (e) => {
    for (const container of Object.values(config_spans)) {
      container.config_value = container.ui_value;
    }
  };
  unset_button.onclick = unsetImageOptions;
}

// We add a function to check if the clipboard is popped out
CONTAINER.isPoppedOut = () => {
  return CONTAINER.classList.contains("popped-out");
};

CLIPBOARD_HEADER.onmousedown = function (event) {
  if (event.target.matches("span.clipboard-value")) {
    console.log("We don't move!");
    return;
  }
  const start = {
    left: parseFloat(CONTAINER.style.left),
    top: parseFloat(CONTAINER.style.top),
    X: event.pageX,
    Y: event.pageY,
  };
  function moveAt(event, start) {
    const top = event.pageY - start.Y + start.top + "px";
    const left = event.pageX - start.X + start.left + "px";
    CLIPBOARD_HEADER.style.left = left;
    CONTAINER.style.left = left;
    CONTAINER.style.top = top;
  }

  // move our absolutely positioned ball under the pointer
  moveAt(event, start);
  function onMouseMove(event) {
    moveAt(event, start);
  }

  // We use this to remove the mousemove when clicking outside of the container
  const controller = new AbortController();

  // move the container on mousemove
  document.addEventListener("mousemove", onMouseMove, {
    signal: controller.signal,
  });
  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        cleanUp();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );

  function cleanUp() {
    console.log("cleaning up the plot move listener");
    controller.abort();
    CLIPBOARD_HEADER.onmouseup = null;
  }

  // (3) drop the ball, remove unneeded handlers
  CLIPBOARD_HEADER.onmouseup = cleanUp;
};

function sendToClipboard(blob) {
  if (!navigator.clipboard) {
    alert(
      "The Clipboard API does not seem to be available, make sure the Pluto notebook is being used from either localhost or an https source."
    );
  }
  navigator.clipboard
    .write([
      new ClipboardItem({
        // The key is determined dynamically based on the blob's type.
        [blob.type]: blob,
      }),
    ])
    .then(
      function () {
        console.log("Async: Copying to clipboard was successful!");
      },
      function (err) {
        console.error("Async: Could not copy text: ", err);
      }
    );
}

function copyImageToClipboard() {
  // We extract the image options from the provided parameters (if they exist)
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key. We also ignore format because the clipboard only supports png.
    if (val === undefined || key === "format") {
      continue;
    }
    config[key] = val;
  }
  Plotly.toImage(PLOT, config).then(function (dataUrl) {
    fetch(dataUrl)
      .then((res) => res.blob())
      .then((blob) => {
        const paste_receiver = document.querySelector('paste-receiver.plutoplotly')
        if (paste_receiver) {
          paste_receiver.attachImage(dataUrl, CONTAINER)
        }
        sendToClipboard(blob)
      });
  });
}

function saveImageToFile() {
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key.
    if (val === undefined) {
      continue;
    }
    config[key] = val;
  }
  Plotly.downloadImage(PLOT, config);
}

let container_rect = { width: 0, height: 0, top: 0, left: 0 };
function unpop_container(cl) {
  CONTAINER.classList.toggle("popped-out", false);
  CONTAINER.classList.toggle(cl, false);
  // We fix the height back to the value it had before popout, also setting the flag to signal that upon first resize we remove the fixed inline-style
  CONTAINER.style.height = container_rect.height + "px";
  remove_container_size = true;
  // We set the other fixed inline-styles to null
  CONTAINER.style.width = "";
  CONTAINER.style.top = "";
  CONTAINER.style.left = "";
  // We also remove the CLIPBOARD_HEADER
  CLIPBOARD_HEADER.style.width = "";
  CLIPBOARD_HEADER.style.left = "";
  // Finally we remove the hidden class to the header
  CLIPBOARD_HEADER.classList.toggle("hidden", true);
  return;
}
function popout_container(opts) {
  const cl = opts?.cl;
  const target_container_size = opts?.target_container_size ?? {};
  const target_plot_size = opts?.target_plot_size ?? {};
  if (CONTAINER.isPoppedOut()) {
    return unpop_container(cl);
  }
  CONTAINER.classList.toggle(cl, cl === undefined ? false : true);
  // We extract the current size of the container, save them and fix them
  const { width, height, top, left } = CONTAINER.getBoundingClientRect();
  container_rect = { width, height, top, left };
  // We save the current plot size before we pop as it will fill the screen
  const current_plot_size = {
    width: PLOT._fullLayout.width,
    height: PLOT._fullLayout.height,
  };
  // We have to save the pad data before popping so we can resize precisely
  const pad = {};
  pad.unpopped = getSizeData().container_pad;
  CONTAINER.classList.toggle("popped-out", true);
  pad.popped = getSizeData().container_pad;
  // We do top and left based on the current rect
  for (const key of ["top", "left"]) {
    const start_val = target_container_size[key] ?? container_rect[key];
    let offset = 0;
    for (const kind of ["padding", "border"]) {
      offset += pad.popped[kind][key] - pad.unpopped[kind][key];
    }
    CONTAINER.style[key] = start_val - offset + "px";
    if (key === "left") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  // We compute the width and height depending on eventual config data
  const csz = computeContainerSize({
    width:
      target_plot_size.width ??
      config_spans.width.config_value ??
      current_plot_size.width,
    height:
      target_plot_size.height ??
      config_spans.height.config_value ??
      current_plot_size.height,
  });
  for (const key of ["width", "height"]) {
    const val = target_container_size[key] ?? csz[key];
    CONTAINER.style[key] = val + "px";
    if (key === "width") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  CLIPBOARD_HEADER.classList.toggle("hidden", false);
  const controller = new AbortController();

  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        unpop_container();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );
}

CONTAINER.popOut = popout_container;

function DualClick(single_func, dbl_func) {
  let nclicks = 0;
  return function (...args) {
    nclicks += 1;
    if (nclicks > 1) {
      dbl_func(...args);
      nclicks = 0;
    } else {
      delay(300).then(() => {
        if (nclicks == 1) {
          single_func(...args);
        }
        nclicks = 0;
      });
    }
  };
}

// We remove the default download image button
plot_obj.config.modeBarButtonsToRemove = _.union(
  plot_obj.config.modeBarButtonsToRemove,
  ["toImage"]
);
// We add the custom button to the modebar
plot_obj.config.modeBarButtonsToAdd = _.union(
  plot_obj.config.modeBarButtonsToAdd,
  [
    {
      name: "Copy PNG to Clipboard",
      icon: {
        height: 520,
        width: 520,
        path: "M280 64h40c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128C0 92.7 28.7 64 64 64h40 9.6C121 27.5 153.3 0 192 0s71 27.5 78.4 64H280zM64 112c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16H320c8.8 0 16-7.2 16-16V128c0-8.8-7.2-16-16-16H304v24c0 13.3-10.7 24-24 24H192 104c-13.3 0-24-10.7-24-24V112H64zm128-8a24 24 0 1 0 0-48 24 24 0 1 0 0 48z",
      },
      direction: "up",
      click: DualClick(copyImageToClipboard, () => {
        popout_container();
      }),
    },
    {
      name: "Download Image",
      icon: Plotly.Icons.camera,
      direction: "up",
      click: DualClick(saveImageToFile, () => {
        popout_container({ cl: "filesave" });
      }),
    },
  ]
);

function getOffsetData(el) {
  let cs = window.getComputedStyle(el, null);
  const odata = {
    padding: {
      left: parseFloat(cs.paddingLeft),
      right: parseFloat(cs.paddingRight),
      top: parseFloat(cs.paddingTop),
      bottom: parseFloat(cs.paddingBottom),
      width: parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight),
      height: parseFloat(cs.paddingTop) + parseFloat(cs.paddingBottom),
    },
    border: {
      left: parseFloat(cs.borderLeftWidth),
      right: parseFloat(cs.borderRightWidth),
      top: parseFloat(cs.borderTopWidth),
      bottom: parseFloat(cs.borderBottomWidth),
      width: parseFloat(cs.borderLeftWidth) + parseFloat(cs.borderRightWidth),
      height: parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth),
    }
  };
  if (el === PLOT) {
    // For the PLOT we also want to take into account the offset
    odata.offset = {
      top: PLOT.offsetParent == CONTAINER ? PLOT.offsetTop : 0,
      left: PLOT.offsetParent == CONTAINER ? PLOT.offsetLeft : 0,
    }
  }
  return odata;
}
function getSizeData() {
  const data = {
    plot_pad: getOffsetData(PLOT),
    plot_rect: PLOT.getBoundingClientRect(),
    container_pad: getOffsetData(CONTAINER),
    container_rect: CONTAINER.getBoundingClientRect(),
  };
  return data;
}
function computeContainerSize({ width, height }, sizeData = getSizeData()) {
  const computed_size = computePlotSize(sizeData);
  const offsets = computed_size.offsets;

  const plot_data = {
    width: width ?? computed_size.width,
    height: height ?? computed_size.height,
  };

  return {
    width: (width ?? computed_size.width) + offsets.width,
    height: (height ?? computed_size.height) + offsets.height,
    noChange: width == computed_size.width && height == computed_size.height,
  }
}

// This function will change the container size so that the resulting plot will be matching the provided specs
function changeContainerSize({ width, height }, sizeData = getSizeData()) {
  if (!CONTAINER.isPoppedOut()) {
    console.log("Tried to change container size when not popped, ignoring");
    return;
  }

  const csz = computeContainerSize({ width, height }, sizeData);

  if (csz.noChange) {
    console.log("Size is the same as current, ignoring");
    return
  }
  // We are now going to set he width and height of the container
  for (const key of ["width", "height"]) {
    CONTAINER.style[key] = csz[key] + "px";
  }
}
// We now create the function that will update the plot based on the values specified
function updateFromHeader() {
  const header_data = {
    height: config_spans.height.ui_value,
    width: config_spans.width.ui_value,
  };
  changeContainerSize(header_data);
}
// We assign this function to the onblur event of width and height
if (firstRun) {
  for (const container of Object.values(config_spans)) {
    container.ui_span.onblur = (e) => {
      container.ui_value = container.ui_span.textContent;
      updateFromHeader();
    };
  }
}
// This function computes the plot size to use for relayout as a function of the container size
function computePlotSize(data = getSizeData()) {
  // Remove Padding
  const { container_pad, plot_pad, container_rect } = data;
  const offsets = {
    width:
      plot_pad.padding.width +
      plot_pad.border.width +
      plot_pad.offset.left +
      container_pad.padding.width +
      container_pad.border.width,
    height:
      plot_pad.padding.height +
      plot_pad.border.height +
      plot_pad.offset.top +
      container_pad.padding.height +
      container_pad.border.height,
  };
  const sz = {
    width: Math.round(container_rect.width - offsets.width),
    height: Math.round(container_rect.height - offsets.height),
    offsets,
  };
  return sz;
}

// Create the resizeObserver to make the plot even more responsive! :magic:
const resizeObserver = new ResizeObserver((entries) => {
  const sizeData = getSizeData();
  const {container_rect, container_pad} = sizeData;
  let plot_size = computePlotSize(sizeData);
  // We save the height in the PLOT object
  PLOT.container_height = container_rect.height;
  // We deal with some stuff if the container is poppped
  CLIPBOARD_HEADER.style.width = container_rect.width + "px";
  CLIPBOARD_HEADER.style.left = container_rect.left + "px";
  config_spans.height.ui_value = plot_size.height;
  config_spans.width.ui_value = plot_size.width;
  /* 
		The addition of the invalid argument `plutoresize` seems to fix the problem with calling `relayout` simply with `{autosize: true}` as update breaking mouse relayout events tracking. 
		See https://github.com/plotly/plotly.js/issues/6156 for details
		*/
  let config = {
    // If this is popped out, we ignore the original width/height
    width: (CONTAINER.isPoppedOut() ? undefined : original_width) ?? plot_size.width,
    height: (CONTAINER.isPoppedOut() ? undefined : original_height) ?? plot_size.height,
    plutoresize: true,
  };
  Plotly.relayout(PLOT, config).then(() => {
    if (remove_container_size && !CONTAINER.isPoppedOut()) {
      // This is needed to avoid the first resize upon plot creation to already be without a fixed height
      CONTAINER.style.height = "";
      CONTAINER.style.width = "";
      remove_container_size = false;
    }
  });
});

resizeObserver.observe(CONTAINER);


Plotly.react(PLOT, plot_obj).then(() => {
	// Assign the Plotly event listeners
	for (const [key, listener_vec] of Object.entries(plotly_listeners)) {
		for (const listener of listener_vec) {
			PLOT.on(key, listener)
		}
	}
	// Assign the JS event listeners
	for (const [key, listener_vec] of Object.entries(js_listeners)) {
		for (const listener of listener_vec) {
			PLOT.addEventListener(key, listener, {
				signal: controller.signal
			})
		}
	}
}
)


invalidation.then(() => {
	// Remove all plotly listeners
	PLOT.removeAllListeners()
	// Remove all JS listeners
	controller.abort()
	// Remove the resizeObserver
	resizeObserver.disconnect()
})



		return CONTAINER
	</script>
</td></tr></table>
</div>mimetext/htmlrootassigneelast_run_timestampA)S缰persist_js_state·has_pluto_hook_features§cell_id$b040f245-b2d6-4ec6-aa7f-511c54aabd0ddepends_on_disabled_cells§runtime ٵpublished_object_keys5c6e0de0c-3901-11f0-234e-bd09c571f662/cfb9dac3af175b345c6e0de0c-3901-11f0-234e-bd09c571f662/4632010f9ca3f26e4c6e0de0c-3901-11f0-234e-bd09c571f662/369509f17cc5b5a5c6e0de0c-3901-11f0-234e-bd09c571f662/70ef6091712c9d41depends_on_skipped_cells§errored$7cdf4142-82fe-4aa6-9665-84a1eef5d038queued¤logsrunning¦outputbody[<bond def="race_1_2" unique_id="IuPL3p1uhwlR"><input type="button" value="Run race"></bond>mimetext/htmlrootassigneelast_run_timestampA2|Cpersist_js_state·has_pluto_hook_features§cell_id$7cdf4142-82fe-4aa6-9665-84a1eef5d038depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$3d10f89f-876e-4d25-b8d6-34ce5c99eb8cqueued¤logsrunning¦outputbodyڳ	<div style = "display: flex;">
	<div>
Race finished in 79 steps
<div style="background-color: white; color: black;">
	<div style="display:flex; align-items: flex-start">
	<div class = "track">
		<div class = "start" vx = "0" vy = "0" dvx = "0" dvy = "0" style="grid-column-start: 4; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "-1" dvy = "0" style="grid-column-start: 8; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "1" dvy = "1" style="grid-column-start: 9; grid-row-start: 1;"></div><div class = "start" vx = "1" vy = "0" dvx = "-1" dvy = "0" style="grid-column-start: 6; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "-1" dvy = "-1" style="grid-column-start: 7; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "1" dvy = "-1" style="grid-column-start: 5; grid-row-start: 1;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 11;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "1" style="grid-column-start: 7; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 24;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "-1" style="grid-column-start: 7; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 32;"></div><div class = "" vx = "0" vy = "4" dvx = "-1" dvy = "0" style="grid-column-start: 7; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 25;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "1" style="grid-column-start: 5; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 26;"></div><div class = "" vx = "1" vy = "3" dvx = "-1" dvy = "1" style="grid-column-start: 6; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 23;"></div><div class = "" vx = "3" vy = "1" dvx = "1" dvy = "-1" style="grid-column-start: 14; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 31;"></div><div class = "" vx = "1" vy = "3" dvx = "1" dvy = "0" style="grid-column-start: 7; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 13;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "-1" style="grid-column-start: 7; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 12;"></div><div class = "" vx = "1" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 9; grid-row-start: 27;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "0" style="grid-column-start: 8; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 32;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "-1" style="grid-column-start: 6; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 8;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "1" style="grid-column-start: 7; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 7;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "1" style="grid-column-start: 9; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 32;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "-1" style="grid-column-start: 7; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 28;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "1" style="grid-column-start: 5; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 28;"></div><div class = "" vx = "1" vy = "1" dvx = "-1" dvy = "0" style="grid-column-start: 9; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 6;"></div><div class = "" vx = "2" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 11; grid-row-start: 28;"></div><div class = "" vx = "1" vy = "1" dvx = "0" dvy = "0" style="grid-column-start: 8; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 14;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "0" style="grid-column-start: 5; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 16;"></div><div class = "" vx = "2" vy = "1" dvx = "0" dvy = "0" style="grid-column-start: 9; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 29;"></div><div class = "" vx = "1" vy = "2" dvx = "0" dvy = "0" style="grid-column-start: 9; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 28;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "1" style="grid-column-start: 8; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 16;"></div><div class = "" vx = "0" vy = "4" dvx = "0" dvy = "-1" style="grid-column-start: 7; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 24;"></div><div class = "" vx = "0" vy = "4" dvx = "1" dvy = "-1" style="grid-column-start: 6; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 19;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "1" style="grid-column-start: 7; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 6;"></div><div class = "" vx = "2" vy = "3" dvx = "1" dvy = "0" style="grid-column-start: 9; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 29;"></div><div class = "" vx = "1" vy = "0" dvx = "0" dvy = "1" style="grid-column-start: 8; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 21;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "1" style="grid-column-start: 7; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 28;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 28;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 29;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 31;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 30;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 27;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 32;"></div>
	</div>
	Finish <br> line
	</div>
	<div>Starting line</div>
</div>
</div>

	<div>
Race finished in 32 steps
<div style="background-color: white; color: black;">
	<div style="display:flex; align-items: flex-start">
	<div class = "track">
		<div class = "start" vx = "0" vy = "0" dvx = "0" dvy = "0" style="grid-column-start: 4; grid-row-start: 1;"></div><div class = "start" vx = "1" vy = "0" dvx = "0" dvy = "1" style="grid-column-start: 8; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 9; grid-row-start: 1;"></div><div class = "start" style="grid-column-start: 6; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "-1" dvy = "-1" style="grid-column-start: 7; grid-row-start: 1;"></div><div class = "start" vx = "1" vy = "0" dvx = "-1" dvy = "1" style="grid-column-start: 5; grid-row-start: 1;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 11;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "1" style="grid-column-start: 7; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 24;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "-1" style="grid-column-start: 7; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 32;"></div><div class = "" vx = "0" vy = "4" dvx = "-1" dvy = "0" style="grid-column-start: 7; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 25;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "1" style="grid-column-start: 5; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 26;"></div><div class = "" vx = "1" vy = "3" dvx = "-1" dvy = "1" style="grid-column-start: 6; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 23;"></div><div class = "" vx = "3" vy = "1" dvx = "0" dvy = "0" style="grid-column-start: 14; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 31;"></div><div class = "" vx = "1" vy = "3" dvx = "1" dvy = "0" style="grid-column-start: 7; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 13;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "-1" style="grid-column-start: 7; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 12;"></div><div class = "" vx = "1" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 9; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 26;"></div><div class = "" vx = "2" vy = "3" dvx = "-1" dvy = "1" style="grid-column-start: 9; grid-row-start: 8;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "1" style="grid-column-start: 7; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 21;"></div><div class = "" vx = "2" vy = "2" dvx = "0" dvy = "1" style="grid-column-start: 7; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 32;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "-1" style="grid-column-start: 7; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 28;"></div><div class = "" vx = "1" vy = "1" dvx = "1" dvy = "1" style="grid-column-start: 5; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 28;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "-1" style="grid-column-start: 9; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 6;"></div><div class = "" vx = "2" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 11; grid-row-start: 28;"></div><div class = "" vx = "1" vy = "1" dvx = "0" dvy = "0" style="grid-column-start: 8; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 14;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "0" style="grid-column-start: 5; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 16;"></div><div class = "" vx = "1" vy = "1" dvx = "-1" dvy = "-1" style="grid-column-start: 9; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 16;"></div><div class = "" vx = "0" vy = "4" dvx = "0" dvy = "-1" style="grid-column-start: 7; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 24;"></div><div class = "" vx = "0" vy = "4" dvx = "1" dvy = "-1" style="grid-column-start: 6; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 19;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "1" style="grid-column-start: 7; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 6;"></div><div class = "" vx = "2" vy = "3" dvx = "-1" dvy = "0" style="grid-column-start: 9; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 10;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 4; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 21;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "1" style="grid-column-start: 7; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 28;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 28;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 29;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 31;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 30;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 27;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 32;"></div>
	</div>
	Finish <br> line
	</div>
	<div>Starting line</div>
</div>
</div>

	</div>
mimetext/htmlrootassigneelast_run_timestampA2Apersist_js_state·has_pluto_hook_features§cell_id$3d10f89f-876e-4d25-b8d6-34ce5c99eb8cdepends_on_disabled_cells§runtime Qpublished_object_keysdepends_on_skipped_cells§errored$772b4dd6-870c-4a16-937c-701d5bb5da44queued¤logsrunning¦outputbody]<bond def="run3_1" unique_id="fn&#43;oTFKyWHQR"><input type="button" value="Run Race"></bond>mimetext/htmlrootassigneelast_run_timestampA3|(persist_js_state·has_pluto_hook_features§cell_id$772b4dd6-870c-4a16-937c-701d5bb5da44depends_on_disabled_cells§runtime 
ޤpublished_object_keysdepends_on_skipped_cells§errored$1aaf3827-5851-4156-a7e6-14f5e4d00238queued¤logsrunning¦outputbodyA<div class="markdown"><h4>Random Policy Visualization</h4>
</div>mimetext/htmlrootassigneelast_run_timestampA"*@Bpersist_js_state·has_pluto_hook_features§cell_id$1aaf3827-5851-4156-a7e6-14f5e4d00238depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$d6e7cc6d-f397-4bdf-974e-9a16922393ddqueued¤logsrunning¦outputbody7create_policy_function (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA/аpersist_js_state·has_pluto_hook_features§cell_id$d6e7cc6d-f397-4bdf-974e-9a16922393dddepends_on_disabled_cells§runtime +published_object_keysdepends_on_skipped_cells§errored$1951fc4c-acc4-49a6-a907-7447ff0f430aqueued¤logsrunning¦outputbodyY<div class="markdown"><p>Example trajectories after training for 1000 episodes</p>
</div>mimetext/htmlrootassigneelast_run_timestampA2|?)persist_js_state·has_pluto_hook_features§cell_id$1951fc4c-acc4-49a6-a907-7447ff0f430adepends_on_disabled_cells§runtime 4Եpublished_object_keysdepends_on_skipped_cells§errored$660ef59c-205c-44c2-9c46-5a74e09497abqueued¤logsrunning¦outputbodymimetext/plainrootassigneelast_run_timestampA)T4persist_js_state·has_pluto_hook_features§cell_id$660ef59c-205c-44c2-9c46-5a74e09497abdepends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$a47474b0-f262-4453-a116-addc3a09119equeued¤logsrunning¦outputbodyelementsprefixFloat32elements0.0text/plain0.0text/plain0.0text/plain0.0text/plain0.0text/plain0.0text/plain0.0text/plain0.0text/plain	0.0text/plainmore B@-0.496586text/plaintypeArrayprefix_shortobjectid4786314f961a1d2a!application/vnd.pluto.tree+objectٴ2×200 Matrix{Float32}:
 -0.496586  -0.670122  -0.2741    -0.579848  …  -1.0       -0.100602  -1.0
 -0.796052  -0.775505  -0.293124  -0.300296      0.945649   0.897465   0.823866text/plainprefixFloat32elements2.0text/plain0.0text/plain2.0text/plain2.0text/plain0.0text/plain0.0text/plain0.0text/plain0.0text/plain	2.0text/plainmore B@0.0text/plaintypeArrayprefix_shortobjectida24a12c04ba1deaa!application/vnd.pluto.tree+objecttypeTupleobjectidbe8778fac26ed8e6mime!application/vnd.pluto.tree+objectrootassigneeq_offpollast_run_timestampA.!persist_js_state·has_pluto_hook_features§cell_id$a47474b0-f262-4453-a116-addc3a09119edepends_on_disabled_cells§runtime2*published_object_keysdepends_on_skipped_cells§errored$acb270a1-e2b9-46bc-9a52-9f66f1cca17cqueued¤logsrunning¦outputbody<bond def="mcϵs1" unique_id="dJACw8LFTPeE"><span style='display: contents;'>
	<span style='display: contents;'><div class="markdown"><table><tr><th align="center">Number of Episodes</th><th align="center">ϵ</th><th align="center">Decay ϵ</th></tr><tr><td align="center"><pl-combined-child key='nfejuiapbp' style='display: contents;'><input type='number' min='1' step='1' max='10000000' value='1000'></pl-combined-child></td><td align="center"><pl-combined-child key='nfejuiapbp' style='display: contents;'><input type='number' min='0.001' step='0.001' max='1.0' value='0.01'></pl-combined-child></td><td align="center"><pl-combined-child key='nfejuiapbp' style='display: contents;'><input type="checkbox"></pl-combined-child></td></tr></table>
</div><script id='nfejuiapbp'>
const div = currentScript.parentElement
let key = "nfejuiapbp"
const inputs = div.querySelectorAll(`pl-combined-child[key='${key}'] > *:first-child`)

const values = Array(inputs.length)

inputs.forEach(async (el,i) => {
	el.oninput = (e) => {
		e.stopPropagation()
	}
	const gen = Generators.input(el)
	while(true) {
		values[i] = await gen.next().value
		div.dispatchEvent(new CustomEvent("input", {}))
	}
})


let set_input_value = (() => {
	let result = null
	try {
	result = setBoundElementValueLikePluto
} catch (e) {
	result = ((input, new_value) => {
	// fallback in case https://github.com/fonsp/Pluto.jl/pull/1755 is not available
    if (new_value == null) {
        //@ts-ignore
        input.value = new_value
        return
    }
    if (input instanceof HTMLInputElement) {
        switch (input.type) {
            case "range":
            case "number": {
                if (input.valueAsNumber !== new_value) {
                    input.valueAsNumber = new_value
                }
                return
            }
            case "date": {
                if (input.valueAsDate == null || Number(input.valueAsDate) !== Number(new_value)) {
                    input.valueAsDate = new_value
                }
                return
            }
            case "checkbox": {
                if (input.checked !== new_value) {
                    input.checked = new_value
                }
                return
            }
            case "file": {
                // Can't set files :(
                return
            }
        }
    } else if (input instanceof HTMLSelectElement && input.multiple) {
        for (let option of Array.from(input.options)) {
            option.selected = new_value.includes(option.value)
        }
        return
    }
    //@ts-ignore
    if (input.value !== new_value) {
        //@ts-ignore
        input.value = new_value
    }
})
}
return result
})()


Object.defineProperty(div, 'value', {
	get: () => values,
	set: (newvals) => {
		if(!newvals) {
			return
		}
		inputs.forEach((el, i) => {
			values[i] = newvals[i]
			set_input_value(el, newvals[i])
		})
},
	configurable: true,
});

</script></span>
	<input type=submit id='mlsojuyloz'>
	<script id='mlsojuyloz'>

let key = "mlsojuyloz"

let div = currentScript.parentElement
let button = currentScript.previousElementSibling
let input = div.firstElementChild
if(input === button) {
	return
}


let set_input_value = (() => {
	let result = null
	try {
	result = setBoundElementValueLikePluto
} catch (e) {
	result = ((input, new_value) => {
	// fallback in case https://github.com/fonsp/Pluto.jl/pull/1755 is not available
    if (new_value == null) {
        //@ts-ignore
        input.value = new_value
        return
    }
    if (input instanceof HTMLInputElement) {
        switch (input.type) {
            case "range":
            case "number": {
                if (input.valueAsNumber !== new_value) {
                    input.valueAsNumber = new_value
                }
                return
            }
            case "date": {
                if (input.valueAsDate == null || Number(input.valueAsDate) !== Number(new_value)) {
                    input.valueAsDate = new_value
                }
                return
            }
            case "checkbox": {
                if (input.checked !== new_value) {
                    input.checked = new_value
                }
                return
            }
            case "file": {
                // Can't set files :(
                return
            }
        }
    } else if (input instanceof HTMLSelectElement && input.multiple) {
        for (let option of Array.from(input.options)) {
            option.selected = new_value.includes(option.value)
        }
        return
    }
    //@ts-ignore
    if (input.value !== new_value) {
        //@ts-ignore
        input.value = new_value
    }
})
}
return result
})()



let private_value = null
let public_value = null




private_value = public_value = div.value
if(private_value != null) {
	set_input_value(input, private_value)
} else {

	// private_value = public_value = input.value
}

input.oninput = (e) => {
	e.stopPropagation()
}
const gen = Generators.input(input)

// If the child does not have an initial value, the `gen.next().value` promise will never resolve. If it does, then it resolves instantly.
let first_value = await Promise.any([
	gen.next().value,
	Promise.resolve(undefined)
])
private_value = public_value = first_value

;(async () => {
	while(true) {
		private_value = await gen.next().value
		// div.dispatchEvent(new CustomEvent("input", {}))
	}
})()

button.addEventListener("click", () => {
	public_value = private_value
	div.dispatchEvent(new CustomEvent("input", {}))
})


Object.defineProperty(div, 'value', {
	get: () => public_value,
	set: (newval) => {
		private_value = newval
		public_value = newval
		
		set_input_value(input, newval)
	},
	configurable: true,
});

</script></span></bond>mimetext/htmlrootassigneelast_run_timestampA3\ٰpersist_js_state·has_pluto_hook_features§cell_id$acb270a1-e2b9-46bc-9a52-9f66f1cca17cdepends_on_disabled_cells§runtimeINepublished_object_keysdepends_on_skipped_cells§errored$334b4d77-8784-46be-b9e8-80c0a2244694queued¤logsrunning¦outputbody3monte_carlo_ϵsoft (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA)Wpersist_js_state·has_pluto_hook_features§cell_id$334b4d77-8784-46be-b9e8-80c0a2244694depends_on_disabled_cells§runtime ?Npublished_object_keysdepends_on_skipped_cells§errored$e5384dd0-fad1-4a24-b011-73b062fcfb1bqueued¤logsrunning¦outputbody}<div class="markdown"><blockquote>
<h3><em>Exercise 5.1</em></h3>
<p>Consider the diagroms on the right in Figure 5.1.  Why does the estimated value function jump for the last two rows in the rear?  Why does it drop off for the whole last row on the left?  Why are the frontmost values higher in the upper diagrams than in the lower?</p>
</blockquote>
<p>The last two rows in the rear are for a player sum equal to 20 or 21.  For a sum of 19 and lower, this policy will hit which is suboptimal for these high sums.  For the sums of 20 or 21 though, sticking is optimal so the value jumps compared to the suboptimal hit at 19.</p>
<p>The far left row represents cases where the dealer is showing an Ace.  Since an Ace is a flexible card, the dealer policy will have more options that result in a win including the possibility of having another face card already &#40;dealer natural&#41;.  It is always worse for the player if the dealer is known to have an Ace.</p>
<p>The frontmost values represent cases where the player sum is 12.  If there is a usable Ace this means that means that the player has two Aces which results in a sum of 12 when the first Ace is counted as 1 and the second is <em>usable</em> and counted as 11.  If there is no usable Ace than a sum of 12 would have to result from some other combination of cards such as 10/2, 9/3, etc...  Since the first case has two Aces, it means that potentially both could count as 1 if needed to avoid a bust.  In the case without a usable Ace, the sum is the same, but there are more opportunities to bust if we draw a card worth 10, so having a sum of 12 with a usable Ace is strictly better.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA"&mapersist_js_state·has_pluto_hook_features§cell_id$e5384dd0-fad1-4a24-b011-73b062fcfb1bdepends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$35914757-6af1-4056-bba4-a9996f65f7f7queued¤logsrunning¦outputbodyelementsprefixFloat32elements0.0text/plain0.0text/plain0.0text/plain0.0text/plain0.0text/plain0.0text/plain0.0text/plain0.0text/plain	0.0text/plainmore B@0.812565text/plaintypeArrayprefix_shortobjectid886b20cbcddd915e!application/vnd.pluto.tree+object$2×1 Matrix{Float32}:
 0.812565
 0.0text/plainprefixFloat32elements0.0text/plain0.0text/plain0.0text/plain0.0text/plain0.0text/plain0.0text/plain0.0text/plain0.0text/plain	0.0text/plainmore B@0.0text/plaintypeArrayprefix_shortobjectid955d7fd8e7c24e2c!application/vnd.pluto.tree+objecttypeTupleobjectidbf7eb1765917781emime!application/vnd.pluto.tree+objectrootassigneelast_run_timestampA.aapersist_js_state·has_pluto_hook_features§cell_id$35914757-6af1-4056-bba4-a9996f65f7f7depends_on_disabled_cells§runtimeppublished_object_keysdepends_on_skipped_cells§errored$cde7be85-9344-4526-bcb2-c2c8b3322435queued¤logsrunning¦outputbodyelements9×12875 Matrix{Float32}:
 0.111111  0.00111111  0.00111111  …  0.111111  0.111111  0.111111  0.111111
 0.111111  0.00111111  0.00111111     0.111111  0.111111  0.111111  0.111111
 0.111111  0.00111111  0.00111111     0.111111  0.111111  0.111111  0.111111
 0.111111  0.00111111  0.991111       0.111111  0.111111  0.111111  0.111111
 0.111111  0.00111111  0.00111111     0.111111  0.111111  0.111111  0.111111
 0.111111  0.00111111  0.00111111  …  0.111111  0.111111  0.111111  0.111111
 0.111111  0.00111111  0.00111111     0.111111  0.111111  0.111111  0.111111
 0.111111  0.00111111  0.00111111     0.111111  0.111111  0.111111  0.111111
 0.111111  0.991111    0.00111111     0.111111  0.111111  0.111111  0.111111text/plain9×12875 Matrix{Float32}:
 0.0  -525.0   -24.0   -32.0     0.0   -18.0  …      0.0  0.0  0.0  0.0  0.0  0.0
 0.0   -50.0  -119.0   -11.0     0.0  -786.0         0.0  0.0  0.0  0.0  0.0  0.0
 0.0   -29.0   -52.5  -190.0     0.0  -106.0         0.0  0.0  0.0  0.0  0.0  0.0
 0.0  -247.0   -12.0     0.0     0.0   -25.0         0.0  0.0  0.0  0.0  0.0  0.0
 0.0   -43.0   -13.0     0.0     0.0   -11.0     -1098.0  0.0  0.0  0.0  0.0  0.0
 0.0   -65.0  -783.0   -88.0  -288.0   -38.0  …      0.0  0.0  0.0  0.0  0.0  0.0
 0.0   -10.0   -58.0   -16.0     0.0   -43.0         0.0  0.0  0.0  0.0  0.0  0.0
 0.0  -120.0   -18.0  -181.0  -433.0   -29.5         0.0  0.0  0.0  0.0  0.0  0.0
 0.0     0.0  -292.0     0.0     0.0   -98.0      -545.0  0.0  0.0  0.0  0.0  0.0text/plaintypeTupleobjectidc9ddb414e83f2974mime!application/vnd.pluto.tree+objectrootassigneelast_run_timestampA3*persist_js_state·has_pluto_hook_features§cell_id$cde7be85-9344-4526-bcb2-c2c8b3322435depends_on_disabled_cells§runtimevpublished_object_keysdepends_on_skipped_cells§errored$881ba6c3-0e6a-4bb8-bc14-2e0face560f2queued¤logsrunning¦outputbody<div class="markdown"><blockquote>
<h3><em>Exercise 5.6</em></h3>
<p>What is the equation analogous to &#40;5.6&#41; for <em>action</em> values <span class="tex">$Q&#40;s,a&#41;$</span> instead of state values <span class="tex">$V&#40;s&#41;$</span>, again given returns generated using <span class="tex">$b$</span>?</p>
</blockquote>
<p>Equation &#40;5.6&#41;:</p>
<p class="tex">$$V&#40;s&#41; &#61; \frac&#123;\sum_&#123;t \in \mathscr&#123;T&#125;&#40;s&#41;&#125;\rho_&#123;t:T&#40;t&#41;-1&#125;G_t&#125;&#123;\sum_&#123;t \in \mathscr&#123;T&#125;&#40;s&#41;&#125; \rho_&#123;t:T&#40;t&#41;-1&#125;&#125;$$</p>
<p>For <span class="tex">$Q&#40;s,a&#41;$</span>, there is no need to calculate the sampling ratio for the first action selected.  Here <span class="tex">$\mathscr&#123;T&#125;&#40;s, a&#41;$</span> is the set of all time steps in which the state action pair <span class="tex">$&#40;s, a&#41;$</span> is visited.</p>
<p class="tex">$$Q&#40;s,a&#41; &#61; \frac&#123;\sum_&#123;t \in \mathscr&#123;T&#125;&#40;s, a&#41;&#125;\rho_&#123;t&#43;1:T&#40;t&#41;-1&#125;G_t&#125;&#123;\sum_&#123;t \in \mathscr&#123;T&#125;&#40;s, a&#41;&#125; \rho_&#123;t&#43;1:T&#40;t&#41;-1&#125;&#125;$$</p>
</div>mimetext/htmlrootassigneelast_run_timestampA"([persist_js_state·has_pluto_hook_features§cell_id$881ba6c3-0e6a-4bb8-bc14-2e0face560f2depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$5c57e4b7-51d6-492d-9fc9-bcdab1dd46f4queued¤logsrunning¦outputbody6plot_blackjack_policy (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA%װpersist_js_state·has_pluto_hook_features§cell_id$5c57e4b7-51d6-492d-9fc9-bcdab1dd46f4depends_on_disabled_cells§runtime -	published_object_keysdepends_on_skipped_cells§errored$e0d3d7d1-203f-42fa-8570-8d1d88bf17c2queued¤logsrunning¦outputbody-<div class="markdown"><h5>Track 2</h5>
</div>mimetext/htmlrootassigneelast_run_timestampA"*Wpersist_js_state·has_pluto_hook_features§cell_id$e0d3d7d1-203f-42fa-8570-8d1d88bf17c2depends_on_disabled_cells§runtime ҵpublished_object_keysdepends_on_skipped_cells§errored$760c5361-02d4-46b7-a05c-fc2d10d93de6queued¤logsrunning¦outputbody3monte_carlo_pred_V (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA%ppersist_js_state·has_pluto_hook_features§cell_id$760c5361-02d4-46b7-a05c-fc2d10d93de6depends_on_disabled_cells§runtime 8Epublished_object_keysdepends_on_skipped_cells§errored$d55860d1-e4c1-4a79-adbe-b40a6d6283a7queued¤logsrunning¦outputbody>initialize_state_action_value (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA$persist_js_state·has_pluto_hook_features§cell_id$d55860d1-e4c1-4a79-adbe-b40a6d6283a7depends_on_disabled_cells§runtime -published_object_keysdepends_on_skipped_cells§errored$06297d75-121a-4178-b45b-83e167efd90dqueued¤logsrunning¦outputbody*joinlines (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA0
Apersist_js_state·has_pluto_hook_features§cell_id$06297d75-121a-4178-b45b-83e167efd90ddepends_on_disabled_cells§runtime kpublished_object_keysdepends_on_skipped_cells§errored$abe70666-39f8-4f1d-a285-a3a99f696d10queued¤logsrunning¦outputbodyz<div class="markdown"><blockquote>
<h3><em>Exercise 5.13</em></h3>
<p>Show the steps to derive &#40;5.14&#41; from &#40;5.12&#41;</p>
</blockquote>
<p>Starting at &#40;5.12&#41;</p>
<p class="tex">$$\rho_&#123;t:T-1&#125;R_&#123;t&#43;1&#125;&#61;\frac&#123;\pi&#40;A_t|S_t&#41;&#125;&#123;b&#40;A_t|S_t&#41;&#125;\frac&#123;\pi&#40;A_&#123;t&#43;1&#125;|S_&#123;t&#43;1&#125;&#41;&#125;&#123;b&#40;A_&#123;t&#43;1&#125;|S_&#123;t&#43;1&#125;&#41;&#125;\frac&#123;\pi&#40;A_&#123;t&#43;2&#125;|S_&#123;t&#43;2&#125;&#41;&#125;&#123;b&#40;A_&#123;t&#43;2&#125;|S_&#123;t&#43;2&#125;&#41;&#125;\cdots\frac&#123;\pi&#40;A_&#123;T-1&#125;|S_&#123;T-1&#125;&#41;&#125;&#123;b&#40;A_&#123;T-1&#125;|S_&#123;T-1&#125;&#41;&#125;R_&#123;t&#43;1&#125;$$</p>
<p>For &#40;5.14&#41; we need to turn this into an expected value</p>
<p class="tex">$$\mathbb&#123;E&#125;&#91;\rho_&#123;t:T-1&#125;R_&#123;t&#43;1&#125;&#93;$$</p>
<p>Now we know that the reward at time step t&#43;1 is only dependent on the action and state at time t.  Moreover, the later parts of the trajectory are also independent of each other.  So we can separate some of these terms into a product of expected values rather than an expected value of products:</p>
<p class="tex">$$\mathbb&#123;E&#125;&#91;\rho_&#123;t:T-1&#125;R_&#123;t&#43;1&#125;&#93;&#61;\mathbb&#123;E&#125; \left &#91; \frac&#123;\pi&#40;A_t|S_t&#41;&#125;&#123;b&#40;A_t|S_t&#41;&#125;\frac&#123;\pi&#40;A_&#123;t&#43;1&#125;|S_&#123;t&#43;1&#125;&#41;&#125;&#123;b&#40;A_&#123;t&#43;1&#125;|S_&#123;t&#43;1&#125;&#41;&#125;\frac&#123;\pi&#40;A_&#123;t&#43;2&#125;|S_&#123;t&#43;2&#125;&#41;&#125;&#123;b&#40;A_&#123;t&#43;2&#125;|S_&#123;t&#43;2&#125;&#41;&#125;\cdots\frac&#123;\pi&#40;A_&#123;T-1&#125;|S_&#123;T-1&#125;&#41;&#125;&#123;b&#40;A_&#123;T-1&#125;|S_&#123;T-1&#125;&#41;&#125;R_&#123;t&#43;1&#125; \right &#93;$$</p>
<p class="tex">$$&#61;\mathbb&#123;E&#125; \left &#91; \frac&#123;\pi&#40;A_t|S_t&#41;&#125;&#123;b&#40;A_t|S_t&#41;&#125;R_&#123;t&#43;1&#125; \right &#93; \prod_&#123;k&#61;t&#43;1&#125;^&#123;T-1&#125;\mathbb&#123;E&#125; \left &#91; \frac&#123;\pi&#40;A_k|S_k&#41;&#125;&#123;b&#40;A_k|S_k&#41;&#125; \right &#93;$$</p>
<p>We know from &#40;5.13&#41; that <span class="tex">$\mathbb&#123;E&#125; \left &#91; \frac&#123;\pi&#40;A_k|S_k&#41;&#125;&#123;b&#40;A_k|S_k&#41;&#125; \right &#93; &#61; 1$</span> so the above expression simplifies to: <span class="tex">$\mathbb&#123;E&#125; \left &#91; \frac&#123;\pi&#40;A_t|S_t&#41;&#125;&#123;b&#40;A_t|S_t&#41;&#125;R_&#123;t&#43;1&#125; \right &#93;$</span>.  Using the original shorthand with ρ:</p>
<p class="tex">$$\mathbb&#123;E&#125;&#91;\rho_&#123;t:T-1&#125;R_&#123;t&#43;1&#125;&#93;&#61;\mathbb&#123;E&#125; \left &#91; \frac&#123;\pi&#40;A_t|S_t&#41;&#125;&#123;b&#40;A_t|S_t&#41;&#125;R_&#123;t&#43;1&#125; \right &#93;&#61;\mathbb&#123;E&#125;&#91;\rho_&#123;t:t&#125;R_&#123;t&#43;1&#125;&#93;$$</p>
</div>mimetext/htmlrootassigneelast_run_timestampA",persist_js_state·has_pluto_hook_features§cell_id$abe70666-39f8-4f1d-a285-a3a99f696d10depends_on_disabled_cells§runtime 	Kpublished_object_keysdepends_on_skipped_cells§errored$7ce6e28e-acd7-46d1-87d6-a25f4656d79dqueued¤logsrunning¦outputbody]<bond def="run2_1" unique_id="eRQOtO/kh&#43;OQ"><input type="button" value="Run race"></bond>mimetext/htmlrootassigneelast_run_timestampA2"persist_js_state·has_pluto_hook_features§cell_id$7ce6e28e-acd7-46d1-87d6-a25f4656d79ddepends_on_disabled_cells§runtime 

published_object_keysdepends_on_skipped_cells§errored$a85e7dd3-ea5e-4c77-a18e-f1e190658ae3queued¤logsrunning¦outputbody.sample_action (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA$vpersist_js_state·has_pluto_hook_features§cell_id$a85e7dd3-ea5e-4c77-a18e-f1e190658ae3depends_on_disabled_cells§runtime `published_object_keysdepends_on_skipped_cells§errored$68f9e0d9-5c9d-4e89-b5ae-f24fd7544a09queued¤logsrunning¦outputbodyelements9×7300 Matrix{Float32}:
 0.111111  0.142857  0.0          …  0.111111  0.111111  0.111111  0.111111
 0.111111  0.142857  0.0             0.111111  0.111111  0.111111  0.111111
 0.111111  0.142857  0.16652         0.111111  0.111111  0.111111  0.111111
 0.111111  0.0       0.16652         0.111111  0.111111  0.111111  0.111111
 0.111111  0.0       0.16652         0.111111  0.111111  0.111111  0.111111
 0.111111  0.142857  0.000879308  …  0.111111  0.111111  0.111111  0.111111
 0.111111  0.142857  0.16652         0.111111  0.111111  0.111111  0.111111
 0.111111  0.142857  0.16652         0.111111  0.111111  0.111111  0.111111
 0.111111  0.142857  0.16652         0.111111  0.111111  0.111111  0.111111text/plain9×7300 Matrix{Float32}:
 0.0     0.0  -5149.0   -84.0   -3379.0  …  0.0  0.0  0.0   0.0  0.0  0.0  0.0  0.0
 0.0     0.0  -1134.0   -25.0     -35.0     0.0  0.0  0.0   0.0  0.0  0.0  0.0  0.0
 0.0     0.0      0.0   -63.0   -3169.0     0.0  0.0  0.0   0.0  0.0  0.0  0.0  0.0
 0.0  -689.0      0.0  -754.0       0.0     0.0  0.0  0.0   0.0  0.0  0.0  0.0  0.0
 0.0  -856.0      0.0     0.0     -67.0     0.0  0.0  0.0   0.0  0.0  0.0  0.0  0.0
 0.0     0.0    -27.0     0.0  -12549.0  …  0.0  0.0  0.0   0.0  0.0  0.0  0.0  0.0
 0.0     0.0      0.0   -37.0  -13470.0     0.0  0.0  0.0  -1.0  0.0  0.0  0.0  0.0
 0.0     0.0      0.0     0.0     -18.0     0.0  0.0  0.0   0.0  0.0  0.0  0.0  0.0
 0.0     0.0      0.0     0.0       0.0     0.0  0.0  0.0   0.0  0.0  0.0  0.0  0.0text/plaintypeTupleobjectid2b08379900fff7c1mime!application/vnd.pluto.tree+objectrootassigneelast_run_timestampA2persist_js_state·has_pluto_hook_features§cell_id$68f9e0d9-5c9d-4e89-b5ae-f24fd7544a09depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cells§errored$ec29865f-3ba3-4bb3-84df-c2b472e03ff2queued¤logsrunning¦outputbodyelementsٿ2×200 Matrix{Float32}:
 1.0  1.0  1.0  1.0  1.0  1.0  1.0  0.0  …  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  1.0     1.0  1.0  1.0  1.0  1.0  1.0  1.0  1.0text/plainٴ2×200 Matrix{Float32}:
 -0.314661  -0.543897   0.0834141  -0.262767  …  -1.0       0.646746  -1.0
 -0.77313   -0.773448  -0.298548   -0.311517      0.947591  0.873747   0.829768text/plaintypeTupleobjectida6680ebecb2a25cfmime!application/vnd.pluto.tree+objectrootassigneelast_run_timestampA'1persist_js_state·has_pluto_hook_features§cell_id$ec29865f-3ba3-4bb3-84df-c2b472e03ff2depends_on_disabled_cells§runtimeηpublished_object_keysdepends_on_skipped_cells§errored$1d6eccf0-2731-47fc-9a41-ea8649e290efqueued¤logsrunning¦outputbodyelements9×7300 Matrix{Float32}:
 0.111111  0.116111    0.111111  …  0.111111  0.111111  0.111111  0.111111
 0.111111  0.116111    0.111111     0.111111  0.111111  0.111111  0.111111
 0.111111  0.116111    0.111111     0.111111  0.111111  0.111111  0.111111
 0.111111  0.116111    0.111111     0.111111  0.111111  0.111111  0.111111
 0.111111  0.00111111  0.111111     0.111111  0.111111  0.111111  0.111111
 0.111111  0.116111    0.111111  …  0.111111  0.111111  0.111111  0.111111
 0.111111  0.116111    0.111111     0.111111  0.111111  0.111111  0.111111
 0.111111  0.116111    0.111111     0.111111  0.111111  0.111111  0.111111
 0.111111  0.116111    0.111111     0.111111  0.111111  0.111111  0.111111text/plain9×7300 Matrix{Float32}:
 0.0      0.0  0.0  -5484.0      0.0  0.0  …  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 0.0      0.0  0.0      0.0      0.0  0.0     0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 0.0      0.0  0.0      0.0      0.0  0.0     0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 0.0      0.0  0.0      0.0      0.0  0.0     0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 0.0  -3014.0  0.0      0.0  -7010.0  0.0     0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 0.0      0.0  0.0      0.0      0.0  0.0  …  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 0.0      0.0  0.0      0.0      0.0  0.0     0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 0.0      0.0  0.0      0.0      0.0  0.0     0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 0.0      0.0  0.0      0.0  -2901.0  0.0     0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0text/plaintypeTupleobjectidfbacd052b48a6dfemime!application/vnd.pluto.tree+objectrootassigneelast_run_timestampA3{persist_js_state·has_pluto_hook_features§cell_id$1d6eccf0-2731-47fc-9a41-ea8649e290efdepends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cells§errored$9ca72278-fff6-4b0f-b72c-e0d3768aff73queued¤logsrunning¦outputbodyk:<div class="markdown"><h3>Figure 5.3</h3>
<p>Weighted importance sampling produces lower error estimates of the value of a single blackjack state from off-policy episodes</p>
	<script id='plot_1'>
		// We start by putting all the variable interpolation here at the beginning
		// We have to convert all typedarrays in the layout to normal arrays. See Issue #25
		// We use lodash for this for compactness
		function removeTypedArray(o) {
			return _.isTypedArray(o) ? Array.from(o) :
			_.isPlainObject(o) ? _.mapValues(o, removeTypedArray) : 
			o
		}

		// Publish the plot object to JS
		let plot_obj = _.update(/* See the documentation for AbstractPlutoDingetjes.Display.published_to_js */ getPublishedObject("c6e0de0c-3901-11f0-234e-bd09c571f662/58d51ac87604fe9c"), "layout", removeTypedArray)
		// Get the plotly listeners
		const plotly_listeners = {}
		// Get the JS listeners
		const js_listeners = {}
		// Deal with eventual custom classes
		let custom_classlist = []


		// Load the plotly library
		let Plotly = undefined
		try {
			let _mod = await import("./plotlyjs/plotlyjs-2.26.2.min.js")
			Plotly = _mod.default
		} catch (e) {
			console.log("Local load failed, trying with the web esm.sh version")
			let _mod = await import("https://esm.sh/plotly.js-dist-min@2.26.2/es2022/plotly.js-dist-min.mjs")
			Plotly = _mod.default
		}

		// Check if we have to force local mathjax font cache
		if (false && window?.MathJax?.config?.svg?.fontCache === 'global') {
			window.MathJax.config.svg.fontCache = 'local'
		}

		// Flag to check if this cell was  manually ran or reactively ran
const firstRun = this ? false : true
const CONTAINER = this ?? html`<div class='plutoplotly-container'>`
const PLOT = CONTAINER.querySelector('.js-plotly-plot') ?? CONTAINER.appendChild(html`<div>`)
const parent = CONTAINER.parentElement
// We use a controller to remove event listeners upon invalidation
const controller = new AbortController()
// We have to add this to keep supporting @bind with the old API using PLOT
PLOT.addEventListener('input', (e) => {
	CONTAINER.value = PLOT.value
	if (e.bubbles) {
		return
	}
	CONTAINER.dispatchEvent(new CustomEvent('input'))
}, { signal: controller.signal })

	// This create the style subdiv on first run
	firstRun && CONTAINER.appendChild(html`
	<style>
	.plutoplotly-container {
		width: 100%;
		height: 100%;
		min-height: 0;
		min-width: 0;
	}
	.plutoplotly-container .js-plotly-plot .plotly div {
		margin: 0 auto; // This centers the plot
	}
	.plutoplotly-container.popped-out {
		overflow: auto;
		z-index: 1000;
		position: fixed;
		resize: both;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		border-top-left-radius: 0px;
		border-top-right-radius: 0px;
	}
	.plutoplotly-clipboard-header {
		display: flex;
		flex-flow: row wrap;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-top-left-radius: 12px;
		border-top-right-radius: 12px;
		position: fixed;
		z-index: 1001;
		cursor: move;
		transform: translate(0px, -100%);
		padding: 5px;
	}
	.plutoplotly-clipboard-header span {
		display: inline-block;
		flex: 1
	}
	.plutoplotly-clipboard-header.hidden {
		display: none;
	}
	.clipboard-span {
		position: relative;
	}
	.clipboard-value {
		padding-right: 5px;
		padding-left: 2px;
		cursor: text;
	}
	.clipboard-span.format {
		display: none;
	}
	.clipboard-span.filename {
		flex: 0 0 100%;
		text-align: center;
		border-top: 3px solid var(--kbd-border-color);
		margin-top: 5px;
		display: none;
	}
	.plutoplotly-container.filesave .clipboard-span.filename {
		display: inline-block;
	}
	.clipboard-value.filename {
		margin-left: 3px;
		text-align: left;
		min-width: min(60%, min-content);
	}
	.plutoplotly-container.filesave .clipboard-span.format {
		display: inline-flex;
	}
	.clipboard-span.format .label {
		flex: 0 0 0;
	}
	.clipboard-value.format {
		position: relative;
		flex: 1 0 auto;
		min-width: 30px;
		margin-right: 10px;
	}
	div.format-options {
		display: inline-flex;
		flex-flow: column;
		position: absolute;
		background: var(--main-bg-color);
		border-radius: 12px;
		padding-left: 3px;
		z-index: 2000;
	}
	div.format-options:hover {
		cursor: pointer;
		border: 3px solid var(--kbd-border-color);
		padding: 3px;
		transform: translate(-3px, -6px);
	}
	div.format-options .format-option {
		display: none;
	}
	div.format-options:hover .format-option {
		display: inline-block;
	}
	.format-option:not(.selected) {
		margin-top: 3px;
	}
	div.format-options .format-option.selected {
		order: -1;
		display: inline-block;
	}
	.format-option:hover {
		background-color: var(--kbd-border-color);
	}
	span.config-value {
		font-weight: normal;
		color: var(--pluto-output-color);
		display: none;
		position: absolute;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		transform: translate(0px, calc(-100% - 10px));
		padding: 5px;
	}
	.label {
		user-select: none;
	}
	.label:hover span.config-value {
		display: inline-block;
		min-width: 150px;
	}
	.clipboard-span.matching-config .label {
		color: var(--cm-macro-color);
		font-weight: bold;
	}
	.clipboard-span.different-config .label {
		color: var(--cm-tag-color);
		font-weight: bold;
	}
</style>
`)

let original_height = plot_obj.layout.height
let original_width = plot_obj.layout.width
// For the height we have to also put a fixed value in case the plot is put on a non-fixed-size container (like the default wrapper)
// We define a variable to check whether we still have to remove the fixed height
let remove_container_size = firstRun
let container_height = original_height ?? PLOT.container_height ?? 400
CONTAINER.style.height = container_height + 'px'

// We create a Promise version of setTimeout
function delay(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

// We import interact for dragging/resizing
const { default: interact } = await import('https://esm.sh/interactjs@1.10.19')


function getImageOptions() {
  const o = plot_obj.config.toImageButtonOptions ?? {};
  return {
    format: o.format ?? "png",
    width: o.width ?? original_width,
    height: o.height ?? original_height,
    scale: o.scale ?? 1,
    filename: o.filename ?? "newplot",
  };
}

const CLIPBOARD_HEADER =
  CONTAINER.querySelector(".plutoplotly-clipboard-header") ??
  CONTAINER.insertAdjacentElement(
    "afterbegin",
    html`<div class="plutoplotly-clipboard-header hidden">
      <span class="clipboard-span format"
        ><span class="label">Format:</span
        ><span class="clipboard-value format"></span
      ></span>
      <span class="clipboard-span width"
        ><span class="label">Width:</span
        ><span class="clipboard-value width"></span>px</span
      >
      <span class="clipboard-span height"
        ><span class="label">Height:</span
        ><span class="clipboard-value height"></span>px</span
      >
      <span class="clipboard-span scale"
        ><span class="label">Scale:</span
        ><span class="clipboard-value scale"></span
      ></span>
      <button class="clipboard-span set">Set</button>
      <button class="clipboard-span unset">Unset</button>
      <span class="clipboard-span filename"
        ><span class="label">Filename:</span
        ><span class="clipboard-value filename"></span
      ></span>
    </div>`
  );

function checkConfigSync(container) {
  const valid_classes = [
    "missing-config",
    "matching-config",
    "different-config",
  ];
  function setClass(cl) {
    for (const name of valid_classes) {
      container.classList.toggle(name, name == cl);
    }
  }
  // We use the custom getters we'll set up in the container
  const { ui_value, config_value, config_span, key } = container;
  if (config_value === undefined) {
    setClass("missing-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> is not present in the config.`;
  } else if (ui_value == config_value) {
    setClass("matching-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has the same value in the config and in the header.`;
  } else {
    setClass("different-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has a different value (<em>${config_value}</em>) in the config.`;
  }
  // Add info about setting and unsetting
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click on the label <em><b>once</b></em> to set the current UI value in the config.`
  );
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click <em><b>twice</b></em> to remove this key from the config.`
  );
}

const valid_formats = ["png", "svg", "webp", "jpeg", "full-json"];
function initializeUIValueSpan(span, key, value) {
  const container = span.closest(".clipboard-span");
  span.contentEditable = key === "format" ? "false" : "true";
  let parse = (x) => x;
  let update = (x) => (span.textContent = x);
  if (key === "width" || key === "height") {
    parse = (x) => Math.round(parseFloat(x));
  } else if (key === "scale") {
    parse = parseFloat;
  } else if (key === "format") {
    // We remove contentEditable
    span.contentEditable = "false";
    // Here we first add the subspans for each option
    const opts_div = span.appendChild(html`<div class="format-options"></div>`);
    for (const fmt of valid_formats) {
      const opt = opts_div.appendChild(
        html`<span class="format-option ${fmt}">${fmt}</span>`
      );
      opt.onclick = (e) => {
        span.value = opt.textContent;
      };
    }
    parse = (x) => {
      return valid_formats.includes(x) ? x : localValue;
    };
    update = (x) => {
      for (const opt of opts_div.children) {
        opt.classList.toggle("selected", opt.textContent === x);
      }
    };
  } else {
    // We only have filename here
  }
  let localValue;
  Object.defineProperty(span, "value", {
    get: () => {
      return localValue;
    },
    set: (val) => {
      if (val !== "") {
        localValue = parse(val);
      }
      update(localValue);
      checkConfigSync(container);
    },
  });
  // We also assign a listener so that the editable is blurred when enter is pressed
  span.onkeydown = (e) => {
    if (e.keyCode === 13) {
      e.preventDefault();
      span.blur();
    }
  };
  span.value = value;
}

function initializeConfigValueSpan(span, key) {
  // Here we mostly want to define the setter and getter
  const container = span.closest(".clipboard-span");
  Object.defineProperty(span, "value", {
    get: () => {
      return plot_obj.config.toImageButtonOptions[key];
    },
    set: (val) => {
      // if undefined is passed, we remove the entry from the options
      if (val === undefined) {
        delete plot_obj.config.toImageButtonOptions[key];
      } else {
        plot_obj.config.toImageButtonOptions[key] = val;
      }
      checkConfigSync(container);
    },
  });
}

const config_spans = {};
for (const [key, value] of Object.entries(getImageOptions())) {
  const container = CLIPBOARD_HEADER.querySelector(`.clipboard-span.${key}`);
  const label = container.querySelector(".label");
  // We give the label a function that on single click will set the current value and with double click will unset it
  label.onclick = DualClick(
    () => {
      container.config_value = container.ui_value;
    },
    (e) => {
      console.log("e", e);
      e.preventDefault();
      container.config_value = undefined;
    }
  );
  const ui_value_span = container.querySelector(".clipboard-value");
  const config_value_span =
    container.querySelector(".config-value") ??
    label.insertAdjacentElement(
      "afterbegin",
      html`<span class="config-value"></span>`
    );
  // Assing the two spans as properties of the containing span
  container.ui_span = ui_value_span;
  container.config_span = config_value_span;
  container.key = key;
  config_spans[key] = container;
  if (firstRun) {
    plot_obj.config.toImageButtonOptions =
      plot_obj.config.toImageButtonOptions ?? {};
    // We do the initialization of the value span
    initializeUIValueSpan(ui_value_span, key, value);
    // Then we initialize the config value
    initializeConfigValueSpan(config_value_span, key);
    // We put some convenience getters/setters
    // ui_value forward
    Object.defineProperty(container, "ui_value", {
      get: () => ui_value_span.value,
      set: (val) => {
        ui_value_span.value = val;
      },
    });
    // config_value forward
    Object.defineProperty(container, "config_value", {
      get: () => config_value_span.value,
      set: (val) => {
        config_value_span.value = val;
      },
    });
  }
}

// These objects will contain the default value

// This code updates the image options in the PLOT config with the provided ones
function setImageOptions(o) {
  for (const [key, container] of Object.entries(config_spans)) {
    container.config_value = o[key];
  }
}
function unsetImageOptions() {
  setImageOptions({});
}

const set_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.set");
const unset_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.unset");
if (firstRun) {
  set_button.onclick = (e) => {
    for (const container of Object.values(config_spans)) {
      container.config_value = container.ui_value;
    }
  };
  unset_button.onclick = unsetImageOptions;
}

// We add a function to check if the clipboard is popped out
CONTAINER.isPoppedOut = () => {
  return CONTAINER.classList.contains("popped-out");
};

CLIPBOARD_HEADER.onmousedown = function (event) {
  if (event.target.matches("span.clipboard-value")) {
    console.log("We don't move!");
    return;
  }
  const start = {
    left: parseFloat(CONTAINER.style.left),
    top: parseFloat(CONTAINER.style.top),
    X: event.pageX,
    Y: event.pageY,
  };
  function moveAt(event, start) {
    const top = event.pageY - start.Y + start.top + "px";
    const left = event.pageX - start.X + start.left + "px";
    CLIPBOARD_HEADER.style.left = left;
    CONTAINER.style.left = left;
    CONTAINER.style.top = top;
  }

  // move our absolutely positioned ball under the pointer
  moveAt(event, start);
  function onMouseMove(event) {
    moveAt(event, start);
  }

  // We use this to remove the mousemove when clicking outside of the container
  const controller = new AbortController();

  // move the container on mousemove
  document.addEventListener("mousemove", onMouseMove, {
    signal: controller.signal,
  });
  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        cleanUp();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );

  function cleanUp() {
    console.log("cleaning up the plot move listener");
    controller.abort();
    CLIPBOARD_HEADER.onmouseup = null;
  }

  // (3) drop the ball, remove unneeded handlers
  CLIPBOARD_HEADER.onmouseup = cleanUp;
};

function sendToClipboard(blob) {
  if (!navigator.clipboard) {
    alert(
      "The Clipboard API does not seem to be available, make sure the Pluto notebook is being used from either localhost or an https source."
    );
  }
  navigator.clipboard
    .write([
      new ClipboardItem({
        // The key is determined dynamically based on the blob's type.
        [blob.type]: blob,
      }),
    ])
    .then(
      function () {
        console.log("Async: Copying to clipboard was successful!");
      },
      function (err) {
        console.error("Async: Could not copy text: ", err);
      }
    );
}

function copyImageToClipboard() {
  // We extract the image options from the provided parameters (if they exist)
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key. We also ignore format because the clipboard only supports png.
    if (val === undefined || key === "format") {
      continue;
    }
    config[key] = val;
  }
  Plotly.toImage(PLOT, config).then(function (dataUrl) {
    fetch(dataUrl)
      .then((res) => res.blob())
      .then((blob) => {
        const paste_receiver = document.querySelector('paste-receiver.plutoplotly')
        if (paste_receiver) {
          paste_receiver.attachImage(dataUrl, CONTAINER)
        }
        sendToClipboard(blob)
      });
  });
}

function saveImageToFile() {
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key.
    if (val === undefined) {
      continue;
    }
    config[key] = val;
  }
  Plotly.downloadImage(PLOT, config);
}

let container_rect = { width: 0, height: 0, top: 0, left: 0 };
function unpop_container(cl) {
  CONTAINER.classList.toggle("popped-out", false);
  CONTAINER.classList.toggle(cl, false);
  // We fix the height back to the value it had before popout, also setting the flag to signal that upon first resize we remove the fixed inline-style
  CONTAINER.style.height = container_rect.height + "px";
  remove_container_size = true;
  // We set the other fixed inline-styles to null
  CONTAINER.style.width = "";
  CONTAINER.style.top = "";
  CONTAINER.style.left = "";
  // We also remove the CLIPBOARD_HEADER
  CLIPBOARD_HEADER.style.width = "";
  CLIPBOARD_HEADER.style.left = "";
  // Finally we remove the hidden class to the header
  CLIPBOARD_HEADER.classList.toggle("hidden", true);
  return;
}
function popout_container(opts) {
  const cl = opts?.cl;
  const target_container_size = opts?.target_container_size ?? {};
  const target_plot_size = opts?.target_plot_size ?? {};
  if (CONTAINER.isPoppedOut()) {
    return unpop_container(cl);
  }
  CONTAINER.classList.toggle(cl, cl === undefined ? false : true);
  // We extract the current size of the container, save them and fix them
  const { width, height, top, left } = CONTAINER.getBoundingClientRect();
  container_rect = { width, height, top, left };
  // We save the current plot size before we pop as it will fill the screen
  const current_plot_size = {
    width: PLOT._fullLayout.width,
    height: PLOT._fullLayout.height,
  };
  // We have to save the pad data before popping so we can resize precisely
  const pad = {};
  pad.unpopped = getSizeData().container_pad;
  CONTAINER.classList.toggle("popped-out", true);
  pad.popped = getSizeData().container_pad;
  // We do top and left based on the current rect
  for (const key of ["top", "left"]) {
    const start_val = target_container_size[key] ?? container_rect[key];
    let offset = 0;
    for (const kind of ["padding", "border"]) {
      offset += pad.popped[kind][key] - pad.unpopped[kind][key];
    }
    CONTAINER.style[key] = start_val - offset + "px";
    if (key === "left") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  // We compute the width and height depending on eventual config data
  const csz = computeContainerSize({
    width:
      target_plot_size.width ??
      config_spans.width.config_value ??
      current_plot_size.width,
    height:
      target_plot_size.height ??
      config_spans.height.config_value ??
      current_plot_size.height,
  });
  for (const key of ["width", "height"]) {
    const val = target_container_size[key] ?? csz[key];
    CONTAINER.style[key] = val + "px";
    if (key === "width") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  CLIPBOARD_HEADER.classList.toggle("hidden", false);
  const controller = new AbortController();

  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        unpop_container();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );
}

CONTAINER.popOut = popout_container;

function DualClick(single_func, dbl_func) {
  let nclicks = 0;
  return function (...args) {
    nclicks += 1;
    if (nclicks > 1) {
      dbl_func(...args);
      nclicks = 0;
    } else {
      delay(300).then(() => {
        if (nclicks == 1) {
          single_func(...args);
        }
        nclicks = 0;
      });
    }
  };
}

// We remove the default download image button
plot_obj.config.modeBarButtonsToRemove = _.union(
  plot_obj.config.modeBarButtonsToRemove,
  ["toImage"]
);
// We add the custom button to the modebar
plot_obj.config.modeBarButtonsToAdd = _.union(
  plot_obj.config.modeBarButtonsToAdd,
  [
    {
      name: "Copy PNG to Clipboard",
      icon: {
        height: 520,
        width: 520,
        path: "M280 64h40c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128C0 92.7 28.7 64 64 64h40 9.6C121 27.5 153.3 0 192 0s71 27.5 78.4 64H280zM64 112c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16H320c8.8 0 16-7.2 16-16V128c0-8.8-7.2-16-16-16H304v24c0 13.3-10.7 24-24 24H192 104c-13.3 0-24-10.7-24-24V112H64zm128-8a24 24 0 1 0 0-48 24 24 0 1 0 0 48z",
      },
      direction: "up",
      click: DualClick(copyImageToClipboard, () => {
        popout_container();
      }),
    },
    {
      name: "Download Image",
      icon: Plotly.Icons.camera,
      direction: "up",
      click: DualClick(saveImageToFile, () => {
        popout_container({ cl: "filesave" });
      }),
    },
  ]
);

function getOffsetData(el) {
  let cs = window.getComputedStyle(el, null);
  const odata = {
    padding: {
      left: parseFloat(cs.paddingLeft),
      right: parseFloat(cs.paddingRight),
      top: parseFloat(cs.paddingTop),
      bottom: parseFloat(cs.paddingBottom),
      width: parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight),
      height: parseFloat(cs.paddingTop) + parseFloat(cs.paddingBottom),
    },
    border: {
      left: parseFloat(cs.borderLeftWidth),
      right: parseFloat(cs.borderRightWidth),
      top: parseFloat(cs.borderTopWidth),
      bottom: parseFloat(cs.borderBottomWidth),
      width: parseFloat(cs.borderLeftWidth) + parseFloat(cs.borderRightWidth),
      height: parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth),
    }
  };
  if (el === PLOT) {
    // For the PLOT we also want to take into account the offset
    odata.offset = {
      top: PLOT.offsetParent == CONTAINER ? PLOT.offsetTop : 0,
      left: PLOT.offsetParent == CONTAINER ? PLOT.offsetLeft : 0,
    }
  }
  return odata;
}
function getSizeData() {
  const data = {
    plot_pad: getOffsetData(PLOT),
    plot_rect: PLOT.getBoundingClientRect(),
    container_pad: getOffsetData(CONTAINER),
    container_rect: CONTAINER.getBoundingClientRect(),
  };
  return data;
}
function computeContainerSize({ width, height }, sizeData = getSizeData()) {
  const computed_size = computePlotSize(sizeData);
  const offsets = computed_size.offsets;

  const plot_data = {
    width: width ?? computed_size.width,
    height: height ?? computed_size.height,
  };

  return {
    width: (width ?? computed_size.width) + offsets.width,
    height: (height ?? computed_size.height) + offsets.height,
    noChange: width == computed_size.width && height == computed_size.height,
  }
}

// This function will change the container size so that the resulting plot will be matching the provided specs
function changeContainerSize({ width, height }, sizeData = getSizeData()) {
  if (!CONTAINER.isPoppedOut()) {
    console.log("Tried to change container size when not popped, ignoring");
    return;
  }

  const csz = computeContainerSize({ width, height }, sizeData);

  if (csz.noChange) {
    console.log("Size is the same as current, ignoring");
    return
  }
  // We are now going to set he width and height of the container
  for (const key of ["width", "height"]) {
    CONTAINER.style[key] = csz[key] + "px";
  }
}
// We now create the function that will update the plot based on the values specified
function updateFromHeader() {
  const header_data = {
    height: config_spans.height.ui_value,
    width: config_spans.width.ui_value,
  };
  changeContainerSize(header_data);
}
// We assign this function to the onblur event of width and height
if (firstRun) {
  for (const container of Object.values(config_spans)) {
    container.ui_span.onblur = (e) => {
      container.ui_value = container.ui_span.textContent;
      updateFromHeader();
    };
  }
}
// This function computes the plot size to use for relayout as a function of the container size
function computePlotSize(data = getSizeData()) {
  // Remove Padding
  const { container_pad, plot_pad, container_rect } = data;
  const offsets = {
    width:
      plot_pad.padding.width +
      plot_pad.border.width +
      plot_pad.offset.left +
      container_pad.padding.width +
      container_pad.border.width,
    height:
      plot_pad.padding.height +
      plot_pad.border.height +
      plot_pad.offset.top +
      container_pad.padding.height +
      container_pad.border.height,
  };
  const sz = {
    width: Math.round(container_rect.width - offsets.width),
    height: Math.round(container_rect.height - offsets.height),
    offsets,
  };
  return sz;
}

// Create the resizeObserver to make the plot even more responsive! :magic:
const resizeObserver = new ResizeObserver((entries) => {
  const sizeData = getSizeData();
  const {container_rect, container_pad} = sizeData;
  let plot_size = computePlotSize(sizeData);
  // We save the height in the PLOT object
  PLOT.container_height = container_rect.height;
  // We deal with some stuff if the container is poppped
  CLIPBOARD_HEADER.style.width = container_rect.width + "px";
  CLIPBOARD_HEADER.style.left = container_rect.left + "px";
  config_spans.height.ui_value = plot_size.height;
  config_spans.width.ui_value = plot_size.width;
  /* 
		The addition of the invalid argument `plutoresize` seems to fix the problem with calling `relayout` simply with `{autosize: true}` as update breaking mouse relayout events tracking. 
		See https://github.com/plotly/plotly.js/issues/6156 for details
		*/
  let config = {
    // If this is popped out, we ignore the original width/height
    width: (CONTAINER.isPoppedOut() ? undefined : original_width) ?? plot_size.width,
    height: (CONTAINER.isPoppedOut() ? undefined : original_height) ?? plot_size.height,
    plutoresize: true,
  };
  Plotly.relayout(PLOT, config).then(() => {
    if (remove_container_size && !CONTAINER.isPoppedOut()) {
      // This is needed to avoid the first resize upon plot creation to already be without a fixed height
      CONTAINER.style.height = "";
      CONTAINER.style.width = "";
      remove_container_size = false;
    }
  });
});

resizeObserver.observe(CONTAINER);


Plotly.react(PLOT, plot_obj).then(() => {
	// Assign the Plotly event listeners
	for (const [key, listener_vec] of Object.entries(plotly_listeners)) {
		for (const listener of listener_vec) {
			PLOT.on(key, listener)
		}
	}
	// Assign the JS event listeners
	for (const [key, listener_vec] of Object.entries(js_listeners)) {
		for (const listener of listener_vec) {
			PLOT.addEventListener(key, listener, {
				signal: controller.signal
			})
		}
	}
}
)


invalidation.then(() => {
	// Remove all plotly listeners
	PLOT.removeAllListeners()
	// Remove all JS listeners
	controller.abort()
	// Remove the resizeObserver
	resizeObserver.disconnect()
})



		return CONTAINER
	</script>

</div>mimetext/htmlrootassigneelast_run_timestampA+̟opersist_js_state·has_pluto_hook_features§cell_id$9ca72278-fff6-4b0f-b72c-e0d3768aff73depends_on_disabled_cells§runtime΃.published_object_keys5c6e0de0c-3901-11f0-234e-bd09c571f662/58d51ac87604fe9cdepends_on_skipped_cells§errored$020131a1-c68b-403a-9c5e-944edb6220e9queued¤logsrunning¦outputbody-updatevalue (generic function with 2 methods)mimetext/plainrootassigneelast_run_timestampA)aspersist_js_state·has_pluto_hook_features§cell_id$020131a1-c68b-403a-9c5e-944edb6220e9depends_on_disabled_cells§runtime 	 published_object_keysdepends_on_skipped_cells§errored$c23475f0-c5f0-49ce-a665-f93c8bda0474queued¤logsrunning¦outputbody3make_blackjack_mdp (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA%spersist_js_state·has_pluto_hook_features§cell_id$c23475f0-c5f0-49ce-a665-f93c8bda0474depends_on_disabled_cells§runtime 4|published_object_keysdepends_on_skipped_cells§errored$15925cc6-9605-4357-9c2a-cdfe54070989queued¤logsrunning¦outputbody	<div class="markdown"><p>Consider an implementation or ordinary importance sampling that updates <span class="tex">$V&#40;s&#41;$</span> incrementally every time a <span class="tex">$G$</span> value is observed for that state.  The equations should be similar to the incremental update rule previously derived for <span class="tex">$V&#40;s&#41;$</span> without importance sampling.</p>
<p>Consider a sequence of returns <span class="tex">$G_1, G_2, \dots , G_&#123;n-1&#125;$</span>, all starting in the same state and each with a corresponding weight <span class="tex">$W_i &#61; \rho_&#123;t_i:T&#40;t_i&#41;-1&#125;$</span>.  We wish to form the estimate</p>
<p class="tex">$$V_n \dot&#61; \frac&#123;\sum_&#123;k&#61;1&#125;^&#123;n-1&#125;W_k G_k&#125;&#123;n-1&#125;, n \geq 2$$</p>
<p>and keep it up-to-date as we obtain a single additional return <span class="tex">$G_n$</span>.  Observe that we can increment n by 1 to get an espression for V in terms of itself.</p>
<p class="tex">$$V_&#123;n&#43;1&#125; &#61; \frac&#123;\sum_&#123;k&#61;1&#125;^n W_k G_k&#125;&#123;n&#125; &#61; \frac&#123;W_n G_n &#43; \sum_&#123;k&#61;1&#125;^&#123;n-1&#125; W_k G_k&#125;&#123;n&#125;$$</p>
<p>Using the original formula for <span class="tex">$V_n$</span>, we can make the following substitution:</p>
<p class="tex">$$\sum_&#123;k&#61;1&#125;^&#123;n-1&#125; W_k G_k &#61; &#40;n-1&#41;V_n$$</p>
<p>which results in </p>
<p class="tex">$$V_&#123;n&#43;1&#125; &#61; \frac&#123;W_n G_n &#43; V_n &#40;n-1&#41;&#125;&#123;n&#125; &#61; V_n &#43; \frac&#123;W_n G_n - V_n&#125;&#123;n&#125;$$</p>
<p>So, to calculate the value function, we can simply apply the following update rule after obtaining new values for W and G:</p>
<p class="tex">$$C \leftarrow C &#43; 1$$</p>
<p class="tex">$$V \leftarrow V &#43; \frac&#123;WG-V&#125;&#123;C&#125;$$</p>
<p>which looks very similar to the ordinary average update rule but with the weight multiplied by G.  C just keeps a running total of the times the state was observed.  Note that C needs to be updated even in the case where W is 0 which is not the case for weighted importance sampling.  A similar inremental update rule is derived later for the weighted case as well as an algorithm for updating the action-value estimate using this method.  Below are code examples for calculating the value estimates for both weighted and normal importance sampling using the incremental implementation.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA"'Ѱpersist_js_state·has_pluto_hook_features§cell_id$15925cc6-9605-4357-9c2a-cdfe54070989depends_on_disabled_cells§runtime ̵published_object_keysdepends_on_skipped_cells§errored$be7c096c-cc8c-407b-8287-8fb2ee7150a7queued¤logsrunning¦outputbody<div class="markdown"><blockquote>
<h3><em>Exercise 5.3</em></h3>
<p>What is the backup diagram for Monte Carlo estimation of <span class="tex">$q_\pi$</span></p>
</blockquote>
<p>Similar to the <span class="tex">$v_\pi$</span> diagram except the root is the s,a pair under consideration followed by the new state and the action taken along the trajectory.  The rewards are still accumulated to the end, just the start of the trajectory is a solid filled in circle that would contain the value for that s,a pair.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA"&persist_js_state·has_pluto_hook_features§cell_id$be7c096c-cc8c-407b-8287-8fb2ee7150a7depends_on_disabled_cells§runtime }ӵpublished_object_keysdepends_on_skipped_cells§errored$9618a093-cdb7-4589-a783-de8e9021b705queued¤logsrunning¦outputbodyD<div class="markdown"><h3>Example 5.3: Solving Blackjack</h3>
</div>mimetext/htmlrootassigneelast_run_timestampA"&(persist_js_state·has_pluto_hook_features§cell_id$9618a093-cdb7-4589-a783-de8e9021b705depends_on_disabled_cells§runtime Եpublished_object_keysdepends_on_skipped_cells§errored$fa49c253-e016-46a7-ba94-0e7448a7e0aequeued¤logsrunning¦outputbody|<div class="markdown"><blockquote>
<h3><em>Exercise 5.10</em></h3>
<p>Derive the weighted-average update rule &#40;5.8&#41; from &#40;5.7&#41;.  Follow the pattern of the derivation of the unweighted rule &#40;2.3&#41;.</p>
</blockquote>
<p>Equation &#40;5.7&#41;</p>
<p class="tex">$$V_&#123;n&#125; &#61; \frac&#123;\sum_&#123;k&#61;1&#125;^&#123;n-1&#125; W_k G_k&#125;&#123;\sum_&#123;k&#61;1&#125;^&#123;n-1&#125;W_k&#125; \implies \sum_&#123;k&#61;1&#125;^&#123;n-1&#125; W_k G_k &#61; V_n \sum_&#123;k&#61;1&#125;^&#123;n-1&#125; W_k \tag&#123;a&#125;$$</p>
<p>or </p>
<p class="tex">$$V_&#123;n&#43;1&#125; &#61; \frac&#123;\sum_&#123;k&#61;1&#125;^&#123;n&#125; W_k G_k&#125;&#123;\sum_&#123;k&#61;1&#125;^&#123;n&#125;W_k&#125;$$</p>
<p>now we can expand the expresion for <span class="tex">$V_&#123;n&#43;1&#125;$</span> to get an incremental rule</p>
<p class="tex">$$\begin&#123;flalign&#125;
V_&#123;n&#43;1&#125; &amp;&#61; \frac&#123;W_n G_n &#43; \sum_&#123;k&#61;1&#125;^&#123;n-1&#125; W_k G_k&#125;&#123;\sum_&#123;k&#61;1&#125;^&#123;n&#125;W_k&#125; \\
&amp;&#61; \frac&#123;W_n G_n &#43; V_n \sum_&#123;k&#61;1&#125;^&#123;n-1&#125;W_k&#125;&#123;\sum_&#123;k&#61;1&#125;^&#123;n&#125;W_k&#125; \tag&#123;by &#40;a&#41;&#125; \\
&amp;&#61; \frac&#123;W_n G_n &#43; V_n \sum_&#123;k&#61;1&#125;^&#123;n&#125;W_k - V_n W_n&#125;&#123;\sum_&#123;k&#61;1&#125;^&#123;n&#125;W_k&#125; \\
&amp;&#61; V_n &#43; W_n\frac&#123;G_n - V_n&#125;&#123;\sum_&#123;k&#61;1&#125;^&#123;n&#125;W_k&#125;
\end&#123;flalign&#125;$$</p>
<p>For a fully incremental rule we also have to replace the sum over <span class="tex">$W_k$</span> which can simply be a running total.</p>
<p class="tex">$$C_n &#61; \sum_&#123;k&#61;1&#125;^n W_k$$</p>
<p>the following update rule will produce an equivalent <span class="tex">$C_n$</span> assuming we take <span class="tex">$C_0&#61;0$</span></p>
<p class="tex">$$C_n &#61; C_&#123;n-1&#125; &#43; W_n$$</p>
<p>Now we can rewrite our last expression for <span class="tex">$V_&#123;n&#43;1&#125;$</span></p>
<p class="tex">$$V_&#123;n&#43;1&#125; &#61; V_n &#43; \frac&#123;W_n&#125;&#123;C_n&#125;&#40;G_n - V_n&#41;$$</p>
</div>mimetext/htmlrootassigneelast_run_timestampA")upersist_js_state·has_pluto_hook_features§cell_id$fa49c253-e016-46a7-ba94-0e7448a7e0aedepends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$f41dd3e6-81bf-43e4-afc2-fc549b77f610queued¤logsrunning¦outputbodyelements#9×12875 Matrix{Float32}:
 0.111111  0.00234528   0.0          0.0  0.0  …  0.125  0.111111  0.111111  0.111111
 0.111111  0.0          1.0          0.0  0.0     0.125  0.111111  0.111111  0.111111
 0.111111  2.05737f-20  0.0          0.0  0.0     0.125  0.111111  0.111111  0.111111
 0.111111  0.0          4.02486f-31  0.0  0.0     0.125  0.111111  0.111111  0.111111
 0.111111  5.26108f-25  0.0          0.0  0.2     0.125  0.111111  0.111111  0.111111
 0.111111  0.0106226    0.0          0.0  0.2  …  0.125  0.111111  0.111111  0.111111
 0.111111  0.987032     0.0          1.0  0.2     0.125  0.111111  0.111111  0.111111
 0.111111  0.0          0.0          0.0  0.2     0.125  0.111111  0.111111  0.111111
 0.111111  2.21416f-22  0.0          0.0  0.2     0.0    0.111111  0.111111  0.111111text/plain9×12875 Matrix{Float32}:
 0.0   -30.0   -89.0     -177.0  -167.0  …  0.0  -332.0  0.0   0.0  0.0  0.0  0.0
 0.0   -96.0   -34.0     -144.0  -266.0     0.0  -109.0  0.0   0.0  0.0  0.0  0.0
 0.0   -56.0  -381.0      -60.0  -123.0     0.0  -259.0  0.0   0.0  0.0  0.0  0.0
 0.0  -688.0   -58.2857  -110.0  -341.0     0.0     0.0  0.0   0.0  0.0  0.0  0.0
 0.0   -63.0  -298.0      -89.0     0.0     0.0     0.0  0.0   0.0  0.0  0.0  0.0
 0.0   -29.0  -312.0      -63.0     0.0  …  0.0     0.0  0.0   0.0  0.0  0.0  0.0
 0.0   -26.0   -84.6667    -9.0     0.0     0.0     0.0  0.0   0.0  0.0  0.0  0.0
 0.0  -326.0  -356.0      -91.0     0.0     0.0     0.0  0.0   0.0  0.0  0.0  0.0
 0.0   -59.0  -285.0      -44.0     0.0     0.0     0.0  0.0  -2.0  0.0  0.0  0.0text/plaintypeTupleobjectidb4c794a4eba7a0b5mime!application/vnd.pluto.tree+objectrootassigneelast_run_timestampA3(?persist_js_state·has_pluto_hook_features§cell_id$f41dd3e6-81bf-43e4-afc2-fc549b77f610depends_on_disabled_cells§runtimeppublished_object_keysdepends_on_skipped_cells§errored$6d765229-2816-4abb-a868-6be919a96530queued¤logsrunning¦outputbodyprefix[MDP_Opaque{BlackjackState, BlackjackAction, var"#blackjackepisode#19", var"#state_init#18"}elementsstatesprefix$Main.var"workspace#3".BlackjackStateelementsprefixBlackjackStateelementssum12text/plainupcard1text/plainuatruetext/plaintypestructprefix_shortBlackjackStateobjectidb87ee777eeec7796!application/vnd.pluto.tree+objectprefixBlackjackStateelementssum12text/plainupcard1text/plainuafalsetext/plaintypestructprefix_shortBlackjackStateobjectid9f1fbc9e814da979!application/vnd.pluto.tree+objectprefixBlackjackStateelementssum12text/plainupcard2text/plainuatruetext/plaintypestructprefix_shortBlackjackStateobjectide2da203ac0f66b10!application/vnd.pluto.tree+objectprefixBlackjackStateelementssum12text/plainupcard2text/plainuafalsetext/plaintypestructprefix_shortBlackjackStateobjectidd4197f3fbf671862!application/vnd.pluto.tree+objectprefixBlackjackStateelementssum12text/plainupcard3text/plainuatruetext/plaintypestructprefix_shortBlackjackStateobjectidc8a811afca9e5748!application/vnd.pluto.tree+objectprefixBlackjackStateelementssum12text/plainupcard3text/plainuafalsetext/plaintypestructprefix_shortBlackjackStateobjectidbbd574ae4196bf55!application/vnd.pluto.tree+objectprefixBlackjackStateelementssum12text/plainupcard4text/plainuatruetext/plaintypestructprefix_shortBlackjackStateobjectidcc503f48c1f0713f!application/vnd.pluto.tree+objectprefixBlackjackStateelementssum12text/plainupcard4text/plainuafalsetext/plaintypestructprefix_shortBlackjackStateobjectid25bb4ebe5d2823d6!application/vnd.pluto.tree+object	prefixBlackjackStateelementssum12text/plainupcard5text/plainuatruetext/plaintypestructprefix_shortBlackjackStateobjectid6bc1a41868c39279!application/vnd.pluto.tree+objectmoreȒprefixBlackjackStateelementssum21text/plainupcard10text/plainuafalsetext/plaintypestructprefix_shortBlackjackStateobjectide3281242af43beb1!application/vnd.pluto.tree+objecttypeArrayprefix_shortobjectid46c688b409ef73b3!application/vnd.pluto.tree+objectstatelookupprefix1Dict{Main.var"workspace#3".BlackjackState, Int64}elementsprefixBlackjackStateelementssum12text/plainupcard1text/plainuafalsetext/plaintypestructprefix_shortBlackjackStateobjectid9f1fbc9e814da979!application/vnd.pluto.tree+object2text/plainprefixBlackjackStateelementssum19text/plainupcard2text/plainuatruetext/plaintypestructprefix_shortBlackjackStateobjectid69f09af6603ebcff!application/vnd.pluto.tree+object143text/plainprefixBlackjackStateelementssum12text/plainupcard7text/plainuafalsetext/plaintypestructprefix_shortBlackjackStateobjectid7cd9112ddd4454cd!application/vnd.pluto.tree+object14text/plainprefixBlackjackStateelementssum20text/plainupcard3text/plainuafalsetext/plaintypestructprefix_shortBlackjackStateobjectidaf49fd3134dee8e1!application/vnd.pluto.tree+object166text/plainprefixBlackjackStateelementssum16text/plainupcard8text/plainuafalsetext/plaintypestructprefix_shortBlackjackStateobjectidce13a84aa34e8895!application/vnd.pluto.tree+object96text/plainprefixBlackjackStateelementssum17text/plainupcard1text/plainuafalsetext/plaintypestructprefix_shortBlackjackStateobjectidfb60f06e2a8949fb!application/vnd.pluto.tree+object102text/plainprefixBlackjackStateelementssum13text/plainupcard8text/plainuafalsetext/plaintypestructprefix_shortBlackjackStateobjectidcb2a499a38978337!application/vnd.pluto.tree+object36text/plainprefixBlackjackStateelementssum14text/plainupcard3text/plainuafalsetext/plaintypestructprefix_shortBlackjackStateobjectid1f4c401d4d952b98!application/vnd.pluto.tree+object46text/plainprefixBlackjackStateelementssum21text/plainupcard9text/plainuafalsetext/plaintypestructprefix_shortBlackjackStateobjectid9136839ae4cc5aa8!application/vnd.pluto.tree+object198text/plainprefixBlackjackStateelementssum13text/plainupcard5text/plainuafalsetext/plaintypestructprefix_shortBlackjackStateobjectid16c31c16d6e9163c!application/vnd.pluto.tree+object30text/plainmoretypeDictprefix_shortDictobjectidd6e65cd5f69af451!application/vnd.pluto.tree+objectactionsprefix%Main.var"workspace#3".BlackjackActionelementsprefixHitelementstypestructprefix_shortHitobjectidffffffff8d1925f5!application/vnd.pluto.tree+objectprefixStickelementstypestructprefix_shortStickobjectidffffffff94fa44e5!application/vnd.pluto.tree+objecttypeArrayprefix_shortobjectideeef370a95fddb26!application/vnd.pluto.tree+objectactionlookupprefix2Dict{Main.var"workspace#3".BlackjackAction, Int64}elementsprefixStickelementstypestructprefix_shortStickobjectidffffffff94fa44e5!application/vnd.pluto.tree+object2text/plainprefixHitelementstypestructprefix_shortHitobjectidffffffff8d1925f5!application/vnd.pluto.tree+object1text/plaintypeDictprefix_shortDictobjectid7dff6031b670ac66!application/vnd.pluto.tree+objectstate_initN(::Main.var"workspace#3".var"#state_init#18") (generic function with 1 method)text/plainsimulatorT(::Main.var"workspace#3".var"#blackjackepisode#19") (generic function with 1 method)text/plaintypestructprefix_shortMDP_Opaqueobjectid8084d455b072a9b0mime!application/vnd.pluto.tree+objectrootassigneeconst blackjack_mdplast_run_timestampA%persist_js_state·has_pluto_hook_features§cell_id$6d765229-2816-4abb-a868-6be919a96530depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cells§errored$e7de31e8-ae95-4616-86a9-a115a5e24330queued¤logsrunning¦outputbodyprefixMDP_Opaque{@NamedTuple{position::Tuple{Int64, Int64}, velocity::Tuple{Int64, Int64}}, Tuple{Int64, Int64}, var"#simulator#140"{Float64, @NamedTuple{start::Set{Tuple{Int64, Int64}}, finish::Set{Tuple{Int64, Int64}}, body::Set{Tuple{Int64, Int64}}}, var"#take_action#139"{Dict{@NamedTuple{position::Tuple{Int64, Int64}, velocity::Tuple{Int64, Int64}}, Int64}}}, var"#state_init#138"{@NamedTuple{start::Set{Tuple{Int64, Int64}}, finish::Set{Tuple{Int64, Int64}}, body::Set{Tuple{Int64, Int64}}}}}elementsstatesprefixI@NamedTuple{position::Tuple{Int64, Int64}, velocity::Tuple{Int64, Int64}}elementselementspositionelements18text/plain16text/plaintypeTupleobjectidaeb6f295858259db!application/vnd.pluto.tree+objectvelocityelements0text/plain0text/plaintypeTupleobjectid9b52efd7a2a08bd5!application/vnd.pluto.tree+objecttypeNamedTupleobjectid6696fcabed9a1a6f!application/vnd.pluto.tree+objectelementspositionelements18text/plain16text/plaintypeTupleobjectidaeb6f295858259db!application/vnd.pluto.tree+objectvelocityelements0text/plain1text/plaintypeTupleobjectid86128cc9b5ae8f4a!application/vnd.pluto.tree+objecttypeNamedTupleobjectidba4e8247f8683be!application/vnd.pluto.tree+objectelementspositionelements18text/plain16text/plaintypeTupleobjectidaeb6f295858259db!application/vnd.pluto.tree+objectvelocityelements0text/plain2text/plaintypeTupleobjectidfc41ae7a664555b0!application/vnd.pluto.tree+objecttypeNamedTupleobjectid8b8fb6d35b83f08e!application/vnd.pluto.tree+objectelementspositionelements18text/plain16text/plaintypeTupleobjectidaeb6f295858259db!application/vnd.pluto.tree+objectvelocityelements0text/plain3text/plaintypeTupleobjectid5a8d0f981b76571a!application/vnd.pluto.tree+objecttypeNamedTupleobjectid922bf9ffd7dc2354!application/vnd.pluto.tree+objectelementspositionelements18text/plain16text/plaintypeTupleobjectidaeb6f295858259db!application/vnd.pluto.tree+objectvelocityelements0text/plain4text/plaintypeTupleobjectid6ac4b5902680c6bb!application/vnd.pluto.tree+objecttypeNamedTupleobjectid7d5c2d6eb80fafa3!application/vnd.pluto.tree+objectelementspositionelements18text/plain16text/plaintypeTupleobjectidaeb6f295858259db!application/vnd.pluto.tree+objectvelocityelements1text/plain0text/plaintypeTupleobjectid1539b04621ff8c7d!application/vnd.pluto.tree+objecttypeNamedTupleobjectid67049892921af984!application/vnd.pluto.tree+objectelementspositionelements18text/plain16text/plaintypeTupleobjectidaeb6f295858259db!application/vnd.pluto.tree+objectvelocityelements1text/plain1text/plaintypeTupleobjectid78e123e4f427692a!application/vnd.pluto.tree+objecttypeNamedTupleobjectid5edf932a0cdf0393!application/vnd.pluto.tree+objectelementspositionelements18text/plain16text/plaintypeTupleobjectidaeb6f295858259db!application/vnd.pluto.tree+objectvelocityelements1text/plain2text/plaintypeTupleobjectide3e6b1884080a98d!application/vnd.pluto.tree+objecttypeNamedTupleobjectid4efbccd93bf6d74f!application/vnd.pluto.tree+object	elementspositionelements18text/plain16text/plaintypeTupleobjectidaeb6f295858259db!application/vnd.pluto.tree+objectvelocityelements1text/plain3text/plaintypeTupleobjectid7d75a9159c58bddf!application/vnd.pluto.tree+objecttypeNamedTupleobjectid4953a4eb18088909!application/vnd.pluto.tree+objectmore2Kelementspositionelements23text/plain27text/plaintypeTupleobjectidda74d5c39ad37f7d!application/vnd.pluto.tree+objectvelocityelements4text/plain4text/plaintypeTupleobjectida7048b0d6f799239!application/vnd.pluto.tree+objecttypeNamedTupleobjectid370c8cd9f01597e7!application/vnd.pluto.tree+objecttypeArrayprefix_shortobjectid2177c00eb2e7467c!application/vnd.pluto.tree+objectstatelookupprefixVDict{@NamedTuple{position::Tuple{Int64, Int64}, velocity::Tuple{Int64, Int64}}, Int64}elementselementspositionelements22text/plain28text/plaintypeTupleobjectidcbfc5affbbf7435!application/vnd.pluto.tree+objectvelocityelements1text/plain1text/plaintypeTupleobjectid78e123e4f427692a!application/vnd.pluto.tree+objecttypeNamedTupleobjectide4bf0cf747d0ff6c!application/vnd.pluto.tree+object57text/plainelementspositionelements28text/plain24text/plaintypeTupleobjectid20a1ce308f12ceac!application/vnd.pluto.tree+objectvelocityelements1text/plain1text/plaintypeTupleobjectid78e123e4f427692a!application/vnd.pluto.tree+objecttypeNamedTupleobjectid7e55961854356963!application/vnd.pluto.tree+object82text/plainelementspositionelements23text/plain24text/plaintypeTupleobjectid544e9e193cf19bfb!application/vnd.pluto.tree+objectvelocityelements4text/plain0text/plaintypeTupleobjectidc772df2bb869c6b4!application/vnd.pluto.tree+objecttypeNamedTupleobjectidc4c4abfe7b05c49d!application/vnd.pluto.tree+object10246text/plainelementspositionelements5text/plain2text/plaintypeTupleobjectidb43f250e13820c5d!application/vnd.pluto.tree+objectvelocityelements0text/plain2text/plaintypeTupleobjectidfc41ae7a664555b0!application/vnd.pluto.tree+objecttypeNamedTupleobjectid8140d1c434ea8616!application/vnd.pluto.tree+object2428text/plainelementspositionelements13text/plain4text/plaintypeTupleobjectidf9849fc4d6ed0a4b!application/vnd.pluto.tree+objectvelocityelements2text/plain4text/plaintypeTupleobjectidfe67fb157b710308!application/vnd.pluto.tree+objecttypeNamedTupleobjectidfb8bac14b00f0c1a!application/vnd.pluto.tree+object9390text/plainelementspositionelements16text/plain16text/plaintypeTupleobjectid3164689f12bc7404!application/vnd.pluto.tree+objectvelocityelements1text/plain1text/plaintypeTupleobjectid78e123e4f427692a!application/vnd.pluto.tree+objecttypeNamedTupleobjectid805c6e6b623dc37f!application/vnd.pluto.tree+object157text/plainelementspositionelements11text/plain8text/plaintypeTupleobjectid9b2ceef039544350!application/vnd.pluto.tree+objectvelocityelements4text/plain4text/plaintypeTupleobjectida7048b0d6f799239!application/vnd.pluto.tree+objecttypeNamedTupleobjectid2e4a05a6c93c1820!application/vnd.pluto.tree+object3525text/plainelementspositionelements6text/plain2text/plaintypeTupleobjectid4d2c7a74e69c74a3!application/vnd.pluto.tree+objectvelocityelements2text/plain2text/plaintypeTupleobjectid74f4975686c560b8!application/vnd.pluto.tree+objecttypeNamedTupleobjectidce6c6a5f7f145ad0!application/vnd.pluto.tree+object6213text/plainelementspositionelements18text/plain15text/plaintypeTupleobjectidf416ee491fa413be!application/vnd.pluto.tree+objectvelocityelements1text/plain3text/plaintypeTupleobjectid7d75a9159c58bddf!application/vnd.pluto.tree+objecttypeNamedTupleobjectidba1a83d36318f0ea!application/vnd.pluto.tree+object9434text/plainelementspositionelements3text/plain2text/plaintypeTupleobjectidc1258421771ca213!application/vnd.pluto.tree+objectvelocityelements4text/plain1text/plaintypeTupleobjectidab958923df88f7e9!application/vnd.pluto.tree+objecttypeNamedTupleobjectide0a57c37bcb0dd81!application/vnd.pluto.tree+object11772text/plainmoretypeDictprefix_shortDictobjectid4c3cc9fe0afa45e6!application/vnd.pluto.tree+objectactionsprefixTuple{Int64, Int64}elementselements-1text/plain-1text/plaintypeTupleobjectida5f5003e88013c47!application/vnd.pluto.tree+objectelements-1text/plain0text/plaintypeTupleobjectid29547c053cf46d53!application/vnd.pluto.tree+objectelements-1text/plain1text/plaintypeTupleobjectidd7f044f2876f60ea!application/vnd.pluto.tree+objectelements0text/plain-1text/plaintypeTupleobjectid4b2797d2a8e67906!application/vnd.pluto.tree+objectelements0text/plain0text/plaintypeTupleobjectid9b52efd7a2a08bd5!application/vnd.pluto.tree+objectelements0text/plain1text/plaintypeTupleobjectid86128cc9b5ae8f4a!application/vnd.pluto.tree+objectelements1text/plain-1text/plaintypeTupleobjectid467534c86eaf64c9!application/vnd.pluto.tree+objectelements1text/plain0text/plaintypeTupleobjectid1539b04621ff8c7d!application/vnd.pluto.tree+object	elements1text/plain1text/plaintypeTupleobjectid78e123e4f427692a!application/vnd.pluto.tree+objecttypeArrayprefix_shortobjectidd05a5360a94e8964!application/vnd.pluto.tree+objectactionlookupprefix Dict{Tuple{Int64, Int64}, Int64}elementselements0text/plain0text/plaintypeTupleobjectid9b52efd7a2a08bd5!application/vnd.pluto.tree+object5text/plainelements1text/plain-1text/plaintypeTupleobjectid467534c86eaf64c9!application/vnd.pluto.tree+object7text/plainelements-1text/plain0text/plaintypeTupleobjectid29547c053cf46d53!application/vnd.pluto.tree+object2text/plainelements0text/plain-1text/plaintypeTupleobjectid4b2797d2a8e67906!application/vnd.pluto.tree+object4text/plainelements0text/plain1text/plaintypeTupleobjectid86128cc9b5ae8f4a!application/vnd.pluto.tree+object6text/plainelements1text/plain1text/plaintypeTupleobjectid78e123e4f427692a!application/vnd.pluto.tree+object9text/plainelements-1text/plain-1text/plaintypeTupleobjectida5f5003e88013c47!application/vnd.pluto.tree+object1text/plainelements-1text/plain1text/plaintypeTupleobjectidd7f044f2876f60ea!application/vnd.pluto.tree+object3text/plainelements1text/plain0text/plaintypeTupleobjectid1539b04621ff8c7d!application/vnd.pluto.tree+object8text/plaintypeDictprefix_shortDictobjectid641a4541bab53459!application/vnd.pluto.tree+objectstate_initٿ(::Main.var"workspace#3".var"#state_init#138"{@NamedTuple{start::Set{Tuple{Int64, Int64}}, finish::Set{Tuple{Int64, Int64}}, body::Set{Tuple{Int64, Int64}}}}) (generic function with 1 method)text/plainsimulatorL(::Main.var"workspace#3".var"#simulator#140"{Float64, @NamedTuple{start::Set{Tuple{Int64, Int64}}, finish::Set{Tuple{Int64, Int64}}, body::Set{Tuple{Int64, Int64}}}, Main.var"workspace#3".var"#take_action#139"{Dict{@NamedTuple{position::Tuple{Int64, Int64}, velocity::Tuple{Int64, Int64}}, Int64}}}) (generic function with 1 method)text/plaintypestructprefix_shortMDP_Opaqueobjectidfe3759ed2536a85amime!application/vnd.pluto.tree+objectrootassigneeconst track2_mdplast_run_timestampA/Hpersist_js_state·has_pluto_hook_features§cell_id$e7de31e8-ae95-4616-86a9-a115a5e24330depends_on_disabled_cells§runtime Qpublished_object_keysdepends_on_skipped_cells§errored$fff54c56-5afe-4d89-9dc5-502d08c89de9queued¤logsrunning¦outputbody-make_col_set (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA/Xհpersist_js_state·has_pluto_hook_features§cell_id$fff54c56-5afe-4d89-9dc5-502d08c89de9depends_on_disabled_cells§runtime hpublished_object_keysdepends_on_skipped_cells§errored$9793b5c9-d4ec-492d-a72d-8737bb65c8a5queued¤logsrunning¦outputbody<div class="markdown"><p>Given a starting state <span class="tex">$S_t$</span>, the probability of the subsequent state-action trajectory, <span class="tex">$A_t, S_&#123;t&#43;1&#125;, A_&#123;t&#43;1&#125;, \ldots ,S_T$</span>, occuring under any policy <span class="tex">$\pi$</span> is:</p>
<p class="tex">$$Pr_&#123;\pi&#125;\&#123;\mathcal&#123;traj&#125;\&#125; &#61; \prod_&#123;k&#61;t&#125;^&#123;T-1&#125; \pi&#40;A_k|S_k&#41;p&#40;S_&#123;k&#43;1&#125;|S_k, A_k&#41;$$</p>
<p>where <span class="tex">$p$</span> here is the state-transition probability function defined by &#40;3.4&#41;.  Thus, the relative probability of the trajectory under the target and behavior policies &#40;the importance-sampling ratio&#41; is</p>
<p class="tex">$$\rho_&#123;t:T-1&#125; \dot&#61; \prod_&#123;k&#61;t&#125;^&#123;T-1&#125;\frac&#123;\pi&#40;A_k|S_k&#41;&#125;&#123;b&#40;A_k|S_k&#41;&#125;$$</p>
<p>To estimate <span class="tex">$v_\pi&#40;s&#41;$</span>, we simply scale the returns by the ratios and average the results:</p>
<p class="tex">$$V&#40;s&#41; \dot&#61; \frac&#123;\sum_&#123;t \in \mathscr&#123;T&#125;&#40;s&#41;&#125; \rho_&#123;t:T&#40;t&#41;-1&#125;G_t&#125;&#123;|\mathscr&#123;T&#125;&#40;s&#41;|&#125;$$</p>
<p>When importance sampling is done as a simple average in this way it is called <em>ordinary importance sampling</em>.</p>
<p>An important alternative is <em>weighted importance sampling</em>, which uses a <em>weighted</em> average, defined as</p>
<p class="tex">$$V&#40;s&#41; \dot&#61; \frac&#123;\sum_&#123;t \in \mathscr&#123;T&#125;&#40;s&#41;&#125; \rho_&#123;t:T&#40;t&#41;-1&#125;G_t&#125;&#123;\sum_&#123;t \in \mathscr&#123;T&#125;&#40;s&#41;&#125; \rho_&#123;t:T&#40;t&#41;-1&#125;&#125;$$</p>
<p>, or zero is the denominator is zero.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA"')persist_js_state·has_pluto_hook_features§cell_id$9793b5c9-d4ec-492d-a72d-8737bb65c8a5depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$1117e6c3-2736-46a4-bac2-d3c99c1998b6queued¤logsrunning¦outputbody<bond def="mcϵs2" unique_id="un/mE9EAmSHf"><span style='display: contents;'>
	<span style='display: contents;'><div class="markdown"><table><tr><th align="center">Number of Episodes</th><th align="center">ϵ</th><th align="center">Decay ϵ</th></tr><tr><td align="center"><pl-combined-child key='rhymrreksi' style='display: contents;'><input type='number' min='1' step='1' max='10000000' value='1000'></pl-combined-child></td><td align="center"><pl-combined-child key='rhymrreksi' style='display: contents;'><input type='number' min='0.001' step='0.001' max='1.0' value='0.01'></pl-combined-child></td><td align="center"><pl-combined-child key='rhymrreksi' style='display: contents;'><input type="checkbox"></pl-combined-child></td></tr></table>
</div><script id='rhymrreksi'>
const div = currentScript.parentElement
let key = "rhymrreksi"
const inputs = div.querySelectorAll(`pl-combined-child[key='${key}'] > *:first-child`)

const values = Array(inputs.length)

inputs.forEach(async (el,i) => {
	el.oninput = (e) => {
		e.stopPropagation()
	}
	const gen = Generators.input(el)
	while(true) {
		values[i] = await gen.next().value
		div.dispatchEvent(new CustomEvent("input", {}))
	}
})


let set_input_value = (() => {
	let result = null
	try {
	result = setBoundElementValueLikePluto
} catch (e) {
	result = ((input, new_value) => {
	// fallback in case https://github.com/fonsp/Pluto.jl/pull/1755 is not available
    if (new_value == null) {
        //@ts-ignore
        input.value = new_value
        return
    }
    if (input instanceof HTMLInputElement) {
        switch (input.type) {
            case "range":
            case "number": {
                if (input.valueAsNumber !== new_value) {
                    input.valueAsNumber = new_value
                }
                return
            }
            case "date": {
                if (input.valueAsDate == null || Number(input.valueAsDate) !== Number(new_value)) {
                    input.valueAsDate = new_value
                }
                return
            }
            case "checkbox": {
                if (input.checked !== new_value) {
                    input.checked = new_value
                }
                return
            }
            case "file": {
                // Can't set files :(
                return
            }
        }
    } else if (input instanceof HTMLSelectElement && input.multiple) {
        for (let option of Array.from(input.options)) {
            option.selected = new_value.includes(option.value)
        }
        return
    }
    //@ts-ignore
    if (input.value !== new_value) {
        //@ts-ignore
        input.value = new_value
    }
})
}
return result
})()


Object.defineProperty(div, 'value', {
	get: () => values,
	set: (newvals) => {
		if(!newvals) {
			return
		}
		inputs.forEach((el, i) => {
			values[i] = newvals[i]
			set_input_value(el, newvals[i])
		})
},
	configurable: true,
});

</script></span>
	<input type=submit id='bowhisexvj'>
	<script id='bowhisexvj'>

let key = "bowhisexvj"

let div = currentScript.parentElement
let button = currentScript.previousElementSibling
let input = div.firstElementChild
if(input === button) {
	return
}


let set_input_value = (() => {
	let result = null
	try {
	result = setBoundElementValueLikePluto
} catch (e) {
	result = ((input, new_value) => {
	// fallback in case https://github.com/fonsp/Pluto.jl/pull/1755 is not available
    if (new_value == null) {
        //@ts-ignore
        input.value = new_value
        return
    }
    if (input instanceof HTMLInputElement) {
        switch (input.type) {
            case "range":
            case "number": {
                if (input.valueAsNumber !== new_value) {
                    input.valueAsNumber = new_value
                }
                return
            }
            case "date": {
                if (input.valueAsDate == null || Number(input.valueAsDate) !== Number(new_value)) {
                    input.valueAsDate = new_value
                }
                return
            }
            case "checkbox": {
                if (input.checked !== new_value) {
                    input.checked = new_value
                }
                return
            }
            case "file": {
                // Can't set files :(
                return
            }
        }
    } else if (input instanceof HTMLSelectElement && input.multiple) {
        for (let option of Array.from(input.options)) {
            option.selected = new_value.includes(option.value)
        }
        return
    }
    //@ts-ignore
    if (input.value !== new_value) {
        //@ts-ignore
        input.value = new_value
    }
})
}
return result
})()



let private_value = null
let public_value = null




private_value = public_value = div.value
if(private_value != null) {
	set_input_value(input, private_value)
} else {

	// private_value = public_value = input.value
}

input.oninput = (e) => {
	e.stopPropagation()
}
const gen = Generators.input(input)

// If the child does not have an initial value, the `gen.next().value` promise will never resolve. If it does, then it resolves instantly.
let first_value = await Promise.any([
	gen.next().value,
	Promise.resolve(undefined)
])
private_value = public_value = first_value

;(async () => {
	while(true) {
		private_value = await gen.next().value
		// div.dispatchEvent(new CustomEvent("input", {}))
	}
})()

button.addEventListener("click", () => {
	public_value = private_value
	div.dispatchEvent(new CustomEvent("input", {}))
})


Object.defineProperty(div, 'value', {
	get: () => public_value,
	set: (newval) => {
		private_value = newval
		public_value = newval
		
		set_input_value(input, newval)
	},
	configurable: true,
});

</script></span></bond>mimetext/htmlrootassigneelast_run_timestampA31npersist_js_state·has_pluto_hook_features§cell_id$1117e6c3-2736-46a4-bac2-d3c99c1998b6depends_on_disabled_cells§runtime	published_object_keysdepends_on_skipped_cells§errored$5948f670-1203-4b75-8517-f8470f5d01aaqueued¤logsrunning¦outputbody+figure_5_4 (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA,persist_js_state·has_pluto_hook_features§cell_id$5948f670-1203-4b75-8517-f8470f5d01aadepends_on_disabled_cells§runtime7<published_object_keysdepends_on_skipped_cells§errored$2ed88aa5-fc42-4a57-924d-e918805e2208queued¤logsrunning¦outputbody-<div class="markdown"><h5>Track 2</h5>
</div>mimetext/htmlrootassigneelast_run_timestampA"+ Opersist_js_state·has_pluto_hook_features§cell_id$2ed88aa5-fc42-4a57-924d-e918805e2208depends_on_disabled_cells§runtime lpublished_object_keysdepends_on_skipped_cells§errored$c9bd778c-217a-4664-8cde-841beca10307queued¤logsrunning¦outputbody<div>Reward = +1 on All Transitions</div>
<div style="display: flex; align-items: center; background-color: lightgray; color: black; height: 150px; width: 100px;">
<div class="backup" style="transform: scale(130%)">
	<div class="circlestate"></div>
	<div class="arrow"></div>
	<div class="term"></div>
</div>
<div>
	<div class="loop"></div>
	<div style="transform: translateY(-15px)">1-p</div>
</div>
</div>
<style>
	.loop {
		display: flex;
		border-width: 2px 0px 0px 2px;
		border-style: solid;
		border-color: black;
		width: 38px;
		height: 28px;
		border-radius: 50% 50% 50% 15%;
		transform: translateY(-30px) rotate(45deg);
	}
	.loop::before {
		content: '';
		position: relative;
		width: 5px;
		height: 5px;
		border-width: 0px 0px 3px 3px;
		border-style: solid;
		border-color: black;
		transform: translateX(-4px) translateY(17px) rotate(-45deg)
	}
	.loop::after {
		content: 'p';
		border-width: 0px 2px 2px 0px;
		border-style: solid;
		border-color: black;
		width: 38px;
		height: 28px;
		border-radius: 50% 50% 50% 0%;
	}
</style>
mimetext/htmlrootassigneelast_run_timestampA)ۥpersist_js_state·has_pluto_hook_features§cell_id$c9bd778c-217a-4664-8cde-841beca10307depends_on_disabled_cells§runtimejpublished_object_keysdepends_on_skipped_cells§errored$605b045d-fe5c-426b-9f55-b7dd1d037c50queued¤logsrunning¦outputbodyY<div class="markdown"><p>Example trajectories after training for 1000 episodes</p>
</div>mimetext/htmlrootassigneelast_run_timestampA22persist_js_state·has_pluto_hook_features§cell_id$605b045d-fe5c-426b-9f55-b7dd1d037c50depends_on_disabled_cells§runtime εpublished_object_keysdepends_on_skipped_cells§errored$88335fca-fd87-487b-9de2-ea7c779b54cfqueued¤logsrunning¦outputbodyJ<div class="markdown"><h2>5.9 Per-decision Importance Sampling</h2>
</div>mimetext/htmlrootassigneelast_run_timestampA"+ޘpersist_js_state·has_pluto_hook_features§cell_id$88335fca-fd87-487b-9de2-ea7c779b54cfdepends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$fd91d00a-f94f-40ff-88a7-9d85f05acc96queued¤logsrunning¦outputbody-make_row_set (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA/Qkpersist_js_state·has_pluto_hook_features§cell_id$fd91d00a-f94f-40ff-88a7-9d85f05acc96depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$a59d9c84-d35f-4a9b-9fb6-13e30cdd7c3aqueued¤logsrunning¦outputbody2.01716f0mimetext/plainrootassigneelast_run_timestampA-tpersist_js_state·has_pluto_hook_features§cell_id$a59d9c84-d35f-4a9b-9fb6-13e30cdd7c3adepends_on_disabled_cells§runtimey̵published_object_keysdepends_on_skipped_cells§errored$df3c4a33-45f1-4cc2-8c06-d500a0eecc8fqueued¤logsrunning¦outputbodyelementsstartprefixSet{Tuple{Int64, Int64}}elementselements0text/plain0text/plaintypeTupleobjectid9b52efd7a2a08bd5!application/vnd.pluto.tree+objectelements4text/plain0text/plaintypeTupleobjectidc772df2bb869c6b4!application/vnd.pluto.tree+objectelements5text/plain0text/plaintypeTupleobjectid973ae957c0c386bd!application/vnd.pluto.tree+objectelements2text/plain0text/plaintypeTupleobjectid83bf2aef4031930b!application/vnd.pluto.tree+objectelements3text/plain0text/plaintypeTupleobjectidaa4c36dcad24fa29!application/vnd.pluto.tree+objectelements1text/plain0text/plaintypeTupleobjectid1539b04621ff8c7d!application/vnd.pluto.tree+objecttypeSetprefix_shortSetobjectid1d8241165bb36cd8!application/vnd.pluto.tree+objectfinishprefixSet{Tuple{Int64, Int64}}elementselements13text/plain27text/plaintypeTupleobjectid54596a77c929eebd!application/vnd.pluto.tree+objectelements13text/plain28text/plaintypeTupleobjectide62a3fcc16b8e2ed!application/vnd.pluto.tree+objectelements13text/plain30text/plaintypeTupleobjectid8412ec158a86a5dd!application/vnd.pluto.tree+objectelements13text/plain29text/plaintypeTupleobjectida412ad26df95fe95!application/vnd.pluto.tree+objectelements13text/plain26text/plaintypeTupleobjectidd220e80edae3ebdb!application/vnd.pluto.tree+objectelements13text/plain31text/plaintypeTupleobjectiddd11b696ef064776!application/vnd.pluto.tree+objecttypeSetprefix_shortSetobjectid445dadcb9dd2ee11!application/vnd.pluto.tree+objectbodyprefixSet{Tuple{Int64, Int64}}elementselements1text/plain28text/plaintypeTupleobjectid72e21e63940a8fea!application/vnd.pluto.tree+objectelements-2text/plain10text/plaintypeTupleobjectid9461b7cf1c0d4966!application/vnd.pluto.tree+objectelements-1text/plain4text/plaintypeTupleobjectid6ab5d2dd7af393ce!application/vnd.pluto.tree+objectelements2text/plain26text/plaintypeTupleobjectidd3f46239e4706803!application/vnd.pluto.tree+objectelements5text/plain28text/plaintypeTupleobjectideb92527562a71ccc!application/vnd.pluto.tree+objectelements-1text/plain22text/plaintypeTupleobjectid6f6a11db6a4c9b77!application/vnd.pluto.tree+objectelements0text/plain17text/plaintypeTupleobjectid7be014bd27506452!application/vnd.pluto.tree+objectelements6text/plain29text/plaintypeTupleobjectidbcd5c7e53eb2beaf!application/vnd.pluto.tree+object	elements9text/plain26text/plaintypeTupleobjectid6f8558ee5165148d!application/vnd.pluto.tree+object
elements-2text/plain21text/plaintypeTupleobjectida97d298421d9eb40!application/vnd.pluto.tree+objectmoretypeSetprefix_shortSetobjectidc62bd8def750e86d!application/vnd.pluto.tree+objecttypeNamedTupleobjectid60c6d3bae0348446mime!application/vnd.pluto.tree+objectrootassigneeconst track1last_run_timestampA/GNpersist_js_state·has_pluto_hook_features§cell_id$df3c4a33-45f1-4cc2-8c06-d500a0eecc8fdepends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cells§errored$e2fc1d47-2ee9-4844-a6b1-16f76531da86queued¤logsrunning¦outputbodya<bond def="run3_2" unique_id="/2bK&#43;8/fRo4&#43;"><input type="button" value="Run Race"></bond>mimetext/htmlrootassigneelast_run_timestampA3ipersist_js_state·has_pluto_hook_features§cell_id$e2fc1d47-2ee9-4844-a6b1-16f76531da86depends_on_disabled_cells§runtime 
npublished_object_keysdepends_on_skipped_cells§errored$2d36ebe3-1a86-4cad-a235-baec726da926queued¤logsrunning¦outputbody<div class="markdown"><h4>Example Random Trajectories on Each Track</h4>
<p>The black arrows represent the velocity of the car at that position, and the red arrows show the policy action to change the velocity.  Note that only non-negative values are allowed for velocity to some of the actions have no impact.  Also, the car is not allowed by be stopped so if an action were to reduce the velocity to 0, then a random velocity of &#43;1 will be assigned to either the x or y direction.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA"*]persist_js_state·has_pluto_hook_features§cell_id$2d36ebe3-1a86-4cad-a235-baec726da926depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$dfc2d648-ec08-49cd-a55f-72a766cad728queued¤logsrunning¦outputbodyelements9×7300 Matrix{Float32}:
 0.111111  0.111111  0.111111  0.111111  …  0.111111  0.111111  0.111111  0.111111
 0.111111  0.111111  0.111111  0.111111     0.111111  0.111111  0.111111  0.111111
 0.111111  0.111111  0.111111  0.111111     0.111111  0.111111  0.111111  0.111111
 0.111111  0.111111  0.111111  0.111111     0.111111  0.111111  0.111111  0.111111
 0.111111  0.111111  0.111111  0.111111     0.111111  0.111111  0.111111  0.111111
 0.111111  0.111111  0.111111  0.111111  …  0.111111  0.111111  0.111111  0.111111
 0.111111  0.111111  0.111111  0.111111     0.111111  0.111111  0.111111  0.111111
 0.111111  0.111111  0.111111  0.111111     0.111111  0.111111  0.111111  0.111111
 0.111111  0.111111  0.111111  0.111111     0.111111  0.111111  0.111111  0.111111text/plain9×7300 Matrix{Float32}:
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  …  0.0  0.0  0.0   0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0     0.0  0.0  0.0   0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0     0.0  0.0  0.0   0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0     0.0  0.0  0.0   0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0     0.0  0.0  0.0   0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  …  0.0  0.0  0.0   0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0     0.0  0.0  0.0  -1.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0     0.0  0.0  0.0   0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0     0.0  0.0  0.0   0.0  0.0  0.0  0.0  0.0text/plaintypeTupleobjectid5321b0339663132bmime!application/vnd.pluto.tree+objectrootassigneelast_run_timestampA1persist_js_state·has_pluto_hook_features§cell_id$dfc2d648-ec08-49cd-a55f-72a766cad728depends_on_disabled_cells§runtimeTpublished_object_keysdepends_on_skipped_cells§errored$7ee4e17e-c1a9-4df0-a014-114bebcb4f52queued¤logsrunning¦outputbody/makegridsquare (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA/gpersist_js_state·has_pluto_hook_features§cell_id$7ee4e17e-c1a9-4df0-a014-114bebcb4f52depends_on_disabled_cells§runtime #published_object_keysdepends_on_skipped_cells§errored$2d10281a-a4af-4ea8-b63b-e11f2d0893edqueued¤logsrunning¦outputbody4make_greedy_policy! (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA%:persist_js_state·has_pluto_hook_features§cell_id$2d10281a-a4af-4ea8-b63b-e11f2d0893eddepends_on_disabled_cells§runtime )Եpublished_object_keysdepends_on_skipped_cells§errored$e87932d9-fbc0-4ea5-a8ee-28eac5eed84fqueued¤logsrunning¦outputbody*scoregame (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA%6=.persist_js_state·has_pluto_hook_features§cell_id$e87932d9-fbc0-4ea5-a8ee-28eac5eed84fdepends_on_disabled_cells§runtime첵published_object_keysdepends_on_skipped_cells§errored$1cc46e33-6885-4d6f-805e-9ff928f1cf23queued¤logsrunning¦outputbodyprefixFloat64elements0.0text/plain1.0text/plain2.0text/plain3.0text/plain4.0text/plain1.41421text/plain2.23607text/plain3.16228text/plain	4.12311text/plain
2.82843text/plain3.60555text/plain4.47214text/plain4.24264text/plain5.0text/plain5.65685text/plaintypeArrayprefix_shortobjectid92c7ba6aa0ad7162mime!application/vnd.pluto.tree+objectrootassigneeconst racetrackspeedslast_run_timestampA/*persist_js_state·has_pluto_hook_features§cell_id$1cc46e33-6885-4d6f-805e-9ff928f1cf23depends_on_disabled_cells§runtimeąpublished_object_keysdepends_on_skipped_cells§errored$f79d97bb-341a-46ad-bdfc-d080af13e2dfqueued¤logsrunning¦outputbodyI<div class="markdown"><h4>Monte Carlo ϵ-Soft Solution Method</h4>
</div>mimetext/htmlrootassigneelast_run_timestampA"+Wpersist_js_state·has_pluto_hook_features§cell_id$f79d97bb-341a-46ad-bdfc-d080af13e2dfdepends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$6a11daf7-2859-41fa-9c3d-d1f3580dbb5fqueued¤logsrunning¦outputbody<<div class="markdown"><h3>Example 5.1: Blackjack</h3>
</div>mimetext/htmlrootassigneelast_run_timestampA"&)Rpersist_js_state·has_pluto_hook_features§cell_id$6a11daf7-2859-41fa-9c3d-d1f3580dbb5fdepends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$985f0537-2bbe-4dbb-a113-8ac98d2e0a5fqueued¤logsrunning¦outputbodym<div class="markdown"><p>Statistics for Steps to Finish Race on Track 1</p>

<table><tr><th align="right">Statistic</th><th align="right"><div class="markdown"><p>Monte Carlo ϵ-Soft</p>
</div></th><th align="right">Random Policy</th></tr><tr><td align="right">Mean</td><td align="right">81</td><td align="right">2557</td></tr><tr><td align="right">Median</td><td align="right">58</td><td align="right">1946</td></tr><tr><td align="right">Std</td><td align="right">70</td><td align="right">2207</td></tr><tr><td align="right">Minimum</td><td align="right">14</td><td align="right">14</td></tr><tr><td align="right">Maximum</td><td align="right">555</td><td align="right">9974</td></tr></table>
<p>Cummulative Distribution Function of Steps to Finish Race 	<script id='plot_1'>
		// We start by putting all the variable interpolation here at the beginning
		// We have to convert all typedarrays in the layout to normal arrays. See Issue #25
		// We use lodash for this for compactness
		function removeTypedArray(o) {
			return _.isTypedArray(o) ? Array.from(o) :
			_.isPlainObject(o) ? _.mapValues(o, removeTypedArray) : 
			o
		}

		// Publish the plot object to JS
		let plot_obj = _.update(/* See the documentation for AbstractPlutoDingetjes.Display.published_to_js */ getPublishedObject("c6e0de0c-3901-11f0-234e-bd09c571f662/6a054f00f0376f57"), "layout", removeTypedArray)
		// Get the plotly listeners
		const plotly_listeners = {}
		// Get the JS listeners
		const js_listeners = {}
		// Deal with eventual custom classes
		let custom_classlist = []


		// Load the plotly library
		let Plotly = undefined
		try {
			let _mod = await import("./plotlyjs/plotlyjs-2.26.2.min.js")
			Plotly = _mod.default
		} catch (e) {
			console.log("Local load failed, trying with the web esm.sh version")
			let _mod = await import("https://esm.sh/plotly.js-dist-min@2.26.2/es2022/plotly.js-dist-min.mjs")
			Plotly = _mod.default
		}

		// Check if we have to force local mathjax font cache
		if (false && window?.MathJax?.config?.svg?.fontCache === 'global') {
			window.MathJax.config.svg.fontCache = 'local'
		}

		// Flag to check if this cell was  manually ran or reactively ran
const firstRun = this ? false : true
const CONTAINER = this ?? html`<div class='plutoplotly-container'>`
const PLOT = CONTAINER.querySelector('.js-plotly-plot') ?? CONTAINER.appendChild(html`<div>`)
const parent = CONTAINER.parentElement
// We use a controller to remove event listeners upon invalidation
const controller = new AbortController()
// We have to add this to keep supporting @bind with the old API using PLOT
PLOT.addEventListener('input', (e) => {
	CONTAINER.value = PLOT.value
	if (e.bubbles) {
		return
	}
	CONTAINER.dispatchEvent(new CustomEvent('input'))
}, { signal: controller.signal })

	// This create the style subdiv on first run
	firstRun && CONTAINER.appendChild(html`
	<style>
	.plutoplotly-container {
		width: 100%;
		height: 100%;
		min-height: 0;
		min-width: 0;
	}
	.plutoplotly-container .js-plotly-plot .plotly div {
		margin: 0 auto; // This centers the plot
	}
	.plutoplotly-container.popped-out {
		overflow: auto;
		z-index: 1000;
		position: fixed;
		resize: both;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		border-top-left-radius: 0px;
		border-top-right-radius: 0px;
	}
	.plutoplotly-clipboard-header {
		display: flex;
		flex-flow: row wrap;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-top-left-radius: 12px;
		border-top-right-radius: 12px;
		position: fixed;
		z-index: 1001;
		cursor: move;
		transform: translate(0px, -100%);
		padding: 5px;
	}
	.plutoplotly-clipboard-header span {
		display: inline-block;
		flex: 1
	}
	.plutoplotly-clipboard-header.hidden {
		display: none;
	}
	.clipboard-span {
		position: relative;
	}
	.clipboard-value {
		padding-right: 5px;
		padding-left: 2px;
		cursor: text;
	}
	.clipboard-span.format {
		display: none;
	}
	.clipboard-span.filename {
		flex: 0 0 100%;
		text-align: center;
		border-top: 3px solid var(--kbd-border-color);
		margin-top: 5px;
		display: none;
	}
	.plutoplotly-container.filesave .clipboard-span.filename {
		display: inline-block;
	}
	.clipboard-value.filename {
		margin-left: 3px;
		text-align: left;
		min-width: min(60%, min-content);
	}
	.plutoplotly-container.filesave .clipboard-span.format {
		display: inline-flex;
	}
	.clipboard-span.format .label {
		flex: 0 0 0;
	}
	.clipboard-value.format {
		position: relative;
		flex: 1 0 auto;
		min-width: 30px;
		margin-right: 10px;
	}
	div.format-options {
		display: inline-flex;
		flex-flow: column;
		position: absolute;
		background: var(--main-bg-color);
		border-radius: 12px;
		padding-left: 3px;
		z-index: 2000;
	}
	div.format-options:hover {
		cursor: pointer;
		border: 3px solid var(--kbd-border-color);
		padding: 3px;
		transform: translate(-3px, -6px);
	}
	div.format-options .format-option {
		display: none;
	}
	div.format-options:hover .format-option {
		display: inline-block;
	}
	.format-option:not(.selected) {
		margin-top: 3px;
	}
	div.format-options .format-option.selected {
		order: -1;
		display: inline-block;
	}
	.format-option:hover {
		background-color: var(--kbd-border-color);
	}
	span.config-value {
		font-weight: normal;
		color: var(--pluto-output-color);
		display: none;
		position: absolute;
		background: var(--main-bg-color);
		border: 3px solid var(--kbd-border-color);
		border-radius: 12px;
		transform: translate(0px, calc(-100% - 10px));
		padding: 5px;
	}
	.label {
		user-select: none;
	}
	.label:hover span.config-value {
		display: inline-block;
		min-width: 150px;
	}
	.clipboard-span.matching-config .label {
		color: var(--cm-macro-color);
		font-weight: bold;
	}
	.clipboard-span.different-config .label {
		color: var(--cm-tag-color);
		font-weight: bold;
	}
</style>
`)

let original_height = plot_obj.layout.height
let original_width = plot_obj.layout.width
// For the height we have to also put a fixed value in case the plot is put on a non-fixed-size container (like the default wrapper)
// We define a variable to check whether we still have to remove the fixed height
let remove_container_size = firstRun
let container_height = original_height ?? PLOT.container_height ?? 400
CONTAINER.style.height = container_height + 'px'

// We create a Promise version of setTimeout
function delay(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

// We import interact for dragging/resizing
const { default: interact } = await import('https://esm.sh/interactjs@1.10.19')


function getImageOptions() {
  const o = plot_obj.config.toImageButtonOptions ?? {};
  return {
    format: o.format ?? "png",
    width: o.width ?? original_width,
    height: o.height ?? original_height,
    scale: o.scale ?? 1,
    filename: o.filename ?? "newplot",
  };
}

const CLIPBOARD_HEADER =
  CONTAINER.querySelector(".plutoplotly-clipboard-header") ??
  CONTAINER.insertAdjacentElement(
    "afterbegin",
    html`<div class="plutoplotly-clipboard-header hidden">
      <span class="clipboard-span format"
        ><span class="label">Format:</span
        ><span class="clipboard-value format"></span
      ></span>
      <span class="clipboard-span width"
        ><span class="label">Width:</span
        ><span class="clipboard-value width"></span>px</span
      >
      <span class="clipboard-span height"
        ><span class="label">Height:</span
        ><span class="clipboard-value height"></span>px</span
      >
      <span class="clipboard-span scale"
        ><span class="label">Scale:</span
        ><span class="clipboard-value scale"></span
      ></span>
      <button class="clipboard-span set">Set</button>
      <button class="clipboard-span unset">Unset</button>
      <span class="clipboard-span filename"
        ><span class="label">Filename:</span
        ><span class="clipboard-value filename"></span
      ></span>
    </div>`
  );

function checkConfigSync(container) {
  const valid_classes = [
    "missing-config",
    "matching-config",
    "different-config",
  ];
  function setClass(cl) {
    for (const name of valid_classes) {
      container.classList.toggle(name, name == cl);
    }
  }
  // We use the custom getters we'll set up in the container
  const { ui_value, config_value, config_span, key } = container;
  if (config_value === undefined) {
    setClass("missing-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> is not present in the config.`;
  } else if (ui_value == config_value) {
    setClass("matching-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has the same value in the config and in the header.`;
  } else {
    setClass("different-config");
    config_span.innerHTML = `The key <b><em>${key}</em></b> has a different value (<em>${config_value}</em>) in the config.`;
  }
  // Add info about setting and unsetting
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click on the label <em><b>once</b></em> to set the current UI value in the config.`
  );
  config_span.insertAdjacentHTML(
    "beforeend",
    `<br>Click <em><b>twice</b></em> to remove this key from the config.`
  );
}

const valid_formats = ["png", "svg", "webp", "jpeg", "full-json"];
function initializeUIValueSpan(span, key, value) {
  const container = span.closest(".clipboard-span");
  span.contentEditable = key === "format" ? "false" : "true";
  let parse = (x) => x;
  let update = (x) => (span.textContent = x);
  if (key === "width" || key === "height") {
    parse = (x) => Math.round(parseFloat(x));
  } else if (key === "scale") {
    parse = parseFloat;
  } else if (key === "format") {
    // We remove contentEditable
    span.contentEditable = "false";
    // Here we first add the subspans for each option
    const opts_div = span.appendChild(html`<div class="format-options"></div>`);
    for (const fmt of valid_formats) {
      const opt = opts_div.appendChild(
        html`<span class="format-option ${fmt}">${fmt}</span>`
      );
      opt.onclick = (e) => {
        span.value = opt.textContent;
      };
    }
    parse = (x) => {
      return valid_formats.includes(x) ? x : localValue;
    };
    update = (x) => {
      for (const opt of opts_div.children) {
        opt.classList.toggle("selected", opt.textContent === x);
      }
    };
  } else {
    // We only have filename here
  }
  let localValue;
  Object.defineProperty(span, "value", {
    get: () => {
      return localValue;
    },
    set: (val) => {
      if (val !== "") {
        localValue = parse(val);
      }
      update(localValue);
      checkConfigSync(container);
    },
  });
  // We also assign a listener so that the editable is blurred when enter is pressed
  span.onkeydown = (e) => {
    if (e.keyCode === 13) {
      e.preventDefault();
      span.blur();
    }
  };
  span.value = value;
}

function initializeConfigValueSpan(span, key) {
  // Here we mostly want to define the setter and getter
  const container = span.closest(".clipboard-span");
  Object.defineProperty(span, "value", {
    get: () => {
      return plot_obj.config.toImageButtonOptions[key];
    },
    set: (val) => {
      // if undefined is passed, we remove the entry from the options
      if (val === undefined) {
        delete plot_obj.config.toImageButtonOptions[key];
      } else {
        plot_obj.config.toImageButtonOptions[key] = val;
      }
      checkConfigSync(container);
    },
  });
}

const config_spans = {};
for (const [key, value] of Object.entries(getImageOptions())) {
  const container = CLIPBOARD_HEADER.querySelector(`.clipboard-span.${key}`);
  const label = container.querySelector(".label");
  // We give the label a function that on single click will set the current value and with double click will unset it
  label.onclick = DualClick(
    () => {
      container.config_value = container.ui_value;
    },
    (e) => {
      console.log("e", e);
      e.preventDefault();
      container.config_value = undefined;
    }
  );
  const ui_value_span = container.querySelector(".clipboard-value");
  const config_value_span =
    container.querySelector(".config-value") ??
    label.insertAdjacentElement(
      "afterbegin",
      html`<span class="config-value"></span>`
    );
  // Assing the two spans as properties of the containing span
  container.ui_span = ui_value_span;
  container.config_span = config_value_span;
  container.key = key;
  config_spans[key] = container;
  if (firstRun) {
    plot_obj.config.toImageButtonOptions =
      plot_obj.config.toImageButtonOptions ?? {};
    // We do the initialization of the value span
    initializeUIValueSpan(ui_value_span, key, value);
    // Then we initialize the config value
    initializeConfigValueSpan(config_value_span, key);
    // We put some convenience getters/setters
    // ui_value forward
    Object.defineProperty(container, "ui_value", {
      get: () => ui_value_span.value,
      set: (val) => {
        ui_value_span.value = val;
      },
    });
    // config_value forward
    Object.defineProperty(container, "config_value", {
      get: () => config_value_span.value,
      set: (val) => {
        config_value_span.value = val;
      },
    });
  }
}

// These objects will contain the default value

// This code updates the image options in the PLOT config with the provided ones
function setImageOptions(o) {
  for (const [key, container] of Object.entries(config_spans)) {
    container.config_value = o[key];
  }
}
function unsetImageOptions() {
  setImageOptions({});
}

const set_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.set");
const unset_button = CLIPBOARD_HEADER.querySelector(".clipboard-span.unset");
if (firstRun) {
  set_button.onclick = (e) => {
    for (const container of Object.values(config_spans)) {
      container.config_value = container.ui_value;
    }
  };
  unset_button.onclick = unsetImageOptions;
}

// We add a function to check if the clipboard is popped out
CONTAINER.isPoppedOut = () => {
  return CONTAINER.classList.contains("popped-out");
};

CLIPBOARD_HEADER.onmousedown = function (event) {
  if (event.target.matches("span.clipboard-value")) {
    console.log("We don't move!");
    return;
  }
  const start = {
    left: parseFloat(CONTAINER.style.left),
    top: parseFloat(CONTAINER.style.top),
    X: event.pageX,
    Y: event.pageY,
  };
  function moveAt(event, start) {
    const top = event.pageY - start.Y + start.top + "px";
    const left = event.pageX - start.X + start.left + "px";
    CLIPBOARD_HEADER.style.left = left;
    CONTAINER.style.left = left;
    CONTAINER.style.top = top;
  }

  // move our absolutely positioned ball under the pointer
  moveAt(event, start);
  function onMouseMove(event) {
    moveAt(event, start);
  }

  // We use this to remove the mousemove when clicking outside of the container
  const controller = new AbortController();

  // move the container on mousemove
  document.addEventListener("mousemove", onMouseMove, {
    signal: controller.signal,
  });
  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        cleanUp();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );

  function cleanUp() {
    console.log("cleaning up the plot move listener");
    controller.abort();
    CLIPBOARD_HEADER.onmouseup = null;
  }

  // (3) drop the ball, remove unneeded handlers
  CLIPBOARD_HEADER.onmouseup = cleanUp;
};

function sendToClipboard(blob) {
  if (!navigator.clipboard) {
    alert(
      "The Clipboard API does not seem to be available, make sure the Pluto notebook is being used from either localhost or an https source."
    );
  }
  navigator.clipboard
    .write([
      new ClipboardItem({
        // The key is determined dynamically based on the blob's type.
        [blob.type]: blob,
      }),
    ])
    .then(
      function () {
        console.log("Async: Copying to clipboard was successful!");
      },
      function (err) {
        console.error("Async: Could not copy text: ", err);
      }
    );
}

function copyImageToClipboard() {
  // We extract the image options from the provided parameters (if they exist)
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key. We also ignore format because the clipboard only supports png.
    if (val === undefined || key === "format") {
      continue;
    }
    config[key] = val;
  }
  Plotly.toImage(PLOT, config).then(function (dataUrl) {
    fetch(dataUrl)
      .then((res) => res.blob())
      .then((blob) => {
        const paste_receiver = document.querySelector('paste-receiver.plutoplotly')
        if (paste_receiver) {
          paste_receiver.attachImage(dataUrl, CONTAINER)
        }
        sendToClipboard(blob)
      });
  });
}

function saveImageToFile() {
  const config = {};
  for (const [key, container] of Object.entries(config_spans)) {
    let val =
      container.config_value ??
      (CONTAINER.isPoppedOut() ? container.ui_value : undefined);
    // If we have undefined we don't create the key.
    if (val === undefined) {
      continue;
    }
    config[key] = val;
  }
  Plotly.downloadImage(PLOT, config);
}

let container_rect = { width: 0, height: 0, top: 0, left: 0 };
function unpop_container(cl) {
  CONTAINER.classList.toggle("popped-out", false);
  CONTAINER.classList.toggle(cl, false);
  // We fix the height back to the value it had before popout, also setting the flag to signal that upon first resize we remove the fixed inline-style
  CONTAINER.style.height = container_rect.height + "px";
  remove_container_size = true;
  // We set the other fixed inline-styles to null
  CONTAINER.style.width = "";
  CONTAINER.style.top = "";
  CONTAINER.style.left = "";
  // We also remove the CLIPBOARD_HEADER
  CLIPBOARD_HEADER.style.width = "";
  CLIPBOARD_HEADER.style.left = "";
  // Finally we remove the hidden class to the header
  CLIPBOARD_HEADER.classList.toggle("hidden", true);
  return;
}
function popout_container(opts) {
  const cl = opts?.cl;
  const target_container_size = opts?.target_container_size ?? {};
  const target_plot_size = opts?.target_plot_size ?? {};
  if (CONTAINER.isPoppedOut()) {
    return unpop_container(cl);
  }
  CONTAINER.classList.toggle(cl, cl === undefined ? false : true);
  // We extract the current size of the container, save them and fix them
  const { width, height, top, left } = CONTAINER.getBoundingClientRect();
  container_rect = { width, height, top, left };
  // We save the current plot size before we pop as it will fill the screen
  const current_plot_size = {
    width: PLOT._fullLayout.width,
    height: PLOT._fullLayout.height,
  };
  // We have to save the pad data before popping so we can resize precisely
  const pad = {};
  pad.unpopped = getSizeData().container_pad;
  CONTAINER.classList.toggle("popped-out", true);
  pad.popped = getSizeData().container_pad;
  // We do top and left based on the current rect
  for (const key of ["top", "left"]) {
    const start_val = target_container_size[key] ?? container_rect[key];
    let offset = 0;
    for (const kind of ["padding", "border"]) {
      offset += pad.popped[kind][key] - pad.unpopped[kind][key];
    }
    CONTAINER.style[key] = start_val - offset + "px";
    if (key === "left") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  // We compute the width and height depending on eventual config data
  const csz = computeContainerSize({
    width:
      target_plot_size.width ??
      config_spans.width.config_value ??
      current_plot_size.width,
    height:
      target_plot_size.height ??
      config_spans.height.config_value ??
      current_plot_size.height,
  });
  for (const key of ["width", "height"]) {
    const val = target_container_size[key] ?? csz[key];
    CONTAINER.style[key] = val + "px";
    if (key === "width") {
      CLIPBOARD_HEADER.style[key] = CONTAINER.style[key];
    }
  }
  CLIPBOARD_HEADER.classList.toggle("hidden", false);
  const controller = new AbortController();

  document.addEventListener(
    "mousedown",
    (e) => {
      if (e.target.closest(".plutoplotly-container") !== CONTAINER) {
        unpop_container();
        controller.abort();
        return;
      }
    },
    { signal: controller.signal }
  );
}

CONTAINER.popOut = popout_container;

function DualClick(single_func, dbl_func) {
  let nclicks = 0;
  return function (...args) {
    nclicks += 1;
    if (nclicks > 1) {
      dbl_func(...args);
      nclicks = 0;
    } else {
      delay(300).then(() => {
        if (nclicks == 1) {
          single_func(...args);
        }
        nclicks = 0;
      });
    }
  };
}

// We remove the default download image button
plot_obj.config.modeBarButtonsToRemove = _.union(
  plot_obj.config.modeBarButtonsToRemove,
  ["toImage"]
);
// We add the custom button to the modebar
plot_obj.config.modeBarButtonsToAdd = _.union(
  plot_obj.config.modeBarButtonsToAdd,
  [
    {
      name: "Copy PNG to Clipboard",
      icon: {
        height: 520,
        width: 520,
        path: "M280 64h40c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128C0 92.7 28.7 64 64 64h40 9.6C121 27.5 153.3 0 192 0s71 27.5 78.4 64H280zM64 112c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16H320c8.8 0 16-7.2 16-16V128c0-8.8-7.2-16-16-16H304v24c0 13.3-10.7 24-24 24H192 104c-13.3 0-24-10.7-24-24V112H64zm128-8a24 24 0 1 0 0-48 24 24 0 1 0 0 48z",
      },
      direction: "up",
      click: DualClick(copyImageToClipboard, () => {
        popout_container();
      }),
    },
    {
      name: "Download Image",
      icon: Plotly.Icons.camera,
      direction: "up",
      click: DualClick(saveImageToFile, () => {
        popout_container({ cl: "filesave" });
      }),
    },
  ]
);

function getOffsetData(el) {
  let cs = window.getComputedStyle(el, null);
  const odata = {
    padding: {
      left: parseFloat(cs.paddingLeft),
      right: parseFloat(cs.paddingRight),
      top: parseFloat(cs.paddingTop),
      bottom: parseFloat(cs.paddingBottom),
      width: parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight),
      height: parseFloat(cs.paddingTop) + parseFloat(cs.paddingBottom),
    },
    border: {
      left: parseFloat(cs.borderLeftWidth),
      right: parseFloat(cs.borderRightWidth),
      top: parseFloat(cs.borderTopWidth),
      bottom: parseFloat(cs.borderBottomWidth),
      width: parseFloat(cs.borderLeftWidth) + parseFloat(cs.borderRightWidth),
      height: parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth),
    }
  };
  if (el === PLOT) {
    // For the PLOT we also want to take into account the offset
    odata.offset = {
      top: PLOT.offsetParent == CONTAINER ? PLOT.offsetTop : 0,
      left: PLOT.offsetParent == CONTAINER ? PLOT.offsetLeft : 0,
    }
  }
  return odata;
}
function getSizeData() {
  const data = {
    plot_pad: getOffsetData(PLOT),
    plot_rect: PLOT.getBoundingClientRect(),
    container_pad: getOffsetData(CONTAINER),
    container_rect: CONTAINER.getBoundingClientRect(),
  };
  return data;
}
function computeContainerSize({ width, height }, sizeData = getSizeData()) {
  const computed_size = computePlotSize(sizeData);
  const offsets = computed_size.offsets;

  const plot_data = {
    width: width ?? computed_size.width,
    height: height ?? computed_size.height,
  };

  return {
    width: (width ?? computed_size.width) + offsets.width,
    height: (height ?? computed_size.height) + offsets.height,
    noChange: width == computed_size.width && height == computed_size.height,
  }
}

// This function will change the container size so that the resulting plot will be matching the provided specs
function changeContainerSize({ width, height }, sizeData = getSizeData()) {
  if (!CONTAINER.isPoppedOut()) {
    console.log("Tried to change container size when not popped, ignoring");
    return;
  }

  const csz = computeContainerSize({ width, height }, sizeData);

  if (csz.noChange) {
    console.log("Size is the same as current, ignoring");
    return
  }
  // We are now going to set he width and height of the container
  for (const key of ["width", "height"]) {
    CONTAINER.style[key] = csz[key] + "px";
  }
}
// We now create the function that will update the plot based on the values specified
function updateFromHeader() {
  const header_data = {
    height: config_spans.height.ui_value,
    width: config_spans.width.ui_value,
  };
  changeContainerSize(header_data);
}
// We assign this function to the onblur event of width and height
if (firstRun) {
  for (const container of Object.values(config_spans)) {
    container.ui_span.onblur = (e) => {
      container.ui_value = container.ui_span.textContent;
      updateFromHeader();
    };
  }
}
// This function computes the plot size to use for relayout as a function of the container size
function computePlotSize(data = getSizeData()) {
  // Remove Padding
  const { container_pad, plot_pad, container_rect } = data;
  const offsets = {
    width:
      plot_pad.padding.width +
      plot_pad.border.width +
      plot_pad.offset.left +
      container_pad.padding.width +
      container_pad.border.width,
    height:
      plot_pad.padding.height +
      plot_pad.border.height +
      plot_pad.offset.top +
      container_pad.padding.height +
      container_pad.border.height,
  };
  const sz = {
    width: Math.round(container_rect.width - offsets.width),
    height: Math.round(container_rect.height - offsets.height),
    offsets,
  };
  return sz;
}

// Create the resizeObserver to make the plot even more responsive! :magic:
const resizeObserver = new ResizeObserver((entries) => {
  const sizeData = getSizeData();
  const {container_rect, container_pad} = sizeData;
  let plot_size = computePlotSize(sizeData);
  // We save the height in the PLOT object
  PLOT.container_height = container_rect.height;
  // We deal with some stuff if the container is poppped
  CLIPBOARD_HEADER.style.width = container_rect.width + "px";
  CLIPBOARD_HEADER.style.left = container_rect.left + "px";
  config_spans.height.ui_value = plot_size.height;
  config_spans.width.ui_value = plot_size.width;
  /* 
		The addition of the invalid argument `plutoresize` seems to fix the problem with calling `relayout` simply with `{autosize: true}` as update breaking mouse relayout events tracking. 
		See https://github.com/plotly/plotly.js/issues/6156 for details
		*/
  let config = {
    // If this is popped out, we ignore the original width/height
    width: (CONTAINER.isPoppedOut() ? undefined : original_width) ?? plot_size.width,
    height: (CONTAINER.isPoppedOut() ? undefined : original_height) ?? plot_size.height,
    plutoresize: true,
  };
  Plotly.relayout(PLOT, config).then(() => {
    if (remove_container_size && !CONTAINER.isPoppedOut()) {
      // This is needed to avoid the first resize upon plot creation to already be without a fixed height
      CONTAINER.style.height = "";
      CONTAINER.style.width = "";
      remove_container_size = false;
    }
  });
});

resizeObserver.observe(CONTAINER);


Plotly.react(PLOT, plot_obj).then(() => {
	// Assign the Plotly event listeners
	for (const [key, listener_vec] of Object.entries(plotly_listeners)) {
		for (const listener of listener_vec) {
			PLOT.on(key, listener)
		}
	}
	// Assign the JS event listeners
	for (const [key, listener_vec] of Object.entries(js_listeners)) {
		for (const listener of listener_vec) {
			PLOT.addEventListener(key, listener, {
				signal: controller.signal
			})
		}
	}
}
)


invalidation.then(() => {
	// Remove all plotly listeners
	PLOT.removeAllListeners()
	// Remove all JS listeners
	controller.abort()
	// Remove the resizeObserver
	resizeObserver.disconnect()
})



		return CONTAINER
	</script>
</p>
</div>mimetext/htmlrootassigneelast_run_timestampA3_|persist_js_state·has_pluto_hook_features§cell_id$985f0537-2bbe-4dbb-a113-8ac98d2e0a5fdepends_on_disabled_cells§runtime_Gpublished_object_keys5c6e0de0c-3901-11f0-234e-bd09c571f662/6a054f00f0376f57depends_on_skipped_cells§errored$217ecc59-d6e3-48fa-9d6d-700a3947b805queued¤logsrunning¦outputbody1.936f0mimetext/plainrootassigneelast_run_timestampA-zpersist_js_state·has_pluto_hook_features§cell_id$217ecc59-d6e3-48fa-9d6d-700a3947b805depends_on_disabled_cells§runtimeBҵpublished_object_keysdepends_on_skipped_cells§errored$a35de859-4046-4f6d-9ea9-b523d21cee5dqueued¤logsrunning¦outputbody0make_value_grid (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA%cpersist_js_state·has_pluto_hook_features§cell_id$a35de859-4046-4f6d-9ea9-b523d21cee5ddepends_on_disabled_cells§runtime ѵpublished_object_keysdepends_on_skipped_cells§errored$12c0cd0b-eb4f-45a0-836b-53b3c5cdafd9queued¤logsrunning¦outputbodyW<div class="markdown"><h2>5.5 Off-policy Prediction via Importance Sampling</h2>
</div>mimetext/htmlrootassigneelast_run_timestampA"'+persist_js_state·has_pluto_hook_features§cell_id$12c0cd0b-eb4f-45a0-836b-53b3c5cdafd9depends_on_disabled_cells§runtime ŵpublished_object_keysdepends_on_skipped_cells§errored$aaa9647c-afb6-44d1-ae1e-a2e957064080queued¤logsrunning¦outputbody,updatecount (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA)Zpersist_js_state·has_pluto_hook_features§cell_id$aaa9647c-afb6-44d1-ae1e-a2e957064080depends_on_disabled_cells§runtime Z published_object_keysdepends_on_skipped_cells§errored$b57462b6-8f9c-4553-9c05-134ff043b00dqueued¤logsrunning¦outputbody&<div class="markdown"><blockquote>
<h3><em>Exercise 5.9</em></h3>
<p>Modify the algorithm for first-visit MC policy evaluation &#40;section 5.1&#41; to use the incremental implementation for sample averages described in Section 2.4</p>
</blockquote>
<p>Returns&#40;s&#41; will not maintain a list but instead be a list of single values for each state.  Additionally, another list Counts&#40;s&#41; should be initialized at 0 for each state.  When new G values are obtained for state, the Count&#40;s&#41; value should be incremented by 1.  Then Returns&#40;s&#41; can be updated with the following formula: </p>
<p class="tex">$$\begin&#123;flalign&#125;
	\text&#123;Returns&#125;&#40;s&#41; &amp;&#61; \left &#91; \text&#123;Returns&#125;&#40;s&#41; \times &#40;\text&#123;Counts&#125;&#40;s&#41; - 1&#41; &#43; G \right &#93; / \text&#123;Counts&#125;&#40;s&#41; \\ 
	&amp;&#61; \text&#123;Returns&#125;&#40;s&#41; &#43; \frac&#123;G - \text&#123;Returns&#125;&#40;s&#41;&#125;&#123;\text&#123;Counts&#125;&#40;s&#41;&#125;
\end&#123;flalign&#125;$$</p>
</div>mimetext/htmlrootassigneelast_run_timestampA"(persist_js_state·has_pluto_hook_features§cell_id$b57462b6-8f9c-4553-9c05-134ff043b00ddepends_on_disabled_cells§runtime 7published_object_keysdepends_on_skipped_cells§errored$f506e8ba-b073-4f59-91b4-3fe99822d2a4queued¤logsrunning¦outputbodyprefixDict{Float64, Int64}elements5.0text/plain133text/plain2.23607text/plain59text/plain4.12311text/plain109text/plain4.24264text/plain112text/plain1.0text/plain27text/plain0.0text/plain0text/plain4.0text/plain106text/plain4.47214text/plain119text/plain2.0text/plain53text/plain3.16228text/plain84text/plain1.41421text/plain38text/plain2.82843text/plain75text/plain3.0text/plain80text/plain3.60555text/plain96text/plain5.65685text/plain150text/plaintypeDictprefix_shortDictobjectid79fbf8f1a441acamime!application/vnd.pluto.tree+objectrootassigneeconst scalelookuplast_run_timestampA/A曰persist_js_state·has_pluto_hook_features§cell_id$f506e8ba-b073-4f59-91b4-3fe99822d2a4depends_on_disabled_cells§runtimecpublished_object_keysdepends_on_skipped_cells§errored$bf19e6cf-1fb5-49c9-974e-1613d90ef4cfqueued¤logsrunning¦outputbodyelementsٻ2×200 Matrix{Float32}:
 0.95  0.95  0.95  0.95  0.95  0.05  0.95  …  0.05  0.05  0.05  0.05  0.05  0.05
 0.05  0.05  0.05  0.05  0.05  0.95  0.05     0.95  0.95  0.95  0.95  0.95  0.95text/plainٲ2×200 Matrix{Float32}:
 -0.349328  -0.587688   0.042062  -0.306492  …  -1.0       0.302885  -1.0
 -0.70339   -0.748792  -0.325779  -0.324561      0.944796  0.875826   0.810059text/plaintypeTupleobjectid5248b2b655ffdee9mime!application/vnd.pluto.tree+objectrootassigneelast_run_timestampA)Rpersist_js_state·has_pluto_hook_features§cell_id$bf19e6cf-1fb5-49c9-974e-1613d90ef4cfdepends_on_disabled_cells§runtime'@ѵpublished_object_keysdepends_on_skipped_cells§errored$77cf7fee-0ad8-4d22-b376-75833307db93queued¤logsrunning¦outputbodyM<script>
	
// Load the library for consistent smooth scrolling
const {default: scrollIntoView} = await import("data:text/javascript;base64,dmFyIFE9ZT0+Im9iamVjdCI9PXR5cGVvZiBlJiZudWxsIT1lJiYxPT09ZS5ub2RlVHlwZSxVPShlLHQpPT4oIXR8fCJoaWRkZW4iIT09ZSkmJiJ2aXNpYmxlIiE9PWUmJiJjbGlwIiE9PWUsQT0oZSx0KT0+e2lmKGUuY2xpZW50SGVpZ2h0PGUuc2Nyb2xsSGVpZ2h0fHxlLmNsaWVudFdpZHRoPGUuc2Nyb2xsV2lkdGgpe2xldCBsPWdldENvbXB1dGVkU3R5bGUoZSxudWxsKTtyZXR1cm4gVShsLm92ZXJmbG93WSx0KXx8VShsLm92ZXJmbG93WCx0KXx8KGU9PntsZXQgdD0oZT0+e2lmKCFlLm93bmVyRG9jdW1lbnR8fCFlLm93bmVyRG9jdW1lbnQuZGVmYXVsdFZpZXcpcmV0dXJuIG51bGw7dHJ5e3JldHVybiBlLm93bmVyRG9jdW1lbnQuZGVmYXVsdFZpZXcuZnJhbWVFbGVtZW50fWNhdGNoe3JldHVybiBudWxsfX0pKGUpO3JldHVybiEhdCYmKHQuY2xpZW50SGVpZ2h0PGUuc2Nyb2xsSGVpZ2h0fHx0LmNsaWVudFdpZHRoPGUuc2Nyb2xsV2lkdGgpfSkoZSl9cmV0dXJuITF9LFg9KGUsdCxsLG8sbixyLGkscyk9PnI8ZSYmaT50fHxyPmUmJmk8dD8wOnI8PWUmJnM8PWx8fGk+PXQmJnM+PWw/ci1lLW86aT50JiZzPGx8fHI8ZSYmcz5sP2ktdCtuOjAsJD1lPT5lLnBhcmVudEVsZW1lbnQ/PyhlLmdldFJvb3ROb2RlKCkuaG9zdHx8bnVsbCksdHQ9KGUsdCk9Pnt2YXIgbCxvLG4scjtpZih0eXBlb2YgZG9jdW1lbnQ+InUiKXJldHVybltdO2xldHtzY3JvbGxNb2RlOmksYmxvY2s6cyxpbmxpbmU6YSxib3VuZGFyeTpoLHNraXBPdmVyZmxvd0hpZGRlbkVsZW1lbnRzOnV9PXQsZz0iZnVuY3Rpb24iPT10eXBlb2YgaD9oOmU9PmUhPT1oO2lmKCFRKGUpKXRocm93IFR5cGVFcnJvcigiSW52YWxpZCB0YXJnZXQiKTtsZXQgdj1kb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50fHxkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsbT1bXSx3PWU7Zm9yKDtRKHcpJiZnKHcpOyl7aWYoKHc9JCh3KSk9PT12KXttLnB1c2godyk7YnJlYWt9bnVsbCE9dyYmdz09PWRvY3VtZW50LmJvZHkmJkEodykmJiFBKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCl8fG51bGwhPXcmJkEodyx1KSYmbS5wdXNoKHcpfWxldCBXPW51bGwhPShvPW51bGw9PShsPXdpbmRvdy52aXN1YWxWaWV3cG9ydCk/dm9pZCAwOmwud2lkdGgpP286aW5uZXJXaWR0aCxIPW51bGwhPShyPW51bGw9PShuPXdpbmRvdy52aXN1YWxWaWV3cG9ydCk/dm9pZCAwOm4uaGVpZ2h0KT9yOmlubmVySGVpZ2h0LHtzY3JvbGxYOl8sc2Nyb2xsWTp4fT13aW5kb3cse2hlaWdodDpFLHdpZHRoOlQsdG9wOk4scmlnaHQ6TCxib3R0b206WSxsZWZ0OkN9PWUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksUj0ic3RhcnQiPT09c3x8Im5lYXJlc3QiPT09cz9OOiJlbmQiPT09cz9ZOk4rRS8yLFY9ImNlbnRlciI9PT1hP0MrVC8yOiJlbmQiPT09YT9MOkMsQj1bXTtmb3IobGV0IEQ9MDtEPG0ubGVuZ3RoO0QrKyl7bGV0IE89bVtEXSx7aGVpZ2h0Omosd2lkdGg6SSx0b3A6UyxyaWdodDpxLGJvdHRvbTp6LGxlZnQ6Rn09Ty5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtpZigiaWYtbmVlZGVkIj09PWkmJk4+PTAmJkM+PTAmJlk8PUgmJkw8PVcmJk4+PVMmJlk8PXomJkM+PUYmJkw8PXEpYnJlYWs7bGV0IEc9Z2V0Q29tcHV0ZWRTdHlsZShPKSxKPXBhcnNlSW50KEcuYm9yZGVyTGVmdFdpZHRoLDEwKSxLPXBhcnNlSW50KEcuYm9yZGVyVG9wV2lkdGgsMTApLFA9cGFyc2VJbnQoRy5ib3JkZXJSaWdodFdpZHRoLDEwKSxaPXBhcnNlSW50KEcuYm9yZGVyQm90dG9tV2lkdGgsMTApLGVlPTAsZXQ9MCxlbD0ib2Zmc2V0V2lkdGgiaW4gTz9PLm9mZnNldFdpZHRoLU8uY2xpZW50V2lkdGgtSi1QOjAsZW89Im9mZnNldEhlaWdodCJpbiBPP08ub2Zmc2V0SGVpZ2h0LU8uY2xpZW50SGVpZ2h0LUstWjowLGVuPSJvZmZzZXRXaWR0aCJpbiBPPzA9PT1PLm9mZnNldFdpZHRoPzA6SS9PLm9mZnNldFdpZHRoOjAsZXI9Im9mZnNldEhlaWdodCJpbiBPPzA9PT1PLm9mZnNldEhlaWdodD8wOmovTy5vZmZzZXRIZWlnaHQ6MDtpZih2PT09TyllZT0ic3RhcnQiPT09cz9SOiJlbmQiPT09cz9SLUg6Im5lYXJlc3QiPT09cz9YKHgseCtILEgsSyxaLHgrUix4K1IrRSxFKTpSLUgvMixldD0ic3RhcnQiPT09YT9WOiJjZW50ZXIiPT09YT9WLVcvMjoiZW5kIj09PWE/Vi1XOlgoXyxfK1csVyxKLFAsXytWLF8rVitULFQpLGVlPU1hdGgubWF4KDAsZWUreCksZXQ9TWF0aC5tYXgoMCxldCtfKTtlbHNle2VlPSJzdGFydCI9PT1zP1ItUy1LOiJlbmQiPT09cz9SLXorWitlbzoibmVhcmVzdCI9PT1zP1goUyx6LGosSyxaK2VvLFIsUitFLEUpOlItKFMrai8yKStlby8yLGV0PSJzdGFydCI9PT1hP1YtRi1KOiJjZW50ZXIiPT09YT9WLShGK0kvMikrZWwvMjoiZW5kIj09PWE/Vi1xK1ArZWw6WChGLHEsSSxKLFArZWwsVixWK1QsVCk7bGV0e3Njcm9sbExlZnQ6ZWksc2Nyb2xsVG9wOmVkfT1PO2VlPU1hdGgubWF4KDAsTWF0aC5taW4oZWQrZWUvZXIsTy5zY3JvbGxIZWlnaHQtai9lcitlbykpLGV0PU1hdGgubWF4KDAsTWF0aC5taW4oZWkrZXQvZW4sTy5zY3JvbGxXaWR0aC1JL2VuK2VsKSksUis9ZWQtZWUsVis9ZWktZXR9Qi5wdXNoKHtlbDpPLHRvcDplZSxsZWZ0OmV0fSl9cmV0dXJuIEJ9LGY9ZT0+e3ZhciB0O3JldHVybiExPT09ZT97YmxvY2s6ImVuZCIsaW5saW5lOiJuZWFyZXN0In06KHQ9ZSk9PT1PYmplY3QodCkmJjAhPT1PYmplY3Qua2V5cyh0KS5sZW5ndGg/ZTp7YmxvY2s6InN0YXJ0IixpbmxpbmU6Im5lYXJlc3QifX07ZnVuY3Rpb24gYyhlLHQpe3ZhciBsO2lmKCFlLmlzQ29ubmVjdGVkfHwhKGU9PntsZXQgdD1lO2Zvcig7dCYmdC5wYXJlbnROb2RlOyl7aWYodC5wYXJlbnROb2RlPT09ZG9jdW1lbnQpcmV0dXJuITA7dD10LnBhcmVudE5vZGUgaW5zdGFuY2VvZiBTaGFkb3dSb290P3QucGFyZW50Tm9kZS5ob3N0OnQucGFyZW50Tm9kZX1yZXR1cm4hMX0pKGUpKXJldHVybjtpZigib2JqZWN0Ij09dHlwZW9mKGw9dCkmJiJmdW5jdGlvbiI9PXR5cGVvZiBsLmJlaGF2aW9yKXJldHVybiB0LmJlaGF2aW9yKHR0KGUsdCkpO2xldCBvPSJib29sZWFuIj09dHlwZW9mIHR8fG51bGw9PXQ/dm9pZCAwOnQuYmVoYXZpb3I7Zm9yKGxldHtlbDpuLHRvcDpyLGxlZnQ6aX1vZiB0dChlLGYodCkpKW4uc2Nyb2xsKHt0b3A6cixsZWZ0OmksYmVoYXZpb3I6b30pfXZhciBkLHA9KCk9PihkfHwoZD0icGVyZm9ybWFuY2UiaW4gd2luZG93P3BlcmZvcm1hbmNlLm5vdy5iaW5kKHBlcmZvcm1hbmNlKTpEYXRlLm5vdyksZCgpKTtmdW5jdGlvbiBiKGUpe2xldCB0PU1hdGgubWluKChwKCktZS5zdGFydFRpbWUpL2UuZHVyYXRpb24sMSksbD1lLmVhc2UodCksbz1lLnN0YXJ0WCsoZS54LWUuc3RhcnRYKSpsLG49ZS5zdGFydFkrKGUueS1lLnN0YXJ0WSkqbDtlLm1ldGhvZChvLG4sdCxsKSxvIT09ZS54fHxuIT09ZS55P3JlcXVlc3RBbmltYXRpb25GcmFtZSgoKT0+YihlKSk6ZS5jYigpfWZ1bmN0aW9uIHkoZSx0LGwpe2xldCBvPWFyZ3VtZW50cy5sZW5ndGg+MyYmdm9pZCAwIT09YXJndW1lbnRzWzNdP2FyZ3VtZW50c1szXTo2MDAsbj1hcmd1bWVudHMubGVuZ3RoPjQmJnZvaWQgMCE9PWFyZ3VtZW50c1s0XT9hcmd1bWVudHNbNF06ZT0+MSstLWUqZSplKmUqZSxyPWFyZ3VtZW50cy5sZW5ndGg+NT9hcmd1bWVudHNbNV06dm9pZCAwLGk9YXJndW1lbnRzLmxlbmd0aD42P2FyZ3VtZW50c1s2XTp2b2lkIDAscz1lLnNjcm9sbExlZnQsYT1lLnNjcm9sbFRvcDtiKHtzY3JvbGxhYmxlOmUsbWV0aG9kKHQsbCxvLG4pe2xldCByPU1hdGguY2VpbCh0KSxzPU1hdGguY2VpbChsKTtlLnNjcm9sbExlZnQ9cixlLnNjcm9sbFRvcD1zLGk/Lih7dGFyZ2V0OmUsZWxhcHNlZDpvLHZhbHVlOm4sbGVmdDpyLHRvcDpzfSl9LHN0YXJ0VGltZTpwKCksc3RhcnRYOnMsc3RhcnRZOmEseDp0LHk6bCxkdXJhdGlvbjpvLGVhc2U6bixjYjpyfSl9dmFyIE09ZT0+ZSYmIWUuYmVoYXZpb3J8fCJzbW9vdGgiPT09ZS5iZWhhdmlvcixrPWZ1bmN0aW9uKGUsdCl7bGV0IGw9dHx8e307cmV0dXJuIE0obCk/YyhlLHtibG9jazpsLmJsb2NrLGlubGluZTpsLmlubGluZSxzY3JvbGxNb2RlOmwuc2Nyb2xsTW9kZSxib3VuZGFyeTpsLmJvdW5kYXJ5LHNraXBPdmVyZmxvd0hpZGRlbkVsZW1lbnRzOmwuc2tpcE92ZXJmbG93SGlkZGVuRWxlbWVudHMsYmVoYXZpb3I6ZT0+UHJvbWlzZS5hbGwoZS5yZWR1Y2UoKGUsdCk9PntsZXR7ZWw6byxsZWZ0Om4sdG9wOnJ9PXQsaT1vLnNjcm9sbExlZnQscz1vLnNjcm9sbFRvcDtyZXR1cm4gaT09PW4mJnM9PT1yP2U6Wy4uLmUsbmV3IFByb21pc2UoZT0+eShvLG4scixsLmR1cmF0aW9uLGwuZWFzZSwoKT0+ZSh7ZWw6byxsZWZ0OltpLG5dLHRvcDpbcyxyXX0pLGwub25TY3JvbGxDaGFuZ2UpKV19LFtdKSl9KTpQcm9taXNlLnJlc29sdmUoYyhlLHQpKX07ZXhwb3J0e2sgYXMgZGVmYXVsdH07")

const indent = true
const aside = true
const title_text = "Table of Contents"
const include_definitions = false


const tocNode = html`<nav class="plutoui-toc">
	<header>
	 <span class="toc-toggle open-toc"></span>
	 <span class="toc-toggle closed-toc"></span>
	 ${title_text}
	</header>
	<section></section>
</nav>`

tocNode.classList.toggle("aside", aside)
tocNode.classList.toggle("indent", indent)


const getParentCell = el => el.closest("pluto-cell")

const getHeaders = () => {
	const depth = Math.max(1, Math.min(6, 3)) // should be in range 1:6
	const range = Array.from({length: depth}, (x, i) => i+1) // [1, ..., depth]
	
	const selector = [
		...(include_definitions ? [
			`pluto-notebook pluto-cell .pluto-docs-binding`, 
			`pluto-notebook pluto-cell assignee:not(:empty)`, 
		] : []),
		...range.map(i => `pluto-notebook pluto-cell h${i}`)
	].join(",")
	return Array.from(document.querySelectorAll(selector)).filter(el => 
		// exclude headers inside of a pluto-docs-binding block
		!(el.nodeName.startsWith("H") && el.closest(".pluto-docs-binding"))
	)
}


const document_click_handler = (event) => {
	const path = (event.path || event.composedPath())
	const toc = path.find(elem => elem?.classList?.contains?.("toc-toggle"))
	if (toc) {
		event.stopImmediatePropagation()
		toc.closest(".plutoui-toc").classList.toggle("hide")
	}
}

document.addEventListener("click", document_click_handler)


const header_to_index_entry_map = new Map()
const currently_highlighted_set = new Set()

const last_toc_element_click_time = { current: 0 }

const intersection_callback = (ixs) => {
	let on_top = ixs.filter(ix => ix.intersectionRatio > 0 && ix.intersectionRect.y < ix.rootBounds.height / 2)
	if(on_top.length > 0){
		currently_highlighted_set.forEach(a => a.classList.remove("in-view"))
		currently_highlighted_set.clear()
		on_top.slice(0,1).forEach(i => {
			let div = header_to_index_entry_map.get(i.target)
			div.classList.add("in-view")
			currently_highlighted_set.add(div)
			
			/// scroll into view
			/*
			const toc_height = tocNode.offsetHeight
			const div_pos = div.offsetTop
			const div_height = div.offsetHeight
			const current_scroll = tocNode.scrollTop
			const header_height = tocNode.querySelector("header").offsetHeight
			
			const scroll_to_top = div_pos - header_height
			const scroll_to_bottom = div_pos + div_height - toc_height
			
			// if we set a scrollTop, then the browser will stop any currently ongoing smoothscroll animation. So let's only do this if you are not currently in a smoothscroll.
			if(Date.now() - last_toc_element_click_time.current >= 2000)
				if(current_scroll < scroll_to_bottom){
					tocNode.scrollTop = scroll_to_bottom
				} else if(current_scroll > scroll_to_top){
					tocNode.scrollTop = scroll_to_top
				}
			*/
		})
	}
}
let intersection_observer_1 = new IntersectionObserver(intersection_callback, {
	root: null, // i.e. the viewport
  	threshold: 1,
	rootMargin: "-15px", // slightly smaller than the viewport
	// delay: 100,
})
let intersection_observer_2 = new IntersectionObserver(intersection_callback, {
	root: null, // i.e. the viewport
  	threshold: 1,
	rootMargin: "15px", // slightly larger than the viewport
	// delay: 100,
})

const render = (elements) => {
	header_to_index_entry_map.clear()
	currently_highlighted_set.clear()
	intersection_observer_1.disconnect()
	intersection_observer_2.disconnect()

		let last_level = `H1`
	return html`${elements.map(h => {
	const parent_cell = getParentCell(h)

		let [className, title_el] = h.matches(`.pluto-docs-binding`) ? ["pluto-docs-binding-el", h.firstElementChild] : [h.nodeName, h]

	const a = html`<a 
		class="${className}" 
		title="${title_el.innerText}"
		href="#${parent_cell.id}"
	>${title_el.innerHTML}</a>`
	/* a.onmouseover=()=>{
		parent_cell.firstElementChild.classList.add(
			'highlight-pluto-cell-shoulder'
		)
	}
	a.onmouseout=() => {
		parent_cell.firstElementChild.classList.remove(
			'highlight-pluto-cell-shoulder'
		)
	} */
		
		
	a.onclick=(e) => {
		e.preventDefault();
		last_toc_element_click_time.current = Date.now()
		scrollIntoView(h, {
			behavior: 'smooth', 
			block: 'start',
		}).then(() => 
			// sometimes it doesn't scroll to the right place
			// solution: try a second time!
			scrollIntoView(h, {
				behavior: 'smooth', 
				block: 'start',
			})
	   )
	}

	const row =  html`<div class="toc-row ${className} after-${last_level}">${a}</div>`
		intersection_observer_1.observe(title_el)
		intersection_observer_2.observe(title_el)
		header_to_index_entry_map.set(title_el, row)

	if(className.startsWith("H"))
		last_level = className
		
	return row
})}`
}

const invalidated = { current: false }

const updateCallback = () => {
	if (!invalidated.current) {
		tocNode.querySelector("section").replaceWith(
			html`<section>${render(getHeaders())}</section>`
		)
	}
}
updateCallback()
setTimeout(updateCallback, 100)
setTimeout(updateCallback, 1000)
setTimeout(updateCallback, 5000)

const notebook = document.querySelector("pluto-notebook")


// We have a mutationobserver for each cell:
const mut_observers = {
	current: [],
}

const createCellObservers = () => {
	mut_observers.current.forEach((o) => o.disconnect())
	mut_observers.current = Array.from(notebook.querySelectorAll("pluto-cell")).map(el => {
		const o = new MutationObserver(updateCallback)
		o.observe(el, {attributeFilter: ["class"]})
		return o
	})
}
createCellObservers()

// And one for the notebook's child list, which updates our cell observers:
const notebookObserver = new MutationObserver(() => {
	updateCallback()
	createCellObservers()
})
notebookObserver.observe(notebook, {childList: true})

// And finally, an observer for the document.body classList, to make sure that the toc also works when it is loaded during notebook initialization
const bodyClassObserver = new MutationObserver(updateCallback)
bodyClassObserver.observe(document.body, {attributeFilter: ["class"]})

// Hide/show the ToC when the screen gets small
let match_listener = () => 
	tocNode.classList.toggle("hide", (tocNode.closest("pluto-editor") ?? document.body).scrollWidth < 1000)
for(let s of [1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000]) {
	let m = matchMedia(`(max-width: ${s}px)`)
	m.addListener(match_listener)
	invalidation.then(() => m.removeListener(match_listener))
}
match_listener()

invalidation.then(() => {
	invalidated.current = true
	intersection_observer_1.disconnect()
	intersection_observer_2.disconnect()
	notebookObserver.disconnect()
	bodyClassObserver.disconnect()
	mut_observers.current.forEach((o) => o.disconnect())
	document.removeEventListener("click", document_click_handler)
})

return tocNode
</script>
<style>
@media not print {

.plutoui-toc {
	font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Cantarell, "Apple Color Emoji",
		"Segoe UI Emoji", "Segoe UI Symbol", system-ui, sans-serif;
	--main-bg-color: #fafafa;
	--pluto-output-color: hsl(0, 0%, 36%);
	--pluto-output-h-color: hsl(0, 0%, 21%);
	--sidebar-li-active-bg: rgb(235, 235, 235);
	--icon-filter: unset;
}

@media (prefers-color-scheme: dark) {
	.plutoui-toc {
		--main-bg-color: #303030;
		--pluto-output-color: hsl(0, 0%, 90%);
		--pluto-output-h-color: hsl(0, 0%, 97%);
		--sidebar-li-active-bg: rgb(82, 82, 82);
		--icon-filter: invert(1);
	}
}

.plutoui-toc.aside {
	color: var(--pluto-output-color);
	position: fixed;
	right: 1rem;
	top: 5rem;
	width: min(80vw, 300px);
	padding: 0.5rem;
	padding-top: 0em;
	/* border: 3px solid rgba(0, 0, 0, 0.15); */
	border-radius: 10px;
	/* box-shadow: 0 0 11px 0px #00000010; */
	max-height: calc(100vh - 5rem - 90px);
	overflow: auto;
	z-index: 40;
	background-color: var(--main-bg-color);
	transition: transform 300ms cubic-bezier(0.18, 0.89, 0.45, 1.12);
}

.plutoui-toc.aside.hide {
	transform: translateX(calc(100% - 28px));
}
.plutoui-toc.aside.hide section {
	display: none;
}
.plutoui-toc.aside.hide header {
	margin-bottom: 0em;
	padding-bottom: 0em;
	border-bottom: none;
}
}  /* End of Media print query */
.plutoui-toc.aside.hide .open-toc,
.plutoui-toc.aside:not(.hide) .closed-toc,
.plutoui-toc:not(.aside) .closed-toc {
	display: none;
}

@media (prefers-reduced-motion) {
  .plutoui-toc.aside {
	transition-duration: 0s;
  }
}

.toc-toggle {
	cursor: pointer;
    padding: 1em;
    margin: -1em;
    margin-right: -0.7em;
    line-height: 1em;
    display: flex;
}

.toc-toggle::before {
    content: "";
    display: inline-block;
    height: 1em;
    width: 1em;
    background-image: url("https://cdn.jsdelivr.net/gh/ionic-team/ionicons@5.5.1/src/svg/list-outline.svg");
	/* generated using https://dopiaza.org/tools/datauri/index.php */
    background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MTIiIGhlaWdodD0iNTEyIiB2aWV3Qm94PSIwIDAgNTEyIDUxMiI+PHRpdGxlPmlvbmljb25zLXY1LW88L3RpdGxlPjxsaW5lIHgxPSIxNjAiIHkxPSIxNDQiIHgyPSI0NDgiIHkyPSIxNDQiIHN0eWxlPSJmaWxsOm5vbmU7c3Ryb2tlOiMwMDA7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS13aWR0aDozMnB4Ii8+PGxpbmUgeDE9IjE2MCIgeTE9IjI1NiIgeDI9IjQ0OCIgeTI9IjI1NiIgc3R5bGU9ImZpbGw6bm9uZTtzdHJva2U6IzAwMDtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLXdpZHRoOjMycHgiLz48bGluZSB4MT0iMTYwIiB5MT0iMzY4IiB4Mj0iNDQ4IiB5Mj0iMzY4IiBzdHlsZT0iZmlsbDpub25lO3N0cm9rZTojMDAwO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2Utd2lkdGg6MzJweCIvPjxjaXJjbGUgY3g9IjgwIiBjeT0iMTQ0IiByPSIxNiIgc3R5bGU9ImZpbGw6bm9uZTtzdHJva2U6IzAwMDtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLXdpZHRoOjMycHgiLz48Y2lyY2xlIGN4PSI4MCIgY3k9IjI1NiIgcj0iMTYiIHN0eWxlPSJmaWxsOm5vbmU7c3Ryb2tlOiMwMDA7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS13aWR0aDozMnB4Ii8+PGNpcmNsZSBjeD0iODAiIGN5PSIzNjgiIHI9IjE2IiBzdHlsZT0iZmlsbDpub25lO3N0cm9rZTojMDAwO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2Utd2lkdGg6MzJweCIvPjwvc3ZnPg==");
    background-size: 1em;
	filter: var(--icon-filter);
}

.aside .toc-toggle.open-toc:hover::before {
    background-image: url("https://cdn.jsdelivr.net/gh/ionic-team/ionicons@5.5.1/src/svg/arrow-forward-outline.svg");
	/* generated using https://dopiaza.org/tools/datauri/index.php */
    background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MTIiIGhlaWdodD0iNTEyIiB2aWV3Qm94PSIwIDAgNTEyIDUxMiI+PHRpdGxlPmlvbmljb25zLXY1LWE8L3RpdGxlPjxwb2x5bGluZSBwb2ludHM9IjI2OCAxMTIgNDEyIDI1NiAyNjggNDAwIiBzdHlsZT0iZmlsbDpub25lO3N0cm9rZTojMDAwO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2Utd2lkdGg6NDhweCIvPjxsaW5lIHgxPSIzOTIiIHkxPSIyNTYiIHgyPSIxMDAiIHkyPSIyNTYiIHN0eWxlPSJmaWxsOm5vbmU7c3Ryb2tlOiMwMDA7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS13aWR0aDo0OHB4Ii8+PC9zdmc+");
}
.aside .toc-toggle.closed-toc:hover::before {
    background-image: url("https://cdn.jsdelivr.net/gh/ionic-team/ionicons@5.5.1/src/svg/arrow-back-outline.svg");
	/* generated using https://dopiaza.org/tools/datauri/index.php */
    background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MTIiIGhlaWdodD0iNTEyIiB2aWV3Qm94PSIwIDAgNTEyIDUxMiI+PHRpdGxlPmlvbmljb25zLXY1LWE8L3RpdGxlPjxwb2x5bGluZSBwb2ludHM9IjI0NCA0MDAgMTAwIDI1NiAyNDQgMTEyIiBzdHlsZT0iZmlsbDpub25lO3N0cm9rZTojMDAwO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2Utd2lkdGg6NDhweCIvPjxsaW5lIHgxPSIxMjAiIHkxPSIyNTYiIHgyPSI0MTIiIHkyPSIyNTYiIHN0eWxlPSJmaWxsOm5vbmU7c3Ryb2tlOiMwMDA7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS13aWR0aDo0OHB4Ii8+PC9zdmc+");
}



.plutoui-toc header {
	display: flex;
	align-items: center;
	gap: .3em;
	font-size: 1.5em;
	/* margin-top: -0.1em; */
	margin-bottom: 0.4em;
	padding: 0.5rem;
	margin-left: 0;
	margin-right: 0;
	font-weight: bold;
	/* border-bottom: 2px solid rgba(0, 0, 0, 0.15); */
	position: sticky;
	top: 0px;
	background: var(--main-bg-color);
	z-index: 41;
}
.plutoui-toc.aside header {
	padding-left: 0;
	padding-right: 0;
}

.plutoui-toc section .toc-row {
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	padding: .1em;
	border-radius: .2em;
}

.plutoui-toc section .toc-row.H1 {
	margin-top: 1em;
}


.plutoui-toc.aside section .toc-row.in-view {
	background: var(--sidebar-li-active-bg);
}


	
.highlight-pluto-cell-shoulder {
	background: rgba(0, 0, 0, 0.05);
	background-clip: padding-box;
}

.plutoui-toc section a {
	text-decoration: none;
	font-weight: normal;
	color: var(--pluto-output-color);
}
.plutoui-toc section a:hover {
	color: var(--pluto-output-h-color);
}

.plutoui-toc.indent section a.H1 {
	font-weight: 700;
	line-height: 1em;
}

.plutoui-toc.indent section .after-H2 a { padding-left: 10px; }
.plutoui-toc.indent section .after-H3 a { padding-left: 20px; }
.plutoui-toc.indent section .after-H4 a { padding-left: 30px; }
.plutoui-toc.indent section .after-H5 a { padding-left: 40px; }
.plutoui-toc.indent section .after-H6 a { padding-left: 50px; }

.plutoui-toc.indent section a.H1 { padding-left: 0px; }
.plutoui-toc.indent section a.H2 { padding-left: 10px; }
.plutoui-toc.indent section a.H3 { padding-left: 20px; }
.plutoui-toc.indent section a.H4 { padding-left: 30px; }
.plutoui-toc.indent section a.H5 { padding-left: 40px; }
.plutoui-toc.indent section a.H6 { padding-left: 50px; }


.plutoui-toc.indent section a.pluto-docs-binding-el,
.plutoui-toc.indent section a.ASSIGNEE
	{
	font-family: JuliaMono, monospace;
	font-size: .8em;
	/* background: black; */
	font-weight: 700;
    font-style: italic;
	color: var(--cm-var-color); /* this is stealing a variable from Pluto, but it's fine if that doesnt work */
}
.plutoui-toc.indent section a.pluto-docs-binding-el::before,
.plutoui-toc.indent section a.ASSIGNEE::before
	{
	content: "> ";
	opacity: .3;
}
</style>
mimetext/htmlrootassigneelast_run_timestampA$6)persist_js_state·has_pluto_hook_features§cell_id$77cf7fee-0ad8-4d22-b376-75833307db93depends_on_disabled_cells§runtime!published_object_keysdepends_on_skipped_cells§errored$d11bfcf9-b964-4c67-afdc-53d81f051fd5queued¤logsrunning¦outputbody4monte_carlo_pred_V (generic function with 2 methods)mimetext/plainrootassigneelast_run_timestampA)k.ذpersist_js_state·has_pluto_hook_features§cell_id$d11bfcf9-b964-4c67-afdc-53d81f051fd5depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cells§errored$19e42f50-5301-41b9-becb-2368c26b6236queued¤logsrunning¦outputbody1.9652f0mimetext/plainrootassigneelast_run_timestampA-}persist_js_state·has_pluto_hook_features§cell_id$19e42f50-5301-41b9-becb-2368c26b6236depends_on_disabled_cells§runtimePɵpublished_object_keysdepends_on_skipped_cells§errored$924f4e74-e3a0-42eb-89da-1f9836275588queued¤logsrunning¦outputbody6off_policy_MC_control (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA.2°persist_js_state·has_pluto_hook_features§cell_id$924f4e74-e3a0-42eb-89da-1f9836275588depends_on_disabled_cells§runtime R=published_object_keysdepends_on_skipped_cells§errored$6dc0de46-2164-4580-b186-a73cb5b5167dqueued¤logsrunning¦outputbody-project_path (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA/Kpersist_js_state·has_pluto_hook_features§cell_id$6dc0de46-2164-4580-b186-a73cb5b5167ddepends_on_disabled_cells§runtime 1published_object_keysdepends_on_skipped_cells§errored$63814164-f305-49b3-ab51-675c822d7b18queued¤logsrunning¦outputbodyprefixTuple{Int64, Int64}elements elements0text/plain0text/plaintypeTupleobjectid9b52efd7a2a08bd5!application/vnd.pluto.tree+objectelements0text/plain1text/plaintypeTupleobjectid86128cc9b5ae8f4a!application/vnd.pluto.tree+objectelements0text/plain2text/plaintypeTupleobjectidfc41ae7a664555b0!application/vnd.pluto.tree+objectelements0text/plain3text/plaintypeTupleobjectid5a8d0f981b76571a!application/vnd.pluto.tree+objectelements0text/plain4text/plaintypeTupleobjectid6ac4b5902680c6bb!application/vnd.pluto.tree+objectelements1text/plain0text/plaintypeTupleobjectid1539b04621ff8c7d!application/vnd.pluto.tree+objectelements1text/plain1text/plaintypeTupleobjectid78e123e4f427692a!application/vnd.pluto.tree+objectelements1text/plain2text/plaintypeTupleobjectide3e6b1884080a98d!application/vnd.pluto.tree+object	elements1text/plain3text/plaintypeTupleobjectid7d75a9159c58bddf!application/vnd.pluto.tree+object
elements1text/plain4text/plaintypeTupleobjectid3258627267de1f67!application/vnd.pluto.tree+objectelements2text/plain0text/plaintypeTupleobjectid83bf2aef4031930b!application/vnd.pluto.tree+objectelements2text/plain1text/plaintypeTupleobjectidef30e57ac248f6d7!application/vnd.pluto.tree+objectelements2text/plain2text/plaintypeTupleobjectid74f4975686c560b8!application/vnd.pluto.tree+objectelements2text/plain3text/plaintypeTupleobjectid166e372c63abd549!application/vnd.pluto.tree+objectelements2text/plain4text/plaintypeTupleobjectidfe67fb157b710308!application/vnd.pluto.tree+objectelements3text/plain0text/plaintypeTupleobjectidaa4c36dcad24fa29!application/vnd.pluto.tree+objectelements3text/plain1text/plaintypeTupleobjectidec7c7c340006434b!application/vnd.pluto.tree+objectelements3text/plain2text/plaintypeTupleobjectidc1258421771ca213!application/vnd.pluto.tree+objectelements3text/plain3text/plaintypeTupleobjectid3ed622ab32dfec93!application/vnd.pluto.tree+objectelements3text/plain4text/plaintypeTupleobjectid441bcd44d2e6073b!application/vnd.pluto.tree+objectelements4text/plain0text/plaintypeTupleobjectidc772df2bb869c6b4!application/vnd.pluto.tree+objectelements4text/plain1text/plaintypeTupleobjectidab958923df88f7e9!application/vnd.pluto.tree+objectelements4text/plain2text/plaintypeTupleobjectid27c77ee4a87cee0d!application/vnd.pluto.tree+objectelements4text/plain3text/plaintypeTupleobjectided8ab7e3922a8b9f!application/vnd.pluto.tree+objectelements4text/plain4text/plaintypeTupleobjectida7048b0d6f799239!application/vnd.pluto.tree+objecttypeArrayprefix_shortobjectidf9ad86173c46f993mime!application/vnd.pluto.tree+objectrootassigneeconst racetrack_velocitieslast_run_timestampA/Ơpersist_js_state·has_pluto_hook_features§cell_id$63814164-f305-49b3-ab51-675c822d7b18depends_on_disabled_cells§runtime]ϵpublished_object_keysdepends_on_skipped_cells§errored$4337b83f-b648-4b55-9d2a-4fffcf701111queued¤logsrunning¦outputbodyٺ<style>
	main {
		margin: 0 auto;
		max-width: min(2000px, 90%);
    	padding-left: max(10px, 5%);
    	padding-right: max(10px, 5%);
		font-size: max(10px, min(18px, 2vw));
	}
</style>
mimetext/htmlrootassigneelast_run_timestampA",Yqpersist_js_state·has_pluto_hook_features§cell_id$4337b83f-b648-4b55-9d2a-4fffcf701111depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$1b78b25d-3942-4a6b-a2bd-7d97242da9fequeued¤logsrunning¦outputbody0monte_carlo_ES (generic function with 2 methods)mimetext/plainrootassigneelast_run_timestampA%persist_js_state·has_pluto_hook_features§cell_id$1b78b25d-3942-4a6b-a2bd-7d97242da9fedepends_on_disabled_cells§runtime +published_object_keysdepends_on_skipped_cells§errored$9524a3f5-fca3-4ce9-b04d-0cb6c0cd0c90queued¤logsrunning¦outputbody+	<div style = "display: flex;">
	<div>
Race finished in 6619 steps
<div style="background-color: white; color: black;">
	<div style="display:flex; align-items: flex-start">
	<div class = "track">
		<div class = "start" vx = "0" vy = "0" dvx = "-1" dvy = "0" style="grid-column-start: 4; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "0" dvy = "-1" style="grid-column-start: 8; grid-row-start: 1;"></div><div class = "start" vx = "1" vy = "0" dvx = "-1" dvy = "0" style="grid-column-start: 9; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "0" dvy = "-1" style="grid-column-start: 6; grid-row-start: 1;"></div><div class = "start" vx = "1" vy = "0" dvx = "-1" dvy = "-1" style="grid-column-start: 7; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "1" dvy = "1" style="grid-column-start: 5; grid-row-start: 1;"></div><div class = "" vx = "0" vy = "4" dvx = "0" dvy = "0" style="grid-column-start: 5; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 5;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "0" style="grid-column-start: 6; grid-row-start: 27;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "1" style="grid-column-start: 9; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 18;"></div><div class = "" vx = "2" vy = "4" dvx = "1" dvy = "1" style="grid-column-start: 10; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 22;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "-1" style="grid-column-start: 8; grid-row-start: 24;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "1" style="grid-column-start: 7; grid-row-start: 14;"></div><div class = "" vx = "1" vy = "1" dvx = "-1" dvy = "-1" style="grid-column-start: 10; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 27;"></div><div class = "" vx = "0" vy = "3" dvx = "1" dvy = "1" style="grid-column-start: 5; grid-row-start: 11;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "-1" style="grid-column-start: 7; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 31;"></div><div class = "" vx = "2" vy = "0" dvx = "0" dvy = "1" style="grid-column-start: 11; grid-row-start: 29;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "1" style="grid-column-start: 6; grid-row-start: 30;"></div><div class = "" vx = "0" vy = "3" dvx = "1" dvy = "1" style="grid-column-start: 6; grid-row-start: 13;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "-1" style="grid-column-start: 8; grid-row-start: 15;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "0" style="grid-column-start: 9; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 24;"></div><div class = "" vx = "1" vy = "2" dvx = "-1" dvy = "-1" style="grid-column-start: 7; grid-row-start: 7;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "-1" style="grid-column-start: 8; grid-row-start: 17;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "-1" style="grid-column-start: 6; grid-row-start: 32;"></div><div class = "" vx = "2" vy = "1" dvx = "-1" dvy = "0" style="grid-column-start: 13; grid-row-start: 30;"></div><div class = "" vx = "0" vy = "4" dvx = "-1" dvy = "-1" style="grid-column-start: 5; grid-row-start: 22;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "-1" style="grid-column-start: 6; grid-row-start: 20;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "-1" style="grid-column-start: 5; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 32;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "1" style="grid-column-start: 8; grid-row-start: 25;"></div><div class = "" vx = "2" vy = "1" dvx = "-1" dvy = "0" style="grid-column-start: 12; grid-row-start: 30;"></div><div class = "" vx = "2" vy = "0" dvx = "0" dvy = "-1" style="grid-column-start: 10; grid-row-start: 26;"></div><div class = "" vx = "0" vy = "4" dvx = "1" dvy = "-1" style="grid-column-start: 9; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 23;"></div><div class = "" vx = "0" vy = "3" dvx = "1" dvy = "-1" style="grid-column-start: 4; grid-row-start: 15;"></div><div class = "" vx = "0" vy = "3" dvx = "1" dvy = "1" style="grid-column-start: 9; grid-row-start: 12;"></div><div class = "" vx = "2" vy = "2" dvx = "0" dvy = "-1" style="grid-column-start: 12; grid-row-start: 32;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "0" style="grid-column-start: 7; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 17;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "0" style="grid-column-start: 6; grid-row-start: 19;"></div><div class = "" vx = "1" vy = "3" dvx = "-1" dvy = "0" style="grid-column-start: 6; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 25;"></div><div class = "" vx = "1" vy = "2" dvx = "0" dvy = "0" style="grid-column-start: 5; grid-row-start: 5;"></div><div class = "" vx = "0" vy = "4" dvx = "-1" dvy = "-1" style="grid-column-start: 6; grid-row-start: 26;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "-1" style="grid-column-start: 6; grid-row-start: 8;"></div><div class = "" vx = "1" vy = "4" dvx = "0" dvy = "1" style="grid-column-start: 8; grid-row-start: 29;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "0" style="grid-column-start: 5; grid-row-start: 23;"></div><div class = "" vx = "1" vy = "0" dvx = "1" dvy = "-1" style="grid-column-start: 9; grid-row-start: 5;"></div><div class = "" vx = "2" vy = "0" dvx = "-1" dvy = "-1" style="grid-column-start: 15; grid-row-start: 29;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 7; grid-row-start: 18;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "0" style="grid-column-start: 9; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 30;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "1" style="grid-column-start: 6; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 29;"></div><div class = "" vx = "1" vy = "0" dvx = "0" dvy = "-1" style="grid-column-start: 10; grid-row-start: 28;"></div><div class = "" vx = "0" vy = "4" dvx = "-1" dvy = "0" style="grid-column-start: 5; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 13;"></div><div class = "" vx = "1" vy = "1" dvx = "-1" dvy = "0" style="grid-column-start: 8; grid-row-start: 11;"></div><div class = "" vx = "1" vy = "2" dvx = "-1" dvy = "1" style="grid-column-start: 6; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 24;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "-1" style="grid-column-start: 9; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 20;"></div><div class = "" vx = "1" vy = "0" dvx = "-1" dvy = "1" style="grid-column-start: 6; grid-row-start: 21;"></div><div class = "" vx = "1" vy = "2" dvx = "0" dvy = "1" style="grid-column-start: 7; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 27;"></div><div class = "" vx = "0" vy = "4" dvx = "-1" dvy = "1" style="grid-column-start: 6; grid-row-start: 28;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "1" style="grid-column-start: 6; grid-row-start: 3;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "-1" style="grid-column-start: 8; grid-row-start: 22;"></div><div class = "" vx = "0" vy = "4" dvx = "1" dvy = "0" style="grid-column-start: 4; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 9;"></div><div class = "" vx = "1" vy = "2" dvx = "-1" dvy = "1" style="grid-column-start: 8; grid-row-start: 12;"></div><div class = "" vx = "2" vy = "0" dvx = "1" dvy = "0" style="grid-column-start: 13; grid-row-start: 28;"></div><div class = "" vx = "1" vy = "2" dvx = "-1" dvy = "1" style="grid-column-start: 11; grid-row-start: 31;"></div><div class = "" vx = "1" vy = "4" dvx = "-1" dvy = "0" style="grid-column-start: 7; grid-row-start: 15;"></div><div class = "" vx = "1" vy = "4" dvx = "-1" dvy = "1" style="grid-column-start: 7; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 26;"></div><div class = "" vx = "0" vy = "4" dvx = "0" dvy = "1" style="grid-column-start: 5; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 25;"></div><div class = "" vx = "1" vy = "2" dvx = "0" dvy = "-1" style="grid-column-start: 6; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 13;"></div><div class = "" vx = "0" vy = "4" dvx = "-1" dvy = "1" style="grid-column-start: 7; grid-row-start: 25;"></div><div class = "" vx = "0" vy = "4" dvx = "1" dvy = "0" style="grid-column-start: 4; grid-row-start: 12;"></div><div class = "" vx = "1" vy = "2" dvx = "1" dvy = "-1" style="grid-column-start: 9; grid-row-start: 27;"></div><div class = "" vx = "1" vy = "0" dvx = "0" dvy = "-1" style="grid-column-start: 8; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 20;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "-1" style="grid-column-start: 8; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 10;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "-1" style="grid-column-start: 6; grid-row-start: 14;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "0" style="grid-column-start: 5; grid-row-start: 30;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "1" style="grid-column-start: 5; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 19;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "1" style="grid-column-start: 4; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 27;"></div><div class = "" vx = "0" vy = "4" dvx = "0" dvy = "0" style="grid-column-start: 7; grid-row-start: 29;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "0" style="grid-column-start: 5; grid-row-start: 32;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 6; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 21;"></div><div class = "" vx = "0" vy = "4" dvx = "1" dvy = "-1" style="grid-column-start: 8; grid-row-start: 31;"></div><div class = "" vx = "0" vy = "4" dvx = "1" dvy = "0" style="grid-column-start: 9; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 23;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "-1" style="grid-column-start: 5; grid-row-start: 20;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "-1" style="grid-column-start: 9; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 28;"></div><div class = "" vx = "2" vy = "0" dvx = "-1" dvy = "-1" style="grid-column-start: 15; grid-row-start: 31;"></div><div class = "" vx = "1" vy = "2" dvx = "1" dvy = "1" style="grid-column-start: 9; grid-row-start: 32;"></div><div class = "" vx = "1" vy = "2" dvx = "0" dvy = "1" style="grid-column-start: 6; grid-row-start: 7;"></div><div class = "" vx = "1" vy = "3" dvx = "1" dvy = "-1" style="grid-column-start: 9; grid-row-start: 20;"></div><div class = "" vx = "1" vy = "2" dvx = "1" dvy = "0" style="grid-column-start: 14; grid-row-start: 31;"></div><div class = "" vx = "1" vy = "0" dvx = "-1" dvy = "-1" style="grid-column-start: 16; grid-row-start: 29;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "-1" style="grid-column-start: 5; grid-row-start: 19;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "0" style="grid-column-start: 5; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 30;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "1" style="grid-column-start: 7; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 6;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "-1" style="grid-column-start: 6; grid-row-start: 16;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "1" style="grid-column-start: 9; grid-row-start: 9;"></div><div class = "" vx = "2" vy = "3" dvx = "1" dvy = "1" style="grid-column-start: 9; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 32;"></div><div class = "" vx = "0" vy = "4" dvx = "0" dvy = "1" style="grid-column-start: 5; grid-row-start: 26;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "0" style="grid-column-start: 5; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 22;"></div><div class = "" vx = "0" vy = "4" dvx = "1" dvy = "1" style="grid-column-start: 7; grid-row-start: 22;"></div><div class = "" vx = "0" vy = "4" dvx = "-1" dvy = "-1" style="grid-column-start: 8; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 21;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "1" style="grid-column-start: 9; grid-row-start: 26;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 9; grid-row-start: 8;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "0" style="grid-column-start: 7; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 14;"></div><div class = "" vx = "0" vy = "3" dvx = "1" dvy = "0" style="grid-column-start: 5; grid-row-start: 10;"></div><div class = "" vx = "0" vy = "3" dvx = "1" dvy = "0" style="grid-column-start: 6; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 27;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "-1" style="grid-column-start: 5; grid-row-start: 4;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "-1" style="grid-column-start: 9; grid-row-start: 10;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "-1" style="grid-column-start: 5; grid-row-start: 21;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "-1" style="grid-column-start: 7; grid-row-start: 5;"></div><div class = "" vx = "0" vy = "3" dvx = "1" dvy = "-1" style="grid-column-start: 8; grid-row-start: 30;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "1" style="grid-column-start: 8; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 7;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 9; grid-row-start: 4;"></div><div class = "" vx = "1" vy = "3" dvx = "-1" dvy = "-1" style="grid-column-start: 8; grid-row-start: 32;"></div><div class = "" vx = "0" vy = "4" dvx = "1" dvy = "1" style="grid-column-start: 7; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 30;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "-1" style="grid-column-start: 5; grid-row-start: 28;"></div><div class = "" vx = "1" vy = "0" dvx = "-1" dvy = "1" style="grid-column-start: 5; grid-row-start: 3;"></div><div class = "" vx = "1" vy = "2" dvx = "1" dvy = "1" style="grid-column-start: 9; grid-row-start: 21;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "0" style="grid-column-start: 8; grid-row-start: 20;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "1" style="grid-column-start: 6; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 32;"></div><div class = "" vx = "1" vy = "1" dvx = "-1" dvy = "0" style="grid-column-start: 9; grid-row-start: 28;"></div><div class = "" vx = "1" vy = "1" dvx = "-1" dvy = "1" style="grid-column-start: 9; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 30;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "1" style="grid-column-start: 14; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 16;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "1" style="grid-column-start: 7; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 32;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 5; grid-row-start: 6;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "0" style="grid-column-start: 8; grid-row-start: 19;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "0" style="grid-column-start: 8; grid-row-start: 9;"></div><div class = "" vx = "0" vy = "4" dvx = "-1" dvy = "-1" style="grid-column-start: 6; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 20;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "-1" style="grid-column-start: 6; grid-row-start: 17;"></div><div class = "" vx = "1" vy = "2" dvx = "-1" dvy = "-1" style="grid-column-start: 9; grid-row-start: 6;"></div><div class = "" vx = "2" vy = "1" dvx = "0" dvy = "-1" style="grid-column-start: 11; grid-row-start: 28;"></div><div class = "" vx = "1" vy = "4" dvx = "1" dvy = "0" style="grid-column-start: 8; grid-row-start: 26;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "1" style="grid-column-start: 8; grid-row-start: 8;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "-1" style="grid-column-start: 6; grid-row-start: 25;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "1" style="grid-column-start: 16; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 19;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "-1" style="grid-column-start: 4; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 18;"></div><div class = "" vx = "2" vy = "2" dvx = "-1" dvy = "0" style="grid-column-start: 10; grid-row-start: 29;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "1" style="grid-column-start: 5; grid-row-start: 14;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "-1" style="grid-column-start: 5; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 27;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "1" style="grid-column-start: 4; grid-row-start: 8;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "-1" style="grid-column-start: 8; grid-row-start: 10;"></div><div class = "" vx = "1" vy = "3" dvx = "0" dvy = "0" style="grid-column-start: 9; grid-row-start: 14;"></div><div class = "" vx = "0" vy = "4" dvx = "-1" dvy = "1" style="grid-column-start: 7; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 16;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "1" style="grid-column-start: 9; grid-row-start: 2;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "-1" style="grid-column-start: 6; grid-row-start: 29;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "1" style="grid-column-start: 5; grid-row-start: 7;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "1" style="grid-column-start: 8; grid-row-start: 4;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "0" style="grid-column-start: 8; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 24;"></div><div class = "" vx = "2" vy = "1" dvx = "-1" dvy = "1" style="grid-column-start: 13; grid-row-start: 29;"></div><div class = "" vx = "1" vy = "3" dvx = "-1" dvy = "-1" style="grid-column-start: 9; grid-row-start: 7;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "-1" style="grid-column-start: 4; grid-row-start: 10;"></div><div class = "" vx = "1" vy = "4" dvx = "0" dvy = "-1" style="grid-column-start: 8; grid-row-start: 28;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "0" style="grid-column-start: 8; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 18;"></div><div class = "" vx = "1" vy = "1" dvx = "1" dvy = "1" style="grid-column-start: 7; grid-row-start: 30;"></div><div class = "" vx = "1" vy = "4" dvx = "1" dvy = "0" style="grid-column-start: 5; grid-row-start: 16;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "0" style="grid-column-start: 4; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 15;"></div><div class = "" vx = "0" vy = "4" dvx = "-1" dvy = "-1" style="grid-column-start: 7; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 17;"></div><div class = "" vx = "0" vy = "4" dvx = "0" dvy = "-1" style="grid-column-start: 6; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 20;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "-1" style="grid-column-start: 9; grid-row-start: 16;"></div><div class = "" vx = "2" vy = "4" dvx = "-1" dvy = "-1" style="grid-column-start: 7; grid-row-start: 20;"></div><div class = "" vx = "1" vy = "1" dvx = "1" dvy = "1" style="grid-column-start: 8; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 28;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "1" style="grid-column-start: 4; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 25;"></div><div class = "" vx = "0" vy = "3" dvx = "1" dvy = "-1" style="grid-column-start: 6; grid-row-start: 22;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "0" style="grid-column-start: 16; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 19;"></div><div class = "" vx = "0" vy = "4" dvx = "0" dvy = "0" style="grid-column-start: 5; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 24;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "1" style="grid-column-start: 6; grid-row-start: 12;"></div><div class = "" vx = "0" vy = "4" dvx = "-1" dvy = "0" style="grid-column-start: 7; grid-row-start: 19;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "0" style="grid-column-start: 7; grid-row-start: 9;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "-1" style="grid-column-start: 16; grid-row-start: 32;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "0" style="grid-column-start: 4; grid-row-start: 6;"></div><div class = "" vx = "1" vy = "3" dvx = "1" dvy = "0" style="grid-column-start: 9; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 26;"></div><div class = "" vx = "0" vy = "4" dvx = "-1" dvy = "-1" style="grid-column-start: 8; grid-row-start: 14;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 7; grid-row-start: 26;"></div><div class = "" vx = "1" vy = "0" dvx = "1" dvy = "-1" style="grid-column-start: 7; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 29;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "1" style="grid-column-start: 8; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 17;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "1" style="grid-column-start: 6; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 24;"></div><div class = "" vx = "1" vy = "4" dvx = "-1" dvy = "0" style="grid-column-start: 10; grid-row-start: 31;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 8; grid-row-start: 7;"></div><div class = "" vx = "0" vy = "3" dvx = "1" dvy = "-1" style="grid-column-start: 4; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 25;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 6; grid-row-start: 23;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "-1" style="grid-column-start: 9; grid-row-start: 24;"></div><div class = "" vx = "1" vy = "3" dvx = "0" dvy = "-1" style="grid-column-start: 7; grid-row-start: 10;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "0" style="grid-column-start: 4; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 11;"></div><div class = "" vx = "1" vy = "4" dvx = "-1" dvy = "0" style="grid-column-start: 5; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 21;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "0" style="grid-column-start: 7; grid-row-start: 4;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "-1" style="grid-column-start: 5; grid-row-start: 17;"></div><div class = "" vx = "0" vy = "4" dvx = "0" dvy = "1" style="grid-column-start: 7; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 31;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "1" style="grid-column-start: 4; grid-row-start: 7;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "-1" style="grid-column-start: 8; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 28;"></div><div class = "" vx = "1" vy = "2" dvx = "0" dvy = "1" style="grid-column-start: 9; grid-row-start: 15;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "0" style="grid-column-start: 5; grid-row-start: 25;"></div><div class = "" vx = "1" vy = "3" dvx = "-1" dvy = "1" style="grid-column-start: 9; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 29;"></div><div class = "" vx = "1" vy = "1" dvx = "0" dvy = "-1" style="grid-column-start: 13; grid-row-start: 31;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "0" style="grid-column-start: 7; grid-row-start: 28;"></div><div class = "" vx = "1" vy = "1" dvx = "-1" dvy = "0" style="grid-column-start: 7; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 12;"></div><div class = "" vx = "0" vy = "4" dvx = "1" dvy = "1" style="grid-column-start: 9; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 27;"></div><div class = "" vx = "2" vy = "1" dvx = "-1" dvy = "-1" style="grid-column-start: 12; grid-row-start: 31;"></div><div class = "" vx = "0" vy = "4" dvx = "1" dvy = "-1" style="grid-column-start: 4; grid-row-start: 16;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "0" style="grid-column-start: 8; grid-row-start: 18;"></div><div class = "" vx = "2" vy = "2" dvx = "0" dvy = "0" style="grid-column-start: 7; grid-row-start: 6;"></div><div class = "" vx = "3" vy = "0" dvx = "1" dvy = "1" style="grid-column-start: 16; grid-row-start: 28;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 28;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 29;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 31;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 30;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 27;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 32;"></div>
	</div>
	Finish <br> line
	</div>
	<div>Starting line</div>
</div>
</div>

	<div>
Race finished in 444 steps
<div style="background-color: white; color: black;">
	<div style="display:flex; align-items: flex-start">
	<div class = "track">
		<div class = "start" vx = "0" vy = "0" dvx = "0" dvy = "1" style="grid-column-start: 4; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "0" dvy = "1" style="grid-column-start: 8; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "-1" dvy = "1" style="grid-column-start: 9; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "0" dvy = "-1" style="grid-column-start: 6; grid-row-start: 1;"></div><div class = "start" vx = "1" vy = "0" dvx = "-1" dvy = "1" style="grid-column-start: 7; grid-row-start: 1;"></div><div class = "start" vx = "0" vy = "0" dvx = "0" dvy = "1" style="grid-column-start: 5; grid-row-start: 1;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 24;"></div><div class = "" vx = "1" vy = "3" dvx = "1" dvy = "1" style="grid-column-start: 7; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 11;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "0" style="grid-column-start: 7; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 15;"></div><div class = "" vx = "0" vy = "4" dvx = "1" dvy = "0" style="grid-column-start: 9; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 24;"></div><div class = "" vx = "0" vy = "3" dvx = "1" dvy = "1" style="grid-column-start: 7; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 26;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "1" style="grid-column-start: 9; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 15;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "1" style="grid-column-start: 9; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 25;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "1" style="grid-column-start: 5; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 26;"></div><div class = "" vx = "1" vy = "3" dvx = "-1" dvy = "-1" style="grid-column-start: 6; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 23;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "-1" style="grid-column-start: 9; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 18;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "-1" style="grid-column-start: 9; grid-row-start: 23;"></div><div class = "" vx = "2" vy = "1" dvx = "-1" dvy = "0" style="grid-column-start: 14; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 30;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "-1" style="grid-column-start: 6; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 29;"></div><div class = "" vx = "1" vy = "0" dvx = "0" dvy = "0" style="grid-column-start: 10; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 13;"></div><div class = "" vx = "1" vy = "4" dvx = "0" dvy = "0" style="grid-column-start: 8; grid-row-start: 11;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "1" style="grid-column-start: 6; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 24;"></div><div class = "" vx = "1" vy = "4" dvx = "1" dvy = "0" style="grid-column-start: 9; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 27;"></div><div class = "" vx = "0" vy = "4" dvx = "-1" dvy = "-1" style="grid-column-start: 6; grid-row-start: 28;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "0" style="grid-column-start: 6; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 9;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "1" style="grid-column-start: 8; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 8;"></div><div class = "" vx = "1" vy = "0" dvx = "1" dvy = "1" style="grid-column-start: 12; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 25;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 6; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 12;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "-1" style="grid-column-start: 9; grid-row-start: 27;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "1" style="grid-column-start: 8; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 20;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "1" style="grid-column-start: 8; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 30;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "0" style="grid-column-start: 5; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 32;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "-1" style="grid-column-start: 6; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 31;"></div><div class = "" vx = "0" vy = "4" dvx = "0" dvy = "1" style="grid-column-start: 9; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 23;"></div><div class = "" vx = "0" vy = "4" dvx = "1" dvy = "0" style="grid-column-start: 5; grid-row-start: 20;"></div><div class = "" vx = "1" vy = "3" dvx = "-1" dvy = "1" style="grid-column-start: 9; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 32;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "1" style="grid-column-start: 6; grid-row-start: 7;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "-1" style="grid-column-start: 9; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 30;"></div><div class = "" vx = "1" vy = "0" dvx = "1" dvy = "0" style="grid-column-start: 7; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 16;"></div><div class = "" vx = "1" vy = "2" dvx = "0" dvy = "1" style="grid-column-start: 9; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 11; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 26;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "-1" style="grid-column-start: 5; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 22;"></div><div class = "" vx = "0" vy = "4" dvx = "1" dvy = "1" style="grid-column-start: 8; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 21;"></div><div class = "" vx = "0" vy = "4" dvx = "-1" dvy = "1" style="grid-column-start: 9; grid-row-start: 26;"></div><div class = "" vx = "1" vy = "3" dvx = "0" dvy = "1" style="grid-column-start: 9; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 14;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "0" style="grid-column-start: 5; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 27;"></div><div class = "" vx = "0" vy = "2" dvx = "-1" dvy = "1" style="grid-column-start: 5; grid-row-start: 4;"></div><div class = "" vx = "1" vy = "3" dvx = "-1" dvy = "-1" style="grid-column-start: 9; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 21;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "1" style="grid-column-start: 7; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 7;"></div><div class = "" vx = "1" vy = "0" dvx = "0" dvy = "1" style="grid-column-start: 9; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 23;"></div><div class = "" vx = "1" vy = "1" dvx = "1" dvy = "1" style="grid-column-start: 15; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 28;"></div><div class = "" vx = "1" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 5; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 21;"></div><div class = "" vx = "0" vy = "4" dvx = "-1" dvy = "-1" style="grid-column-start: 8; grid-row-start: 20;"></div><div class = "" vx = "1" vy = "4" dvx = "-1" dvy = "0" style="grid-column-start: 6; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 32;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "-1" style="grid-column-start: 9; grid-row-start: 28;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "1" style="grid-column-start: 9; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 32;"></div><div class = "" vx = "1" vy = "2" dvx = "1" dvy = "0" style="grid-column-start: 5; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 19;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "0" style="grid-column-start: 8; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 20;"></div><div class = "" vx = "1" vy = "4" dvx = "0" dvy = "-1" style="grid-column-start: 6; grid-row-start: 17;"></div><div class = "" vx = "2" vy = "2" dvx = "-1" dvy = "-1" style="grid-column-start: 9; grid-row-start: 6;"></div><div class = "" vx = "1" vy = "0" dvx = "0" dvy = "0" style="grid-column-start: 11; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 26;"></div><div class = "" vx = "1" vy = "3" dvx = "-1" dvy = "-1" style="grid-column-start: 8; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 14;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "1" style="grid-column-start: 5; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 8;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "1" style="grid-column-start: 8; grid-row-start: 10;"></div><div class = "" vx = "0" vy = "4" dvx = "1" dvy = "1" style="grid-column-start: 9; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 16;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 9; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 29;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "0" style="grid-column-start: 5; grid-row-start: 7;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "-1" style="grid-column-start: 8; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 29;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "1" style="grid-column-start: 9; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 10;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 28;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "0" style="grid-column-start: 8; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 15; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 30;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "1" style="grid-column-start: 5; grid-row-start: 16;"></div><div class = "" vx = "0" vy = "2" dvx = "1" dvy = "0" style="grid-column-start: 4; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 13;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 21;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 17;"></div><div class = "" vx = "0" vy = "4" dvx = "1" dvy = "-1" style="grid-column-start: 6; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 14; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 20;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 16;"></div><div class = "" vx = "1" vy = "3" dvx = "1" dvy = "-1" style="grid-column-start: 7; grid-row-start: 20;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "1" style="grid-column-start: 8; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 28;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 30;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 12;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 19;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 9;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 32;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 6;"></div><div class = "" vx = "2" vy = "4" dvx = "1" dvy = "1" style="grid-column-start: 9; grid-row-start: 18;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 26;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 26;"></div><div class = "" vx = "2" vy = "2" dvx = "1" dvy = "-1" style="grid-column-start: 7; grid-row-start: 8;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 29;"></div><div class = "" vx = "0" vy = "1" dvx = "0" dvy = "-1" style="grid-column-start: 8; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 17;"></div><div class = "" vx = "1" vy = "1" dvx = "0" dvy = "0" style="grid-column-start: 6; grid-row-start: 5;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 24;"></div><div class = "" vx = "1" vy = "3" dvx = "-1" dvy = "0" style="grid-column-start: 10; grid-row-start: 31;"></div><div class = "" vx = "1" vy = "2" dvx = "0" dvy = "1" style="grid-column-start: 8; grid-row-start: 7;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 14;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 6; grid-row-start: 23;"></div><div class = "" style="grid-column-start: 9; grid-row-start: 24;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 10;"></div><div class = "" vx = "0" vy = "1" dvx = "1" dvy = "0" style="grid-column-start: 4; grid-row-start: 2;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 11;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 21;"></div><div class = "" vx = "0" vy = "2" dvx = "0" dvy = "1" style="grid-column-start: 7; grid-row-start: 4;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 21;"></div><div class = "" vx = "0" vy = "3" dvx = "0" dvy = "-1" style="grid-column-start: 6; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 7;"></div><div class = "" vx = "0" vy = "4" dvx = "1" dvy = "1" style="grid-column-start: 8; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 1; grid-row-start: 28;"></div><div class = "" vx = "1" vy = "4" dvx = "1" dvy = "0" style="grid-column-start: 9; grid-row-start: 15;"></div><div class = "" style="grid-column-start: 5; grid-row-start: 25;"></div><div class = "" vx = "0" vy = "4" dvx = "0" dvy = "-1" style="grid-column-start: 9; grid-row-start: 17;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 22;"></div><div class = "" style="grid-column-start: 2; grid-row-start: 29;"></div><div class = "" style="grid-column-start: 13; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 7; grid-row-start: 28;"></div><div class = "" vx = "0" vy = "1" dvx = "-1" dvy = "1" style="grid-column-start: 7; grid-row-start: 3;"></div><div class = "" style="grid-column-start: 3; grid-row-start: 12;"></div><div class = "" vx = "0" vy = "3" dvx = "-1" dvy = "-1" style="grid-column-start: 9; grid-row-start: 25;"></div><div class = "" style="grid-column-start: 10; grid-row-start: 27;"></div><div class = "" style="grid-column-start: 12; grid-row-start: 31;"></div><div class = "" style="grid-column-start: 4; grid-row-start: 16;"></div><div class = "" style="grid-column-start: 8; grid-row-start: 18;"></div><div class = "" vx = "1" vy = "2" dvx = "1" dvy = "-1" style="grid-column-start: 7; grid-row-start: 6;"></div><div class = "" style="grid-column-start: 16; grid-row-start: 28;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 28;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 29;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 31;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 30;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 27;"></div><div class = "finish" style="grid-column-start: 17; grid-row-start: 32;"></div>
	</div>
	Finish <br> line
	</div>
	<div>Starting line</div>
</div>
</div>

	</div>
mimetext/htmlrootassigneelast_run_timestampA1.3persist_js_state·has_pluto_hook_features§cell_id$9524a3f5-fca3-4ce9-b04d-0cb6c0cd0c90depends_on_disabled_cells§runtime Ipublished_object_keysdepends_on_skipped_cells§errored$2ed0d4bb-bb6e-4adf-ad7c-8ddeb8c20b84queued¤logsrunning¦outputbodyprefixFloat32elements-0.283645text/plain-0.283863text/plaintypeArrayprefix_shortobjectid15a0fb12b6cc7c7dmime!application/vnd.pluto.tree+objectrootassigneelast_run_timestampA.) persist_js_state·has_pluto_hook_features§cell_id$2ed0d4bb-bb6e-4adf-ad7c-8ddeb8c20b84depends_on_disabled_cells§runtimeNEpublished_object_keysdepends_on_skipped_cells§errored$a0d61852-9942-42de-b554-572c4526a3a8queued¤logsrunning¦outputbody/make_track_mdp (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA/persist_js_state·has_pluto_hook_features§cell_id$a0d61852-9942-42de-b554-572c4526a3a8depends_on_disabled_cells§runtime Yrpublished_object_keysdepends_on_skipped_cells§errored$bb617e58-2700-4f0d-b8c8-3a266142fb70queued¤logsrunning¦outputbodyprefixTuple{Int64, Int64}elementselements-1text/plain-1text/plaintypeTupleobjectida5f5003e88013c47!application/vnd.pluto.tree+objectelements-1text/plain0text/plaintypeTupleobjectid29547c053cf46d53!application/vnd.pluto.tree+objectelements-1text/plain1text/plaintypeTupleobjectidd7f044f2876f60ea!application/vnd.pluto.tree+objectelements0text/plain-1text/plaintypeTupleobjectid4b2797d2a8e67906!application/vnd.pluto.tree+objectelements0text/plain0text/plaintypeTupleobjectid9b52efd7a2a08bd5!application/vnd.pluto.tree+objectelements0text/plain1text/plaintypeTupleobjectid86128cc9b5ae8f4a!application/vnd.pluto.tree+objectelements1text/plain-1text/plaintypeTupleobjectid467534c86eaf64c9!application/vnd.pluto.tree+objectelements1text/plain0text/plaintypeTupleobjectid1539b04621ff8c7d!application/vnd.pluto.tree+object	elements1text/plain1text/plaintypeTupleobjectid78e123e4f427692a!application/vnd.pluto.tree+objecttypeArrayprefix_shortobjectidd05a5360a94e8964mime!application/vnd.pluto.tree+objectrootassigneeconst racetrack_actionslast_run_timestampA/Eɰpersist_js_state·has_pluto_hook_features§cell_id$bb617e58-2700-4f0d-b8c8-3a266142fb70depends_on_disabled_cells§runtimeopublished_object_keysdepends_on_skipped_cells§errored$0d9c5d60-878a-45bb-8707-275cf10be41fqueued¤logsrunning¦outputbodyY<bond def="run2_2" unique_id="R9Ux3nHe4EhE"><input type="button" value="Run race"></bond>mimetext/htmlrootassigneelast_run_timestampA3(4persist_js_state·has_pluto_hook_features§cell_id$0d9c5d60-878a-45bb-8707-275cf10be41fdepends_on_disabled_cells§runtime 5published_object_keysdepends_on_skipped_cells§errored$b6eac49e-6742-4594-87a5-821437846b0dqueued¤logsrunning¦outputbody%test (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA-persist_js_state·has_pluto_hook_features§cell_id$b6eac49e-6742-4594-87a5-821437846b0ddepends_on_disabled_cells§runtime ,Xpublished_object_keysdepends_on_skipped_cells§errored$61d8cfc6-a50c-4546-9e1f-dc73d4764bb9queued¤logsrunning¦outputbody)updateQ! (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA-NͰpersist_js_state·has_pluto_hook_features§cell_id$61d8cfc6-a50c-4546-9e1f-dc73d4764bb9depends_on_disabled_cells§runtime 7published_object_keysdepends_on_skipped_cells§errored$847a074c-1d23-4de3-a039-322aeb9f7613queued¤logsrunning¦outputbodyelements0.5652text/plain0.0text/plain0text/plain0.5155text/plain0.4038text/plain0.0807text/plaintypeTupleobjectidd7544a9cb7c7437bmime!application/vnd.pluto.tree+objectrootassigneelast_run_timestampA-||persist_js_state·has_pluto_hook_features§cell_id$847a074c-1d23-4de3-a039-322aeb9f7613depends_on_disabled_cells§runtimeCpublished_object_keysdepends_on_skipped_cells§errored$d2625507-4787-4b1c-9a91-108012e42cc7queued¤logsrunning¦outputbody4make_rotation_style (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA/Ͱpersist_js_state·has_pluto_hook_features§cell_id$d2625507-4787-4b1c-9a91-108012e42cc7depends_on_disabled_cells§runtime 
published_object_keysdepends_on_skipped_cells§errored$94be5289-bba7-4490-bdcd-0d217a31c665queued¤logsrunning¦outputbody6eval_blackjack_policy (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA)qhpersist_js_state·has_pluto_hook_features§cell_id$94be5289-bba7-4490-bdcd-0d217a31c665depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$f7616806-97ab-4b09-accc-4e047691f879queued¤logsrunning¦outputbodyelementsstartprefixSet{Tuple{Int64, Int64}}elementselements7text/plain0text/plaintypeTupleobjectid627f1c091b0a4b9c!application/vnd.pluto.tree+objectelements4text/plain0text/plaintypeTupleobjectidc772df2bb869c6b4!application/vnd.pluto.tree+objectelements13text/plain0text/plaintypeTupleobjectida6181d00e53a5365!application/vnd.pluto.tree+objectelements15text/plain0text/plaintypeTupleobjectid816aa1f221e923aa!application/vnd.pluto.tree+objectelements2text/plain0text/plaintypeTupleobjectid83bf2aef4031930b!application/vnd.pluto.tree+objectelements10text/plain0text/plaintypeTupleobjectid9923e252784cde82!application/vnd.pluto.tree+objectelements18text/plain0text/plaintypeTupleobjectid8306b9cc8232e6d3!application/vnd.pluto.tree+objectelements21text/plain0text/plaintypeTupleobjectid60607b9e5a59278c!application/vnd.pluto.tree+object	elements5text/plain0text/plaintypeTupleobjectid973ae957c0c386bd!application/vnd.pluto.tree+object
elements16text/plain0text/plaintypeTupleobjectidb06d4522cf52b585!application/vnd.pluto.tree+objectmoretypeSetprefix_shortSetobjectidb6a28855cf29006d!application/vnd.pluto.tree+objectfinishprefixSet{Tuple{Int64, Int64}}elementselements31text/plain29text/plaintypeTupleobjectidbddb0ebc69f81014!application/vnd.pluto.tree+objectelements31text/plain26text/plaintypeTupleobjectid7a8f6e121fb0f1db!application/vnd.pluto.tree+objectelements31text/plain22text/plaintypeTupleobjectid5eac73e27c3431b0!application/vnd.pluto.tree+objectelements31text/plain27text/plaintypeTupleobjectidfb77cb5c89872970!application/vnd.pluto.tree+objectelements31text/plain28text/plaintypeTupleobjectid196e8741f643f3a3!application/vnd.pluto.tree+objectelements31text/plain25text/plaintypeTupleobjectid4783b0de51ea20d2!application/vnd.pluto.tree+objectelements31text/plain24text/plaintypeTupleobjectid3a6d5841ee97ba56!application/vnd.pluto.tree+objectelements31text/plain23text/plaintypeTupleobjectid77bb4b7f5f6e79ec!application/vnd.pluto.tree+object	elements31text/plain21text/plaintypeTupleobjectide62e5aecdedfbbed!application/vnd.pluto.tree+objecttypeSetprefix_shortSetobjectide91180ef62eb64ab!application/vnd.pluto.tree+objectbodyprefixSet{Tuple{Int64, Int64}}elementselements18text/plain16text/plaintypeTupleobjectidaeb6f295858259db!application/vnd.pluto.tree+objectelements16text/plain14text/plaintypeTupleobjectidd93d095a02371a59!application/vnd.pluto.tree+objectelements23text/plain27text/plaintypeTupleobjectidda74d5c39ad37f7d!application/vnd.pluto.tree+objectelements22text/plain28text/plaintypeTupleobjectidcbfc5affbbf7435!application/vnd.pluto.tree+objectelements17text/plain12text/plaintypeTupleobjectid68544eea78f6641!application/vnd.pluto.tree+objectelements28text/plain24text/plaintypeTupleobjectid20a1ce308f12ceac!application/vnd.pluto.tree+objectelements16text/plain16text/plaintypeTupleobjectid3164689f12bc7404!application/vnd.pluto.tree+objectelements19text/plain14text/plaintypeTupleobjectidcb90bf273945b2c8!application/vnd.pluto.tree+object	elements7text/plain8text/plaintypeTupleobjectid300559d2f34a9666!application/vnd.pluto.tree+object
elements25text/plain18text/plaintypeTupleobjectide198c580273e4010!application/vnd.pluto.tree+objectmoretypeSetprefix_shortSetobjectid56568ecb5f27cf54!application/vnd.pluto.tree+objecttypeNamedTupleobjectidf9782d076e3f90a9mime!application/vnd.pluto.tree+objectrootassigneeconst track2last_run_timestampA/Apersist_js_state·has_pluto_hook_features§cell_id$f7616806-97ab-4b09-accc-4e047691f879depends_on_disabled_cells§runtimeGڵpublished_object_keysdepends_on_skipped_cells§errored$70d9d39f-020d-4f25-810c-82a143a3335bqueued¤logsrunning¦outputbodyٿ2×200 Matrix{Float32}:
 0.5  0.5  0.5  0.5  0.5  0.5  0.5  0.5  …  0.5  0.5  0.5  0.5  0.5  0.5  0.5  0.5
 0.5  0.5  0.5  0.5  0.5  0.5  0.5  0.5     0.5  0.5  0.5  0.5  0.5  0.5  0.5  0.5mimetext/plainrootassigneeconst π_rand_blackjacklast_run_timestampA*}J#persist_js_state·has_pluto_hook_features§cell_id$70d9d39f-020d-4f25-810c-82a143a3335bdepends_on_disabled_cells§runtime .published_object_keysdepends_on_skipped_cells§errored$780f2fd9-49c3-48bc-b790-dde5be1dc81bqueued¤logsrunning¦outputbodyprefixI@NamedTuple{position::Tuple{Int64, Int64}, velocity::Tuple{Int64, Int64}}elements elementspositionelements1text/plain28text/plaintypeTupleobjectid72e21e63940a8fea!application/vnd.pluto.tree+objectvelocityelements0text/plain0text/plaintypeTupleobjectid9b52efd7a2a08bd5!application/vnd.pluto.tree+objecttypeNamedTupleobjectide21e0d549cc4c557!application/vnd.pluto.tree+objectelementspositionelements1text/plain28text/plaintypeTupleobjectid72e21e63940a8fea!application/vnd.pluto.tree+objectvelocityelements0text/plain1text/plaintypeTupleobjectid86128cc9b5ae8f4a!application/vnd.pluto.tree+objecttypeNamedTupleobjectid7f58cd1418ac4ecf!application/vnd.pluto.tree+objectelementspositionelements1text/plain28text/plaintypeTupleobjectid72e21e63940a8fea!application/vnd.pluto.tree+objectvelocityelements0text/plain2text/plaintypeTupleobjectidfc41ae7a664555b0!application/vnd.pluto.tree+objecttypeNamedTupleobjectid1c9be938e1978e57!application/vnd.pluto.tree+objectelementspositionelements1text/plain28text/plaintypeTupleobjectid72e21e63940a8fea!application/vnd.pluto.tree+objectvelocityelements0text/plain3text/plaintypeTupleobjectid5a8d0f981b76571a!application/vnd.pluto.tree+objecttypeNamedTupleobjectidde42b54207e3ed51!application/vnd.pluto.tree+objectelementspositionelements1text/plain28text/plaintypeTupleobjectid72e21e63940a8fea!application/vnd.pluto.tree+objectvelocityelements0text/plain4text/plaintypeTupleobjectid6ac4b5902680c6bb!application/vnd.pluto.tree+objecttypeNamedTupleobjectidb60bb04f8974fbb6!application/vnd.pluto.tree+objectelementspositionelements1text/plain28text/plaintypeTupleobjectid72e21e63940a8fea!application/vnd.pluto.tree+objectvelocityelements1text/plain0text/plaintypeTupleobjectid1539b04621ff8c7d!application/vnd.pluto.tree+objecttypeNamedTupleobjectid811cc4bfed2188ee!application/vnd.pluto.tree+objectelementspositionelements1text/plain28text/plaintypeTupleobjectid72e21e63940a8fea!application/vnd.pluto.tree+objectvelocityelements1text/plain1text/plaintypeTupleobjectid78e123e4f427692a!application/vnd.pluto.tree+objecttypeNamedTupleobjectidba63b0bf4384bfeb!application/vnd.pluto.tree+objectelementspositionelements1text/plain28text/plaintypeTupleobjectid72e21e63940a8fea!application/vnd.pluto.tree+objectvelocityelements1text/plain2text/plaintypeTupleobjectide3e6b1884080a98d!application/vnd.pluto.tree+objecttypeNamedTupleobjectid588abfe8835e67f0!application/vnd.pluto.tree+object	elementspositionelements1text/plain28text/plaintypeTupleobjectid72e21e63940a8fea!application/vnd.pluto.tree+objectvelocityelements1text/plain3text/plaintypeTupleobjectid7d75a9159c58bddf!application/vnd.pluto.tree+objecttypeNamedTupleobjectide0a89afaeeb8cc2a!application/vnd.pluto.tree+object
elementspositionelements1text/plain28text/plaintypeTupleobjectid72e21e63940a8fea!application/vnd.pluto.tree+objectvelocityelements1text/plain4text/plaintypeTupleobjectid3258627267de1f67!application/vnd.pluto.tree+objecttypeNamedTupleobjectid5344a49278b1b36!application/vnd.pluto.tree+objectelementspositionelements1text/plain28text/plaintypeTupleobjectid72e21e63940a8fea!application/vnd.pluto.tree+objectvelocityelements2text/plain0text/plaintypeTupleobjectid83bf2aef4031930b!application/vnd.pluto.tree+objecttypeNamedTupleobjectidb06b130db8f7e4fb!application/vnd.pluto.tree+objectelementspositionelements1text/plain28text/plaintypeTupleobjectid72e21e63940a8fea!application/vnd.pluto.tree+objectvelocityelements2text/plain1text/plaintypeTupleobjectidef30e57ac248f6d7!application/vnd.pluto.tree+objecttypeNamedTupleobjectid9da3b55d9d765f30!application/vnd.pluto.tree+objectelementspositionelements1text/plain28text/plaintypeTupleobjectid72e21e63940a8fea!application/vnd.pluto.tree+objectvelocityelements2text/plain2text/plaintypeTupleobjectid74f4975686c560b8!application/vnd.pluto.tree+objecttypeNamedTupleobjectid4b7334d8b722e4c5!application/vnd.pluto.tree+objectelementspositionelements1text/plain28text/plaintypeTupleobjectid72e21e63940a8fea!application/vnd.pluto.tree+objectvelocityelements2text/plain3text/plaintypeTupleobjectid166e372c63abd549!application/vnd.pluto.tree+objecttypeNamedTupleobjectid12fd3745d40ded97!application/vnd.pluto.tree+objectelementspositionelements1text/plain28text/plaintypeTupleobjectid72e21e63940a8fea!application/vnd.pluto.tree+objectvelocityelements2text/plain4text/plaintypeTupleobjectidfe67fb157b710308!application/vnd.pluto.tree+objecttypeNamedTupleobjectid998dce71f304c512!application/vnd.pluto.tree+objectelementspositionelements1text/plain28text/plaintypeTupleobjectid72e21e63940a8fea!application/vnd.pluto.tree+objectvelocityelements3text/plain0text/plaintypeTupleobjectidaa4c36dcad24fa29!application/vnd.pluto.tree+objecttypeNamedTupleobjectid500de2a9e8aa0c4f!application/vnd.pluto.tree+objectelementspositionelements1text/plain28text/plaintypeTupleobjectid72e21e63940a8fea!application/vnd.pluto.tree+objectvelocityelements3text/plain1text/plaintypeTupleobjectidec7c7c340006434b!application/vnd.pluto.tree+objecttypeNamedTupleobjectidb178cc324ec3226d!application/vnd.pluto.tree+objectelementspositionelements1text/plain28text/plaintypeTupleobjectid72e21e63940a8fea!application/vnd.pluto.tree+objectvelocityelements3text/plain2text/plaintypeTupleobjectidc1258421771ca213!application/vnd.pluto.tree+objecttypeNamedTupleobjectid67ac852156bb7cf5!application/vnd.pluto.tree+objectelementspositionelements1text/plain28text/plaintypeTupleobjectid72e21e63940a8fea!application/vnd.pluto.tree+objectvelocityelements3text/plain3text/plaintypeTupleobjectid3ed622ab32dfec93!application/vnd.pluto.tree+objecttypeNamedTupleobjectid9eca4fb39061b113!application/vnd.pluto.tree+objectelementspositionelements1text/plain28text/plaintypeTupleobjectid72e21e63940a8fea!application/vnd.pluto.tree+objectvelocityelements3text/plain4text/plaintypeTupleobjectid441bcd44d2e6073b!application/vnd.pluto.tree+objecttypeNamedTupleobjectidba0183b035192320!application/vnd.pluto.tree+objectmore{elementspositionelements11text/plain26text/plaintypeTupleobjectid1981f96b58fe709e!application/vnd.pluto.tree+objectvelocityelements3text/plain0text/plaintypeTupleobjectidaa4c36dcad24fa29!application/vnd.pluto.tree+objecttypeNamedTupleobjectid96134b5d208df030!application/vnd.pluto.tree+object|elementspositionelements11text/plain26text/plaintypeTupleobjectid1981f96b58fe709e!application/vnd.pluto.tree+objectvelocityelements3text/plain1text/plaintypeTupleobjectidec7c7c340006434b!application/vnd.pluto.tree+objecttypeNamedTupleobjectidd14e3d1c0450631d!application/vnd.pluto.tree+object}elementspositionelements11text/plain26text/plaintypeTupleobjectid1981f96b58fe709e!application/vnd.pluto.tree+objectvelocityelements3text/plain2text/plaintypeTupleobjectidc1258421771ca213!application/vnd.pluto.tree+objecttypeNamedTupleobjectidaaeb61474279f53f!application/vnd.pluto.tree+object~elementspositionelements11text/plain26text/plaintypeTupleobjectid1981f96b58fe709e!application/vnd.pluto.tree+objectvelocityelements3text/plain3text/plaintypeTupleobjectid3ed622ab32dfec93!application/vnd.pluto.tree+objecttypeNamedTupleobjectid42d4a84a1c23f17c!application/vnd.pluto.tree+objectelementspositionelements11text/plain26text/plaintypeTupleobjectid1981f96b58fe709e!application/vnd.pluto.tree+objectvelocityelements3text/plain4text/plaintypeTupleobjectid441bcd44d2e6073b!application/vnd.pluto.tree+objecttypeNamedTupleobjectida981be40c7182ddb!application/vnd.pluto.tree+objectelementspositionelements11text/plain26text/plaintypeTupleobjectid1981f96b58fe709e!application/vnd.pluto.tree+objectvelocityelements4text/plain0text/plaintypeTupleobjectidc772df2bb869c6b4!application/vnd.pluto.tree+objecttypeNamedTupleobjectid8cfb9adb3d87723f!application/vnd.pluto.tree+objectelementspositionelements11text/plain26text/plaintypeTupleobjectid1981f96b58fe709e!application/vnd.pluto.tree+objectvelocityelements4text/plain1text/plaintypeTupleobjectidab958923df88f7e9!application/vnd.pluto.tree+objecttypeNamedTupleobjectidbd1004d406ac2ff3!application/vnd.pluto.tree+objectelementspositionelements11text/plain26text/plaintypeTupleobjectid1981f96b58fe709e!application/vnd.pluto.tree+objectvelocityelements4text/plain2text/plaintypeTupleobjectid27c77ee4a87cee0d!application/vnd.pluto.tree+objecttypeNamedTupleobjectidd173025b56a4b30e!application/vnd.pluto.tree+objectelementspositionelements11text/plain26text/plaintypeTupleobjectid1981f96b58fe709e!application/vnd.pluto.tree+objectvelocityelements4text/plain3text/plaintypeTupleobjectided8ab7e3922a8b9f!application/vnd.pluto.tree+objecttypeNamedTupleobjectid8cc1b39df9e565df!application/vnd.pluto.tree+objectelementspositionelements11text/plain26text/plaintypeTupleobjectid1981f96b58fe709e!application/vnd.pluto.tree+objectvelocityelements4text/plain4text/plaintypeTupleobjectida7048b0d6f799239!application/vnd.pluto.tree+objecttypeNamedTupleobjectidd3ab164e30a99253!application/vnd.pluto.tree+objecttypeArrayprefix_shortobjectide421b5fa4b4d4a53mime!application/vnd.pluto.tree+objectrootassigneelast_run_timestampA3=1Mpersist_js_state·has_pluto_hook_features§cell_id$780f2fd9-49c3-48bc-b790-dde5be1dc81bdepends_on_disabled_cells§runtime1	published_object_keysdepends_on_skipped_cells§errored$833bb53c-bc2b-47fb-9429-d0f6d92efb42queued¤logsrunning¦outputbodyY<bond def="run1_1" unique_id="UOpyOD8JQO8V"><input type="button" value="Run race"></bond>mimetext/htmlrootassigneelast_run_timestampA1%[persist_js_state·has_pluto_hook_features§cell_id$833bb53c-bc2b-47fb-9429-d0f6d92efb42depends_on_disabled_cells§runtimeB published_object_keysdepends_on_skipped_cells§errored$e370dbb3-3bd9-4dc8-b8ca-8aad8711905cqueued¤logsrunning¦outputbodyj<style>
	.track {
		display: grid;
		grid-gap: 0px;
		background-color: white;
		transform: rotateX(180deg);
	}

	.track * {
		width: 15px;
		height: 15px;
		border: 1px solid black;
		box-sizing: content-box;
		display: flex;
		justify-content: center;
		align-items: center;
	}

	[vx][vy][dvx][dvy]::before {
		display: flex;
		align-items: center;
		justify-content: center;
		position: absolute;
	}

	[vx][vy][dvx][dvy]::after {
		display: flex;
		align-items: center;
		justify-content: center;
		position: absolute;
	}

	.start {
		background-color: orange;
	}
	.finish {
		background-color: green;
	}

	[vx='0'][vy='0']::before {
		content: '•';
	}

	
[vx='0'][vy='1']::before {
	content: '→';
	transform: rotate(90.0deg) scale(27%);
}


[vx='0'][vy='2']::before {
	content: '→';
	transform: rotate(90.0deg) scale(53%);
}


[vx='0'][vy='3']::before {
	content: '→';
	transform: rotate(90.0deg) scale(80%);
}


[vx='0'][vy='4']::before {
	content: '→';
	transform: rotate(90.0deg) scale(106%);
}


[vx='1'][vy='0']::before {
	content: '→';
	transform: rotate(0.0deg) scale(27%);
}


[vx='1'][vy='1']::before {
	content: '→';
	transform: rotate(45.0deg) scale(38%);
}


[vx='1'][vy='2']::before {
	content: '→';
	transform: rotate(63.43494882292201deg) scale(59%);
}


[vx='1'][vy='3']::before {
	content: '→';
	transform: rotate(71.56505117707799deg) scale(84%);
}


[vx='1'][vy='4']::before {
	content: '→';
	transform: rotate(75.96375653207353deg) scale(109%);
}


[vx='2'][vy='0']::before {
	content: '→';
	transform: rotate(0.0deg) scale(53%);
}


[vx='2'][vy='1']::before {
	content: '→';
	transform: rotate(26.56505117707799deg) scale(59%);
}


[vx='2'][vy='2']::before {
	content: '→';
	transform: rotate(45.0deg) scale(75%);
}


[vx='2'][vy='3']::before {
	content: '→';
	transform: rotate(56.309932474020215deg) scale(96%);
}


[vx='2'][vy='4']::before {
	content: '→';
	transform: rotate(63.43494882292201deg) scale(119%);
}


[vx='3'][vy='0']::before {
	content: '→';
	transform: rotate(0.0deg) scale(80%);
}


[vx='3'][vy='1']::before {
	content: '→';
	transform: rotate(18.43494882292201deg) scale(84%);
}


[vx='3'][vy='2']::before {
	content: '→';
	transform: rotate(33.690067525979785deg) scale(96%);
}


[vx='3'][vy='3']::before {
	content: '→';
	transform: rotate(45.0deg) scale(112%);
}


[vx='3'][vy='4']::before {
	content: '→';
	transform: rotate(53.13010235415598deg) scale(133%);
}


[vx='4'][vy='0']::before {
	content: '→';
	transform: rotate(0.0deg) scale(106%);
}


[vx='4'][vy='1']::before {
	content: '→';
	transform: rotate(14.036243467926479deg) scale(109%);
}


[vx='4'][vy='2']::before {
	content: '→';
	transform: rotate(26.56505117707799deg) scale(119%);
}


[vx='4'][vy='3']::before {
	content: '→';
	transform: rotate(36.86989764584402deg) scale(133%);
}


[vx='4'][vy='4']::before {
	content: '→';
	transform: rotate(45.0deg) scale(150%);
}

)
	[dvx='-1'][dvy='-1']::after {
	content: '→';
	color: red;
	transform: rotate(-135.0deg);
}

[dvx='-1'][dvy='0']::after {
	content: '→';
	color: red;
	transform: rotate(180.0deg);
}


[dvx='-1'][dvy='1']::after {
	content: '→';
	color: red;
	transform: rotate(135.0deg);
}


[dvx='0'][dvy='-1']::after {
	content: '→';
	color: red;
	transform: rotate(-90.0deg);
}




[dvx='0'][dvy='1']::after {
	content: '→';
	color: red;
	transform: rotate(90.0deg);
}


[dvx='1'][dvy='-1']::after {
	content: '→';
	color: red;
	transform: rotate(-45.0deg);
}


[dvx='1'][dvy='0']::after {
	content: '→';
	color: red;
	transform: rotate(0.0deg);
}


[dvx='1'][dvy='1']::after {
	content: '→';
	color: red;
	transform: rotate(45.0deg);
}

)
</style>
mimetext/htmlrootassigneelast_run_timestampA0 4persist_js_state·has_pluto_hook_features§cell_id$e370dbb3-3bd9-4dc8-b8ca-8aad8711905cdepends_on_disabled_cells§runtimeԩpublished_object_keysdepends_on_skipped_cells§errored$2646c9a2-46b1-4700-9290-ddc7dc9a59afqueued¤logsrunning¦outputbody-updatecount (generic function with 2 methods)mimetext/plainrootassigneelast_run_timestampA)Zpersist_js_state·has_pluto_hook_features§cell_id$2646c9a2-46b1-4700-9290-ddc7dc9a59afdepends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$892b5d8e-ac51-48f1-8288-65e9f68acd2dqueued¤logsrunning¦outputbodyelements10.14text/plain0.224text/plaintypeTupleobjectid54647e13d03e701mime!application/vnd.pluto.tree+objectrootassigneelast_run_timestampA+hpersist_js_state·has_pluto_hook_features§cell_id$892b5d8e-ac51-48f1-8288-65e9f68acd2ddepends_on_disabled_cells§runtime
n1Vpublished_object_keysdepends_on_skipped_cells§errored$acb08e38-fc87-43f4-ac2d-6c6bf0f2e9e6queued¤logsrunning¦outputbody3estimate_mdp_state (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA)persist_js_state·has_pluto_hook_features§cell_id$acb08e38-fc87-43f4-ac2d-6c6bf0f2e9e6depends_on_disabled_cells§runtime m'published_object_keysdepends_on_skipped_cells§errored$fca388bd-eb8b-41e2-8da0-87b9386629c1queued¤logsrunning¦outputbodyD<div class="markdown"><h2>5.6 Incremental Implementation</h2>
</div>mimetext/htmlrootassigneelast_run_timestampA"({persist_js_state·has_pluto_hook_features§cell_id$fca388bd-eb8b-41e2-8da0-87b9386629c1depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored±cell_dependencies $9fe42679-dce3-4ee3-b565-eed4ff7d8e4dprecedence_heuristic	cell_id$9fe42679-dce3-4ee3-b565-eed4ff7d8e4ddownstream_cells_mapupstream_cells_map@md_strgetindex$06960937-a87a-4015-bdeb-5d17aa41fe6bprecedence_heuristic	cell_id$06960937-a87a-4015-bdeb-5d17aa41fe6bdownstream_cells_mapplot_blackjack_value$627d5aa3-974f-4949-8b65-9500eba1d7ccupstream_cells_mapplot_value$01683e11-a368-45bc-abbc-bbd5c94d7b22make_value_grid$a35de859-4046-4f6d-9ea9-b523d21cee5d$abdcbbad-747a-41ba-a95d-82404e735793precedence_heuristic	cell_id$abdcbbad-747a-41ba-a95d-82404e735793downstream_cells_mapmake_ϵsoft_policy!$334b4d77-8784-46be-b9e8-80c0a2244694upstream_cells_mapisapproxsumAbstractVectoroneReallengtheachindex-/+==maximum$846ccb44-a18b-4d87-bbf8-fc59eaf87708precedence_heuristic	cell_id$846ccb44-a18b-4d87-bbf8-fc59eaf87708downstream_cells_mapopmc1$dfc2d648-ec08-49cd-a55f-72a766cad728$887de995-04e8-4d84-88d7-ad096a5747dfupstream_cells_map@md_strCore:Base.get@bindBasePlutoRunnerPlutoRunner.create_bondNumberFieldconfirmCore.applicablegetindex$154edd83-350d-4acf-adfb-6a2d20599b53precedence_heuristic	cell_id$154edd83-350d-4acf-adfb-6a2d20599b53downstream_cells_mapshowrace$9524a3f5-fca3-4ce9-b04d-0cb6c0cd0c90$66645f1a-b591-43e7-b931-8ed0cc7d6898$3d10f89f-876e-4d25-b8d6-34ce5c99eb8c$4481fa33-1ff3-4778-8486-d4d8a15775cd$b7dfc031-6bf6-44cd-b814-05f693a0a27d$6f914006-1d8d-41f5-ae8a-fbe0b336946cupstream_cells_mapHypertextLiteral.BypassHypertextLiteral.ResultHypertextLiteral$77cf7fee-0ad8-4d22-b376-75833307db93HypertextLiteral.contentrendertrack$a307e780-996a-485f-af59-b44982dfceb4@htlrunrace$5e2420fb-b2cc-49fc-91e3-3de80fba698b$ff9276eb-2151-4a6f-8257-8348047a9f4eprecedence_heuristic	cell_id$ff9276eb-2151-4a6f-8257-8348047a9f4edownstream_cells_maprace_episode2$ba044e4f-e2a6-4f96-8756-5b24b1bb5ca2upstream_cells_maprace_track_episode$658ceeaa-1b45-47bd-a364-eaa1759d17actrack2$f7616806-97ab-4b09-accc-4e047691f879π_racetrack_rand$0dfd7afb-127c-4afd-8374-3c9a20a9ee76racetrack_actions$bb617e58-2700-4f0d-b8c8-3a266142fb70rand$6f914006-1d8d-41f5-ae8a-fbe0b336946cprecedence_heuristic	cell_id$6f914006-1d8d-41f5-ae8a-fbe0b336946cdownstream_cells_mapupstream_cells_maptrack2_mdp$e7de31e8-ae95-4616-86a9-a115a5e24330run3_2$e2fc1d47-2ee9-4844-a6b1-16f76531da86πstar3_racetrack2$cde7be85-9344-4526-bcb2-c2c8b3322435track2$f7616806-97ab-4b09-accc-4e047691f879showrace$154edd83-350d-4acf-adfb-6a2d20599b53create_policy_function$d6e7cc6d-f397-4bdf-974e-9a16922393dd$4197cc28-b24c-48cb-bd8d-ef998983ad77precedence_heuristic	cell_id$4197cc28-b24c-48cb-bd8d-ef998983ad77downstream_cells_mapOrdinary$aaa9647c-afb6-44d1-ae1e-a2e957064080$c8f3f7e3-be7e-4615-a667-d9f789928883$d11bfcf9-b964-4c67-afdc-53d81f051fd5$892b5d8e-ac51-48f1-8288-65e9f68acd2d$43f9b824-fd56-4d56-84c3-23e2a3a37178$a59d9c84-d35f-4a9b-9fb6-13e30cdd7c3a$217ecc59-d6e3-48fa-9d6d-700a3947b805$19e42f50-5301-41b9-becb-2368c26b6236$5b32bbc7-dc34-4fc3-bacc-92e55f26a98c$b6eac49e-6742-4594-87a5-821437846b0d$00cd2194-af13-415a-b725-bb34832e5d9a$e67d9deb-a074-48ba-84db-2e6938ea01f8upstream_cells_mapImportanceMethod$d97f693d-27f2-49be-a549-07a290c95b53$e67d9deb-a074-48ba-84db-2e6938ea01f8precedence_heuristic	cell_id$e67d9deb-a074-48ba-84db-2e6938ea01f8downstream_cells_mapmonte_carlo_pred_Q$a59d9c84-d35f-4a9b-9fb6-13e30cdd7c3a$217ecc59-d6e3-48fa-9d6d-700a3947b805$19e42f50-5301-41b9-becb-2368c26b6236$5b32bbc7-dc34-4fc3-bacc-92e55f26a98c$b6eac49e-6742-4594-87a5-821437846b0d$a47474b0-f262-4453-a116-addc3a09119e$35914757-6af1-4056-bba4-a9996f65f7f7$5e012ead-b4f9-45a9-979d-88b0b1086263upstream_cells_map updateQ!$61d8cfc6-a50c-4546-9e1f-dc73d4764bb9zerosum@assertviewlengthsample_action$a85e7dd3-ea5e-4c77-a18e-f1e190658ae3throwMatrixAssertionError!===AbstractFloat:Ordinary$4197cc28-b24c-48cb-bd8d-ef998983ad77ImportanceMethod$d97f693d-27f2-49be-a549-07a290c95b53zerosonesBoolIntegerall+check_policy$11723075-d1db-4512-abf2-3fe494a71a3b*MDP_Opaque$21d248f5-edad-4614-8c1c-ae330f9e5a18$82a1f11e-b1b3-4c7d-ab9d-9f6136ae8195precedence_heuristic	cell_id$82a1f11e-b1b3-4c7d-ab9d-9f6136ae8195downstream_cells_maponestate_π_b$5948f670-1203-4b75-8517-f8470f5d01aa$35914757-6af1-4056-bba4-a9996f65f7f7$5e012ead-b4f9-45a9-979d-88b0b1086263upstream_cells_mapmake_random_policy$b2115f33-f8e2-452e-9b0e-90610f0f09b1onestate_mdp$f071b7e2-3f78-4132-8b84-f810f178c89d$11f8290f-f589-49ff-9602-99ccc4192884precedence_heuristic	cell_id$11f8290f-f589-49ff-9602-99ccc4192884downstream_cells_mapupstream_cells_maptrack2_mdp$e7de31e8-ae95-4616-86a9-a115a5e24330track2$f7616806-97ab-4b09-accc-4e047691f879πstar1_racetrack2$da66b3be-1fe2-4edb-9560-71ce7c0bed12sampleracepolicy$8f38a3e9-1872-4ea6-9a03-87112af4bf07create_policy_function$d6e7cc6d-f397-4bdf-974e-9a16922393dd$7fb4244c-828a-49d6-a15b-178fa3a42e00precedence_heuristic	cell_id$7fb4244c-828a-49d6-a15b-178fa3a42e00downstream_cells_mapπ_blackjack1$a68b4965-c392-47e5-9b29-93e7ada9990a$ec29865f-3ba3-4bb3-84df-c2b472e03ff2$d16ac2a8-1a5a-4ded-9285-d2c6cd550066$892b5d8e-ac51-48f1-8288-65e9f68acd2d$43f9b824-fd56-4d56-84c3-23e2a3a37178$a59d9c84-d35f-4a9b-9fb6-13e30cdd7c3a$217ecc59-d6e3-48fa-9d6d-700a3947b805$19e42f50-5301-41b9-becb-2368c26b6236$5b32bbc7-dc34-4fc3-bacc-92e55f26a98c$b6eac49e-6742-4594-87a5-821437846b0d$00cd2194-af13-415a-b725-bb34832e5d9a$a47474b0-f262-4453-a116-addc3a09119eupstream_cells_mapmake_simple_blackjack_policy$481ad435-cc80-4164-882d-8310b010ca91$0609ad22-0adc-4e4f-afed-b7a46d216576precedence_heuristic	cell_id$0609ad22-0adc-4e4f-afed-b7a46d216576downstream_cells_mapupstream_cells_maptrack1_mdp$9df79a71-e58a-497b-bb02-debb69144925πstar2_racetrack1$68f9e0d9-5c9d-4e89-b5ae-f24fd7544a09sampleracepolicy$8f38a3e9-1872-4ea6-9a03-87112af4bf07create_policy_function$d6e7cc6d-f397-4bdf-974e-9a16922393dd$61eb74eb-88e0-42e6-a14b-3730a800694dprecedence_heuristic	cell_id$61eb74eb-88e0-42e6-a14b-3730a800694ddownstream_cells_maponestate_π_target$5948f670-1203-4b75-8517-f8470f5d01aa$35914757-6af1-4056-bba4-a9996f65f7f7$5e012ead-b4f9-45a9-979d-88b0b1086263upstream_cells_mapreshape$6a96304b-add3-4135-8ccf-46cc23859d53precedence_heuristic	cell_id$6a96304b-add3-4135-8ccf-46cc23859d53downstream_cells_mapupstream_cells_map@md_strgetindex$c883748c-76b9-4086-8698-b40df51390daprecedence_heuristic	cell_id$c883748c-76b9-4086-8698-b40df51390dadownstream_cells_mapupstream_cells_map@md_strgetindex$f071b7e2-3f78-4132-8b84-f810f178c89dprecedence_heuristic	cell_id$f071b7e2-3f78-4132-8b84-f810f178c89ddownstream_cells_mapRight$f071b7e2-3f78-4132-8b84-f810f178c89dOneStateAction$f071b7e2-3f78-4132-8b84-f810f178c89dLeft$f071b7e2-3f78-4132-8b84-f810f178c89dOneState$f071b7e2-3f78-4132-8b84-f810f178c89done_state_simulatorone_state_stepone_state_action_lookuponestate_mdp$82a1f11e-b1b3-4c7d-ab9d-9f6136ae8195$5948f670-1203-4b75-8517-f8470f5d01aa$35914757-6af1-4056-bba4-a9996f65f7f7$5e012ead-b4f9-45a9-979d-88b0b1086263one_state_actionsupstream_cells_mapDictOneStateAction$f071b7e2-3f78-4132-8b84-f810f178c89d!=>randVectorsample_action$a85e7dd3-ea5e-4c77-a18e-f1e190658ae3Right$f071b7e2-3f78-4132-8b84-f810f178c89dLeft$f071b7e2-3f78-4132-8b84-f810f178c89dOneState$f071b7e2-3f78-4132-8b84-f810f178c89dpush!<=MDP_Opaque$21d248f5-edad-4614-8c1c-ae330f9e5a18$8d7b9826-b52c-4d5a-8c63-e83a1229a0beprecedence_heuristic	cell_id$8d7b9826-b52c-4d5a-8c63-e83a1229a0bedownstream_cells_mapupstream_cells_map@md_strmcϵs2$1117e6c3-2736-46a4-bac2-d3c99c1998b6getindex$67e535c7-437a-49ba-b5ab-9dfe63fe4aaaprecedence_heuristic	cell_id$67e535c7-437a-49ba-b5ab-9dfe63fe4aaadownstream_cells_mapupstream_cells_map@md_strgetindex$c8f3f7e3-be7e-4615-a667-d9f789928883precedence_heuristic	cell_id$c8f3f7e3-be7e-4615-a667-d9f789928883downstream_cells_mapupdatevalue$1e6f7e5e-c5ce-479c-abbb-6c388c254626$61d8cfc6-a50c-4546-9e1f-dc73d4764bb9upstream_cells_map-Ordinary$4197cc28-b24c-48cb-bd8d-ef998983ad77/*Real$30809344-b4ab-468b-b4b7-5ef3dca5ffc7precedence_heuristic	cell_id$30809344-b4ab-468b-b4b7-5ef3dca5ffc7downstream_cells_mapupstream_cells_map@md_strgetindex$e2a720b0-a8c4-43a2-bf34-750ff3323004precedence_heuristic	cell_id$e2a720b0-a8c4-43a2-bf34-750ff3323004downstream_cells_mapupstream_cells_map@md_strgetindex$1067fcc4-cbc6-453c-a996-d420c498619aprecedence_heuristic	cell_id$1067fcc4-cbc6-453c-a996-d420c498619adownstream_cells_mapupstream_cells_maptrack1_mdp$9df79a71-e58a-497b-bb02-debb69144925sampleracepolicy$8f38a3e9-1872-4ea6-9a03-87112af4bf07πstar1_racetrack1$dfc2d648-ec08-49cd-a55f-72a766cad728create_policy_function$d6e7cc6d-f397-4bdf-974e-9a16922393dd$6496c993-6d47-4a6e-a497-2a2de172fbc3precedence_heuristic	cell_id$6496c993-6d47-4a6e-a497-2a2de172fbc3downstream_cells_mapupstream_cells_map@md_strgetindex$aa647f3e-a4b2-4825-bb2a-1c2469d2c0ebprecedence_heuristic	cell_id$aa647f3e-a4b2-4825-bb2a-1c2469d2c0ebdownstream_cells_mapupstream_cells_maptrack2_mdp$e7de31e8-ae95-4616-86a9-a115a5e24330πstar2_racetrack2$f41dd3e6-81bf-43e4-afc2-fc549b77f610track2$f7616806-97ab-4b09-accc-4e047691f879sampleracepolicy$8f38a3e9-1872-4ea6-9a03-87112af4bf07create_policy_function$d6e7cc6d-f397-4bdf-974e-9a16922393dd$1d3d509c-b11b-4c57-b100-9bcf0489af2bprecedence_heuristic	cell_id$1d3d509c-b11b-4c57-b100-9bcf0489af2bdownstream_cells_mapcreate_greedy_policy$924f4e74-e3a0-42eb-89da-1f9836275588upstream_cells_mapReal:Matrixzerosmake_greedy_policy!$2d10281a-a4af-4ea8-b63b-e11f2d0893edsizecopy$989ccacd-b410-4967-bf6a-9244e3be785dprecedence_heuristic	cell_id$989ccacd-b410-4967-bf6a-9244e3be785ddownstream_cells_mapmces1$68f9e0d9-5c9d-4e89-b5ae-f24fd7544a09$605b045d-fe5c-426b-9f55-b7dd1d037c50upstream_cells_map@md_strCore:Base.get@bindBasePlutoRunnerPlutoRunner.create_bondNumberFieldconfirmCore.applicablegetindex$b352d98e-0854-45e3-ac73-8ef434525563precedence_heuristic	cell_id$b352d98e-0854-45e3-ac73-8ef434525563downstream_cells_mapupstream_cells_map@md_strgetindex$202eb066-877d-4537-85b2-31b41db8eca0precedence_heuristic	cell_id$202eb066-877d-4537-85b2-31b41db8eca0downstream_cells_mapinitialize_state_valueupstream_cells_maplengthones*MDP_Opaque$21d248f5-edad-4614-8c1c-ae330f9e5a18AbstractFloat$3955d71a-3105-445a-868d-66ba0b3dc515precedence_heuristic	cell_id$3955d71a-3105-445a-868d-66ba0b3dc515downstream_cells_maprace_episode1$ba044e4f-e2a6-4f96-8756-5b24b1bb5ca2upstream_cells_maprace_track_episode$658ceeaa-1b45-47bd-a364-eaa1759d17actrack1$df3c4a33-45f1-4cc2-8c06-d500a0eecc8fπ_racetrack_rand$0dfd7afb-127c-4afd-8374-3c9a20a9ee76racetrack_actions$bb617e58-2700-4f0d-b8c8-3a266142fb70rand$f406be9e-3e3f-4b55-99b0-4858c774ed96precedence_heuristic	cell_id$f406be9e-3e3f-4b55-99b0-4858c774ed96downstream_cells_mapupstream_cells_map@md_strgetindex$648bfc3f-0649-4401-a97f-89e21057f7b7precedence_heuristic	cell_id$648bfc3f-0649-4401-a97f-89e21057f7b7downstream_cells_mapupstream_cells_map@md_strmcϵs1$acb270a1-e2b9-46bc-9a52-9f66f1cca17cgetindex$e10378eb-12b3-4468-9c22-1838107da450precedence_heuristic	cell_id$e10378eb-12b3-4468-9c22-1838107da450downstream_cells_mapupstream_cells_map@md_strgetindex$2e57e4b5-d228-4ce3-b9d8-cf4375bb7c50precedence_heuristic	cell_id$2e57e4b5-d228-4ce3-b9d8-cf4375bb7c50downstream_cells_mapupstream_cells_map@md_strgetindex$edb4ad06-5e6e-48c4-9ee4-ae0b92927a91precedence_heuristic	cell_id$edb4ad06-5e6e-48c4-9ee4-ae0b92927a91downstream_cells_mapupstream_cells_map@md_strmces2$059b1c0f-eb21-4a4a-8aed-64e9ac07b541getindex$9df79a71-e58a-497b-bb02-debb69144925precedence_heuristic	cell_id$9df79a71-e58a-497b-bb02-debb69144925downstream_cells_maptrack1_mdp$dfc2d648-ec08-49cd-a55f-72a766cad728$9524a3f5-fca3-4ce9-b04d-0cb6c0cd0c90$1067fcc4-cbc6-453c-a996-d420c498619a$68f9e0d9-5c9d-4e89-b5ae-f24fd7544a09$3d10f89f-876e-4d25-b8d6-34ce5c99eb8c$0609ad22-0adc-4e4f-afed-b7a46d216576$780f2fd9-49c3-48bc-b790-dde5be1dc81b$1d6eccf0-2731-47fc-9a41-ea8649e290ef$b7dfc031-6bf6-44cd-b814-05f693a0a27d$985f0537-2bbe-4dbb-a113-8ac98d2e0a5fupstream_cells_mapmake_track_mdp$a0d61852-9942-42de-b554-572c4526a3a8track1$df3c4a33-45f1-4cc2-8c06-d500a0eecc8f$cebb79b7-c9d6-4b79-ba0e-b2f3c7587724precedence_heuristic	cell_id$cebb79b7-c9d6-4b79-ba0e-b2f3c7587724downstream_cells_mapupstream_cells_map@md_strgetindex$54f73eb8-dcea-4da0-83af-35720e56ccbcprecedence_heuristic	cell_id$54f73eb8-dcea-4da0-83af-35720e56ccbcdownstream_cells_mapmonte_carlo_ϵsoft$bf19e6cf-1fb5-49c9-974e-1613d90ef4cf$1d6eccf0-2731-47fc-9a41-ea8649e290ef$cde7be85-9344-4526-bcb2-c2c8b3322435upstream_cells_mapmake_random_policy$b2115f33-f8e2-452e-9b0e-90610f0f09b1zeroMatrixMDP_Opaque$21d248f5-edad-4614-8c1c-ae330f9e5a18initialize_state_action_value$d55860d1-e4c1-4a79-adbe-b40a6d6283a7oneReal$418c045d-90c7-42d8-9126-90185f7e197bprecedence_heuristic	cell_id$418c045d-90c7-42d8-9126-90185f7e197bdownstream_cells_mapupstream_cells_mapπstar_blackjack3$39da4cf9-5265-41bc-83d4-311e86675db7Qstar_blackjack3$39da4cf9-5265-41bc-83d4-311e86675db7figure_5_2$627d5aa3-974f-4949-8b65-9500eba1d7cc$6979db32-670d-466a-9a6e-97c2d8527f3dprecedence_heuristic	cell_id$6979db32-670d-466a-9a6e-97c2d8527f3ddownstream_cells_mapupstream_cells_map@md_strfigure5_3$00cd2194-af13-415a-b725-bb34832e5d9agetindex$cd928f87-2832-4595-8ce5-79b69cc56bd9precedence_heuristic	cell_id$cd928f87-2832-4595-8ce5-79b69cc56bd9downstream_cells_mapupstream_cells_map@md_strgetindex$ba044e4f-e2a6-4f96-8756-5b24b1bb5ca2precedence_heuristic	cell_id$ba044e4f-e2a6-4f96-8756-5b24b1bb5ca2downstream_cells_mapupstream_cells_maprace_episode1$3955d71a-3105-445a-868d-66ba0b3dc515track1$df3c4a33-45f1-4cc2-8c06-d500a0eecc8fHypertextLiteral.BypassHypertextLiteral.ResultHypertextLiteral$77cf7fee-0ad8-4d22-b376-75833307db93race_episode2$ff9276eb-2151-4a6f-8257-8348047a9f4etrack2$f7616806-97ab-4b09-accc-4e047691f879HypertextLiteral.contentrendertrack$a307e780-996a-485f-af59-b44982dfceb4@htl$6d6e8916-9b36-4af1-b77d-86cb6a416f88precedence_heuristic	cell_id$6d6e8916-9b36-4af1-b77d-86cb6a416f88downstream_cells_mapupstream_cells_map@md_strgetindex$cede8090-5b1a-436b-a184-fca5c4d3de48precedence_heuristic	cell_id$cede8090-5b1a-436b-a184-fca5c4d3de48downstream_cells_mapupstream_cells_map@md_strgetindex$8668ffc3-6c8c-4c25-8d47-9977bef929d2precedence_heuristic	cell_id$8668ffc3-6c8c-4c25-8d47-9977bef929d2downstream_cells_mapopmc2$da66b3be-1fe2-4edb-9560-71ce7c0bed12$1951fc4c-acc4-49a6-a907-7447ff0f430aupstream_cells_map@md_strCore:Base.get@bindBasePlutoRunnerPlutoRunner.create_bondNumberFieldconfirmCore.applicablegetindex$5834c5e0-8a04-47ea-aab8-881c73d8fd4fprecedence_heuristic	cell_id$5834c5e0-8a04-47ea-aab8-881c73d8fd4fdownstream_cells_mapupstream_cells_map@md_strgetindex$14536b70-35f0-46ba-93fc-3365a1e8c15cprecedence_heuristic	cell_id$14536b70-35f0-46ba-93fc-3365a1e8c15cdownstream_cells_mapupstream_cells_map@md_strgetindex$39da4cf9-5265-41bc-83d4-311e86675db7precedence_heuristic	cell_id$39da4cf9-5265-41bc-83d4-311e86675db7downstream_cells_mapπstar_blackjack3$418c045d-90c7-42d8-9126-90185f7e197bQstar_blackjack3$418c045d-90c7-42d8-9126-90185f7e197bupstream_cells_mapblackjack_mdp$6d765229-2816-4abb-a868-6be919a96530off_policy_MC_control$924f4e74-e3a0-42eb-89da-1f9836275588$d97f693d-27f2-49be-a549-07a290c95b53precedence_heuristic	cell_id$d97f693d-27f2-49be-a549-07a290c95b53downstream_cells_mapImportanceMethod$660ef59c-205c-44c2-9c46-5a74e09497ab$4197cc28-b24c-48cb-bd8d-ef998983ad77$1e6f7e5e-c5ce-479c-abbb-6c388c254626$d11bfcf9-b964-4c67-afdc-53d81f051fd5$61d8cfc6-a50c-4546-9e1f-dc73d4764bb9$e67d9deb-a074-48ba-84db-2e6938ea01f8upstream_cells_map$f9bc84ff-c2f9-4ac2-b2ce-34dfcf837a73precedence_heuristic	cell_id$f9bc84ff-c2f9-4ac2-b2ce-34dfcf837a73downstream_cells_mapupstream_cells_mapQstar_blackjack$ec29865f-3ba3-4bb3-84df-c2b472e03ff2πstar_blackjack$ec29865f-3ba3-4bb3-84df-c2b472e03ff2figure_5_2$627d5aa3-974f-4949-8b65-9500eba1d7cc$8f38a3e9-1872-4ea6-9a03-87112af4bf07precedence_heuristic	cell_id$8f38a3e9-1872-4ea6-9a03-87112af4bf07downstream_cells_mapsampleracepolicy$1067fcc4-cbc6-453c-a996-d420c498619a$11f8290f-f589-49ff-9602-99ccc4192884$0609ad22-0adc-4e4f-afed-b7a46d216576$aa647f3e-a4b2-4825-bb2a-1c2469d2c0eb$985f0537-2bbe-4dbb-a113-8ac98d2e0a5f$821ce23a-524b-4203-96d6-4d5b454fe1fdupstream_cells_map @md_strecdf>isnanislessfilterracetrack_actions$bb617e58-2700-4f0d-b8c8-3a266142fb70length<scatterisemptymeanroundgetindexrunrace$5e2420fb-b2cc-49fc-91e3-3de80fba698bstdminimum:randmedianInt64Markdown.parseplotNaNMarkdownmaximumLayout$627d5aa3-974f-4949-8b65-9500eba1d7ccprecedence_heuristic	cell_id$627d5aa3-974f-4949-8b65-9500eba1d7ccdownstream_cells_mapfigure_5_2$f9bc84ff-c2f9-4ac2-b2ce-34dfcf837a73$b040f245-b2d6-4ec6-aa7f-511c54aabd0d$418c045d-90c7-42d8-9126-90185f7e197bupstream_cells_map@md_strplot_blackjack_value$06960937-a87a-4015-bdeb-5d17aa41fe6b:sum*plot_blackjack_policy$5c57e4b7-51d6-492d-9fc9-bcdab1dd46f4getindex$02dd1e77-2a7e-4123-94db-d17b31a8b15aprecedence_heuristic	cell_id$02dd1e77-2a7e-4123-94db-d17b31a8b15adownstream_cells_mapblackjack_state1$04752549-ffca-4e31-869e-714f835d3e85$d16ac2a8-1a5a-4ded-9285-d2c6cd550066$8faca500-b80d-4b50-88b6-683d18a1286bupstream_cells_mapBlackjackState$e87932d9-fbc0-4ea5-a8ee-28eac5eed84f$09b67730-39e7-4209-8117-6bc3adfb342aprecedence_heuristic	cell_id$09b67730-39e7-4209-8117-6bc3adfb342adownstream_cells_mapupstream_cells_map@md_strgetindex$b7dfc031-6bf6-44cd-b814-05f693a0a27dprecedence_heuristic	cell_id$b7dfc031-6bf6-44cd-b814-05f693a0a27ddownstream_cells_mapupstream_cells_maprun3_1$772b4dd6-870c-4a16-937c-701d5bb5da44track1_mdp$9df79a71-e58a-497b-bb02-debb69144925track1$df3c4a33-45f1-4cc2-8c06-d500a0eecc8fshowrace$154edd83-350d-4acf-adfb-6a2d20599b53πstar3_racetrack1$1d6eccf0-2731-47fc-9a41-ea8649e290efcreate_policy_function$d6e7cc6d-f397-4bdf-974e-9a16922393dd$2572e35c-e6a3-4562-aa0f-6a5ab32d39eaprecedence_heuristic	cell_id$2572e35c-e6a3-4562-aa0f-6a5ab32d39eadownstream_cells_mapupstream_cells_mapHypertextLiteral.BypassHypertextLiteral.ResultHypertextLiteral$77cf7fee-0ad8-4d22-b376-75833307db93@htl$859354fe-7f40-4658-bf12-b5ee20a815a7precedence_heuristic	cell_id$859354fe-7f40-4658-bf12-b5ee20a815a7downstream_cells_mapupstream_cells_map@md_strgetindex$f9f6c182-62f8-4a5a-8b43-8716db468427precedence_heuristic	cell_id$f9f6c182-62f8-4a5a-8b43-8716db468427downstream_cells_mapmaxspeed$f506e8ba-b073-4f59-91b4-3fe99822d2a4upstream_cells_mapracetrackspeeds$1cc46e33-6885-4d6f-805e-9ff928f1cf23maximum$47daf83b-8fe9-4491-b9ae-84bd269d5546precedence_heuristic	cell_id$47daf83b-8fe9-4491-b9ae-84bd269d5546downstream_cells_mapupstream_cells_map@md_strgetindex$ba8a5804-4be3-43fe-95d7-c957ce02a1d4precedence_heuristic	cell_id$ba8a5804-4be3-43fe-95d7-c957ce02a1d4downstream_cells_mapmake_action_style$e370dbb3-3bd9-4dc8-b8ca-8aad8711905cupstream_cells_mapatand==$481ad435-cc80-4164-882d-8310b010ca91precedence_heuristic	cell_id$481ad435-cc80-4164-882d-8310b010ca91downstream_cells_mapmake_simple_blackjack_policy$7fb4244c-828a-49d6-a15b-178fa3a42e00upstream_cells_map<blackjackstates$e87932d9-fbc0-4ea5-a8ee-28eac5eed84fhcatislessmapreduceInteger$8bcaa31b-8caf-43da-83a0-47e0c04c2a30precedence_heuristic	cell_id$8bcaa31b-8caf-43da-83a0-47e0c04c2a30downstream_cells_mapupstream_cells_maptrack1$df3c4a33-45f1-4cc2-8c06-d500a0eecc8fHypertextLiteral.BypassHypertextLiteral.ResultHypertextLiteral$77cf7fee-0ad8-4d22-b376-75833307db93track2$f7616806-97ab-4b09-accc-4e047691f879HypertextLiteral.contentrendertrack$a307e780-996a-485f-af59-b44982dfceb4@htl$7c9486cd-1916-4e13-b415-fb113bd9e04bprecedence_heuristic	cell_id$7c9486cd-1916-4e13-b415-fb113bd9e04bdownstream_cells_mapupstream_cells_map@md_strgetindex$821ce23a-524b-4203-96d6-4d5b454fe1fdprecedence_heuristic	cell_id$821ce23a-524b-4203-96d6-4d5b454fe1fddownstream_cells_mapupstream_cells_maptrack2_mdp$e7de31e8-ae95-4616-86a9-a115a5e24330πstar3_racetrack2$cde7be85-9344-4526-bcb2-c2c8b3322435track2$f7616806-97ab-4b09-accc-4e047691f879sampleracepolicy$8f38a3e9-1872-4ea6-9a03-87112af4bf07create_policy_function$d6e7cc6d-f397-4bdf-974e-9a16922393dd$dc57a71f-e44c-4385-ad2a-e6c14d5e5201precedence_heuristic	cell_id$dc57a71f-e44c-4385-ad2a-e6c14d5e5201downstream_cells_mapupstream_cells_map@md_strgetindex$00cd2194-af13-415a-b725-bb34832e5d9aprecedence_heuristic	cell_id$00cd2194-af13-415a-b725-bb34832e5d9adownstream_cells_mapfigure5_3$9ca72278-fff6-4b0f-b72c-e0d3768aff73$6979db32-670d-466a-9a6e-97c2d8527f3dupstream_cells_map getindex@md_strvarblackjack_mdp$6d765229-2816-4abb-a868-6be919a96530:Ordinary$4197cc28-b24c-48cb-bd8d-ef998983ad77zipblackjack_stateindex1$04752549-ffca-4e31-869e-714f835d3e85Weighted$660ef59c-205c-44c2-9c46-5a74e09497abmonte_carlo_pred_V$760c5361-02d4-46b7-a05c-fc2d10d93de6$d11bfcf9-b964-4c67-afdc-53d81f051fd5blackjack_state_value1$d16ac2a8-1a5a-4ded-9285-d2c6cd550066-scatterplot^π_rand_blackjack$70d9d39f-020d-4f25-810c-82a143a3335bLayoutmeanπ_blackjack1$7fb4244c-828a-49d6-a15b-178fa3a42e00$da66b3be-1fe2-4edb-9560-71ce7c0bed12precedence_heuristic	cell_id$da66b3be-1fe2-4edb-9560-71ce7c0bed12downstream_cells_mapQstar1_racetrack2πstar1_racetrack2$66645f1a-b591-43e7-b931-8ed0cc7d6898$11f8290f-f589-49ff-9602-99ccc4192884upstream_cells_maptrack2_mdp$e7de31e8-ae95-4616-86a9-a115a5e24330off_policy_MC_control$924f4e74-e3a0-42eb-89da-1f9836275588opmc2$8668ffc3-6c8c-4c25-8d47-9977bef929d2$d16ac2a8-1a5a-4ded-9285-d2c6cd550066precedence_heuristic	cell_id$d16ac2a8-1a5a-4ded-9285-d2c6cd550066downstream_cells_mapblackjack_state_value1$00cd2194-af13-415a-b725-bb34832e5d9aupstream_cells_mapblackjack_state1$02dd1e77-2a7e-4123-94db-d17b31a8b15aestimate_blackjack_state$e293e184-5938-40b5-a04b-5306760a06ae|>meanπ_blackjack1$7fb4244c-828a-49d6-a15b-178fa3a42e00$830d6d61-7259-43e7-8d6d-09bc81818dd9precedence_heuristic	cell_id$830d6d61-7259-43e7-8d6d-09bc81818dd9downstream_cells_mapupstream_cells_mapfigure_5_4$5948f670-1203-4b75-8517-f8470f5d01aa$e293e184-5938-40b5-a04b-5306760a06aeprecedence_heuristic	cell_id$e293e184-5938-40b5-a04b-5306760a06aedownstream_cells_mapestimate_blackjack_state$d16ac2a8-1a5a-4ded-9285-d2c6cd550066$8faca500-b80d-4b50-88b6-683d18a1286bupstream_cells_mapblackjack_mdp$6d765229-2816-4abb-a868-6be919a96530estimate_mdp_state$acb08e38-fc87-43f4-ac2d-6c6bf0f2e9e6$66645f1a-b591-43e7-b931-8ed0cc7d6898precedence_heuristic	cell_id$66645f1a-b591-43e7-b931-8ed0cc7d6898downstream_cells_mapupstream_cells_maptrack2_mdp$e7de31e8-ae95-4616-86a9-a115a5e24330race_1_2$7cdf4142-82fe-4aa6-9665-84a1eef5d038track2$f7616806-97ab-4b09-accc-4e047691f879showrace$154edd83-350d-4acf-adfb-6a2d20599b53πstar1_racetrack2$da66b3be-1fe2-4edb-9560-71ce7c0bed12create_policy_function$d6e7cc6d-f397-4bdf-974e-9a16922393dd$658ceeaa-1b45-47bd-a364-eaa1759d17acprecedence_heuristic	cell_id$658ceeaa-1b45-47bd-a364-eaa1759d17acdownstream_cells_maprace_track_episode$a0d61852-9942-42de-b554-572c4526a3a8$5e2420fb-b2cc-49fc-91e3-3de80fba698b$3955d71a-3105-445a-868d-66ba0b3dc515$ff9276eb-2151-4a6f-8257-8348047a9f4eupstream_cells_map setdiff!!intersect!anyfirstproject_path$6dc0de46-2164-4580-b186-a73cb5b5167disless>InfrandVectorlength<push!Float32>=+isemptyin$04752549-ffca-4e31-869e-714f835d3e85precedence_heuristic	cell_id$04752549-ffca-4e31-869e-714f835d3e85downstream_cells_mapblackjack_stateindex1$892b5d8e-ac51-48f1-8288-65e9f68acd2d$43f9b824-fd56-4d56-84c3-23e2a3a37178$a59d9c84-d35f-4a9b-9fb6-13e30cdd7c3a$217ecc59-d6e3-48fa-9d6d-700a3947b805$19e42f50-5301-41b9-becb-2368c26b6236$5b32bbc7-dc34-4fc3-bacc-92e55f26a98c$b6eac49e-6742-4594-87a5-821437846b0d$00cd2194-af13-415a-b725-bb34832e5d9a$2ed0d4bb-bb6e-4adf-ad7c-8ddeb8c20b84upstream_cells_mapblackjack_state1$02dd1e77-2a7e-4123-94db-d17b31a8b15ablackjack_mdp$6d765229-2816-4abb-a868-6be919a96530$e89706f1-0c6a-4da4-82a1-ccf153f2e186precedence_heuristic	cell_id$e89706f1-0c6a-4da4-82a1-ccf153f2e186downstream_cells_mapupstream_cells_map@md_strgetindex$ab10ccd7-75ba-475c-af26-f8b36daaf880precedence_heuristic	cell_id$ab10ccd7-75ba-475c-af26-f8b36daaf880downstream_cells_mapupstream_cells_map@md_strgetindex$4481fa33-1ff3-4778-8486-d4d8a15775cdprecedence_heuristic	cell_id$4481fa33-1ff3-4778-8486-d4d8a15775cddownstream_cells_mapupstream_cells_maptrack2_mdp$e7de31e8-ae95-4616-86a9-a115a5e24330πstar2_racetrack2$f41dd3e6-81bf-43e4-afc2-fc549b77f610track2$f7616806-97ab-4b09-accc-4e047691f879showrace$154edd83-350d-4acf-adfb-6a2d20599b53run2_2$0d9c5d60-878a-45bb-8707-275cf10be41fcreate_policy_function$d6e7cc6d-f397-4bdf-974e-9a16922393dd$1b02e593-d791-424c-b956-62cc480fcf40precedence_heuristic	cell_id$1b02e593-d791-424c-b956-62cc480fcf40downstream_cells_mapupstream_cells_map@md_strgetindex$72e9721f-ee17-4557-b090-71728e6c22ceprecedence_heuristic	cell_id$72e9721f-ee17-4557-b090-71728e6c22cedownstream_cells_mapmakelookup$21d248f5-edad-4614-8c1c-ae330f9e5a18$e87932d9-fbc0-4ea5-a8ee-28eac5eed84f$a0d61852-9942-42de-b554-572c4526a3a8upstream_cells_mapDictenumerate=>Vector$11723075-d1db-4512-abf2-3fe494a71a3bprecedence_heuristic	cell_id$11723075-d1db-4512-abf2-3fe494a71a3bdownstream_cells_mapcheck_policy$760c5361-02d4-46b7-a05c-fc2d10d93de6$d11bfcf9-b964-4c67-afdc-53d81f051fd5$e67d9deb-a074-48ba-84db-2e6938ea01f8upstream_cells_mapMain.Base.inferencebarrier@assertsizenothinglengthMainthrowAssertionErrorMatrixMDP_Opaque$21d248f5-edad-4614-8c1c-ae330f9e5a18==AbstractFloat$059b1c0f-eb21-4a4a-8aed-64e9ac07b541precedence_heuristic	cell_id$059b1c0f-eb21-4a4a-8aed-64e9ac07b541downstream_cells_mapmces2$f41dd3e6-81bf-43e4-afc2-fc549b77f610$edb4ad06-5e6e-48c4-9ee4-ae0b92927a91upstream_cells_map@md_strCore:Base.get@bindBasePlutoRunnerPlutoRunner.create_bondNumberFieldconfirmCore.applicablegetindex$b2115f33-f8e2-452e-9b0e-90610f0f09b1precedence_heuristic	cell_id$b2115f33-f8e2-452e-9b0e-90610f0f09b1downstream_cells_mapmake_random_policy$1b78b25d-3942-4a6b-a2bd-7d97242da9fe$54f73eb8-dcea-4da0-83af-35720e56ccbc$70d9d39f-020d-4f25-810c-82a143a3335b$82a1f11e-b1b3-4c7d-ab9d-9f6136ae8195$924f4e74-e3a0-42eb-89da-1f9836275588upstream_cells_maplength/onesMDP_Opaque$21d248f5-edad-4614-8c1c-ae330f9e5a18AbstractFloat$82284c63-2306-4469-9b1a-a5ec87037e79precedence_heuristic	cell_id$82284c63-2306-4469-9b1a-a5ec87037e79downstream_cells_mapupstream_cells_mapplot_fig5_1$a68b4965-c392-47e5-9b29-93e7ada9990a$5b32bbc7-dc34-4fc3-bacc-92e55f26a98cprecedence_heuristic	cell_id$5b32bbc7-dc34-4fc3-bacc-92e55f26a98cdownstream_cells_mapupstream_cells_mapmonte_carlo_pred_Q$e67d9deb-a074-48ba-84db-2e6938ea01f8blackjack_mdp$6d765229-2816-4abb-a868-6be919a96530:sumOrdinary$4197cc28-b24c-48cb-bd8d-ef998983ad77|>filterblackjack_stateindex1$04752549-ffca-4e31-869e-714f835d3e85!=π_rand_blackjack$70d9d39f-020d-4f25-810c-82a143a3335b==meanπ_blackjack1$7fb4244c-828a-49d6-a15b-178fa3a42e00$c8be6951-b6ec-4444-8c7f-ca5db6681571precedence_heuristic	cell_id$c8be6951-b6ec-4444-8c7f-ca5db6681571downstream_cells_mapmakegridsquare$a307e780-996a-485f-af59-b44982dfceb4upstream_cells_map-+$887de995-04e8-4d84-88d7-ad096a5747dfprecedence_heuristic	cell_id$887de995-04e8-4d84-88d7-ad096a5747dfdownstream_cells_mapupstream_cells_map@md_stropmc1$846ccb44-a18b-4d87-bbf8-fc59eaf87708getindex$3ee31af5-b19c-49dc-8fbf-f07e93d1f0c5precedence_heuristic	cell_id$3ee31af5-b19c-49dc-8fbf-f07e93d1f0c5downstream_cells_mapupstream_cells_map@md_strgetindex$ffd1e39d-e66b-40a3-8ad1-c9480d371fe8precedence_heuristic	cell_id$ffd1e39d-e66b-40a3-8ad1-c9480d371fe8downstream_cells_mapupstream_cells_map@md_strgetindex$13cc524c-d983-44f4-8731-0595249fb888precedence_heuristic	cell_id$13cc524c-d983-44f4-8731-0595249fb888downstream_cells_mapmonte_carlo_ES$ec29865f-3ba3-4bb3-84df-c2b472e03ff2$68f9e0d9-5c9d-4e89-b5ae-f24fd7544a09$f41dd3e6-81bf-43e4-afc2-fc549b77f610upstream_cells_mapzero:zerosrandcopyRealInt64length-/Matrix+make_greedy_policy!$2d10281a-a4af-4ea8-b63b-e11f2d0893edMDP_Opaque$21d248f5-edad-4614-8c1c-ae330f9e5a18*$8faca500-b80d-4b50-88b6-683d18a1286bprecedence_heuristic	cell_id$8faca500-b80d-4b50-88b6-683d18a1286bdownstream_cells_mapupstream_cells_mapblackjack_state1$02dd1e77-2a7e-4123-94db-d17b31a8b15aestimate_blackjack_state$e293e184-5938-40b5-a04b-5306760a06ae|>π_rand_blackjack$70d9d39f-020d-4f25-810c-82a143a3335bmeanvar$755be8f1-9d9e-4afd-8a70-07fab78e4333precedence_heuristic	cell_id$755be8f1-9d9e-4afd-8a70-07fab78e4333downstream_cells_mapupstream_cells_map@md_strgetindex$01683e11-a368-45bc-abbc-bbd5c94d7b22precedence_heuristic	cell_id$01683e11-a368-45bc-abbc-bbd5c94d7b22downstream_cells_mapplot_value$a68b4965-c392-47e5-9b29-93e7ada9990a$06960937-a87a-4015-bdeb-5d17aa41fe6bupstream_cells_map:plotheatmapattrLayout$5e2420fb-b2cc-49fc-91e3-3de80fba698bprecedence_heuristic	cell_id$5e2420fb-b2cc-49fc-91e3-3de80fba698bdownstream_cells_maprunrace$8f38a3e9-1872-4ea6-9a03-87112af4bf07$154edd83-350d-4acf-adfb-6a2d20599b53upstream_cells_maprace_track_episode$658ceeaa-1b45-47bd-a364-eaa1759d17actrack1$df3c4a33-45f1-4cc2-8c06-d500a0eecc8frand$1e6f7e5e-c5ce-479c-abbb-6c388c254626precedence_heuristic	cell_id$1e6f7e5e-c5ce-479c-abbb-6c388c254626downstream_cells_mapupdateV!$d11bfcf9-b964-4c67-afdc-53d81f051fd5upstream_cells_map zeroImportanceMethod$d97f693d-27f2-49be-a549-07a290c95b53oneWeighted$660ef59c-205c-44c2-9c46-5a74e09497abVectorlengthisaRealupdatecount$aaa9647c-afb6-44d1-ae1e-a2e957064080$2646c9a2-46b1-4700-9290-ddc7dc9a59af-updatevalue$c8f3f7e3-be7e-4615-a667-d9f789928883$020131a1-c68b-403a-9c5e-944edb6220e9/Matrix+*==$5e012ead-b4f9-45a9-979d-88b0b1086263precedence_heuristic	cell_id$5e012ead-b4f9-45a9-979d-88b0b1086263downstream_cells_mapupstream_cells_mapmonte_carlo_pred_Q$e67d9deb-a074-48ba-84db-2e6938ea01f8onestate_π_b$82a1f11e-b1b3-4c7d-ab9d-9f6136ae8195onestate_mdp$f071b7e2-3f78-4132-8b84-f810f178c89dWeighted$660ef59c-205c-44c2-9c46-5a74e09497abonestate_π_target$61eb74eb-88e0-42e6-a14b-3730a800694d$a0eb6939-11bb-458d-bee3-9ed763819f62precedence_heuristic	cell_id$a0eb6939-11bb-458d-bee3-9ed763819f62downstream_cells_mapupstream_cells_map@md_strgetindex$21d248f5-edad-4614-8c1c-ae330f9e5a18precedence_heuristic	cell_id$21d248f5-edad-4614-8c1c-ae330f9e5a18downstream_cells_mapMDP_Opaque$b2115f33-f8e2-452e-9b0e-90610f0f09b1$202eb066-877d-4537-85b2-31b41db8eca0$d55860d1-e4c1-4a79-adbe-b40a6d6283a7$11723075-d1db-4512-abf2-3fe494a71a3b$760c5361-02d4-46b7-a05c-fc2d10d93de6$c23475f0-c5f0-49ce-a665-f93c8bda0474$13cc524c-d983-44f4-8731-0595249fb888$1b78b25d-3942-4a6b-a2bd-7d97242da9fe$334b4d77-8784-46be-b9e8-80c0a2244694$54f73eb8-dcea-4da0-83af-35720e56ccbc$d11bfcf9-b964-4c67-afdc-53d81f051fd5$f071b7e2-3f78-4132-8b84-f810f178c89d$e67d9deb-a074-48ba-84db-2e6938ea01f8$924f4e74-e3a0-42eb-89da-1f9836275588$a0d61852-9942-42de-b554-572c4526a3a8upstream_cells_mapVectorInt64newDictFunctionmakelookup$72e9721f-ee17-4557-b090-71728e6c22ce$a68b4965-c392-47e5-9b29-93e7ada9990aprecedence_heuristic	cell_id$a68b4965-c392-47e5-9b29-93e7ada9990adownstream_cells_mapplot_fig5_1$82284c63-2306-4469-9b1a-a5ec87037e79upstream_cells_mapplot_value$01683e11-a368-45bc-abbc-bbd5c94d7b22HypertextLiteral.BypassHypertextLiteral.ResultHypertextLiteral$77cf7fee-0ad8-4d22-b376-75833307db93HypertextLiteral.contenteval_blackjack_policy$94be5289-bba7-4490-bdcd-0d217a31c665@htlπ_blackjack1$7fb4244c-828a-49d6-a15b-178fa3a42e00$d766d44e-3684-497c-814e-8f71740cb232precedence_heuristic	cell_id$d766d44e-3684-497c-814e-8f71740cb232downstream_cells_mapupstream_cells_map@md_strgetindex$0dfd7afb-127c-4afd-8374-3c9a20a9ee76precedence_heuristic	cell_id$0dfd7afb-127c-4afd-8374-3c9a20a9ee76downstream_cells_mapπ_racetrack_rand$3955d71a-3105-445a-868d-66ba0b3dc515$ff9276eb-2151-4a6f-8257-8348047a9f4eupstream_cells_mapracetrack_actions$bb617e58-2700-4f0d-b8c8-3a266142fb70rand$bf33230e-342b-4486-89ac-9667438de503precedence_heuristic	cell_id$bf33230e-342b-4486-89ac-9667438de503downstream_cells_mapupstream_cells_map@md_strgetindex$826139cc-b52e-11ec-0d47-25ab689851fdprecedence_heuristic	cell_id$826139cc-b52e-11ec-0d47-25ab689851fddownstream_cells_mapupstream_cells_map@md_strgetindex$0bd705cb-ad38-4cbb-b8fc-7e0617635282precedence_heuristic	cell_id$0bd705cb-ad38-4cbb-b8fc-7e0617635282downstream_cells_mapupstream_cells_map@md_strgetindex$43f9b824-fd56-4d56-84c3-23e2a3a37178precedence_heuristic	cell_id$43f9b824-fd56-4d56-84c3-23e2a3a37178downstream_cells_mapupstream_cells_mapmonte_carlo_pred_V$760c5361-02d4-46b7-a05c-fc2d10d93de6$d11bfcf9-b964-4c67-afdc-53d81f051fd5blackjack_mdp$6d765229-2816-4abb-a868-6be919a96530Ordinary$4197cc28-b24c-48cb-bd8d-ef998983ad77|>π_rand_blackjack$70d9d39f-020d-4f25-810c-82a143a3335bmeanblackjack_stateindex1$04752549-ffca-4e31-869e-714f835d3e85π_blackjack1$7fb4244c-828a-49d6-a15b-178fa3a42e00$b39d1ea0-86a2-4215-ae73-e4492f3f2f00precedence_heuristic	cell_id$b39d1ea0-86a2-4215-ae73-e4492f3f2f00downstream_cells_mapupstream_cells_map@md_strgetindex$a307e780-996a-485f-af59-b44982dfceb4precedence_heuristic	cell_id$a307e780-996a-485f-af59-b44982dfceb4downstream_cells_maprendertrack$154edd83-350d-4acf-adfb-6a2d20599b53$8bcaa31b-8caf-43da-83a0-47e0c04c2a30$ba044e4f-e2a6-4f96-8756-5b24b1bb5ca2upstream_cells_map Dictvcat!@htllengtheachindexmakegridsquare$7ee4e17e-c1a9-4df0-a014-114bebcb4f52$c8be6951-b6ec-4444-8c7f-ca5db6681571HypertextLiteral.ResultisemptylastextremaHypertextLiteral.Bypassfirst|>unionHypertextLiteral.content=>haskeyreduceHTMLHypertextLiteral$77cf7fee-0ad8-4d22-b376-75833307db93*$b040f245-b2d6-4ec6-aa7f-511c54aabd0dprecedence_heuristic	cell_id$b040f245-b2d6-4ec6-aa7f-511c54aabd0ddownstream_cells_mapupstream_cells_mapπstar_blackjack2$bf19e6cf-1fb5-49c9-974e-1613d90ef4cffigure_5_2$627d5aa3-974f-4949-8b65-9500eba1d7ccQstar_blackjack2$bf19e6cf-1fb5-49c9-974e-1613d90ef4cf$7cdf4142-82fe-4aa6-9665-84a1eef5d038precedence_heuristic	cell_id$7cdf4142-82fe-4aa6-9665-84a1eef5d038downstream_cells_maprace_1_2$66645f1a-b591-43e7-b931-8ed0cc7d6898upstream_cells_mapCoreBasePlutoRunner.create_bondPlutoRunnerCore.applicable@bindBase.getButton$3d10f89f-876e-4d25-b8d6-34ce5c99eb8cprecedence_heuristic	cell_id$3d10f89f-876e-4d25-b8d6-34ce5c99eb8cdownstream_cells_mapupstream_cells_maptrack1_mdp$9df79a71-e58a-497b-bb02-debb69144925πstar2_racetrack1$68f9e0d9-5c9d-4e89-b5ae-f24fd7544a09track1$df3c4a33-45f1-4cc2-8c06-d500a0eecc8fshowrace$154edd83-350d-4acf-adfb-6a2d20599b53run2_1$7ce6e28e-acd7-46d1-87d6-a25f4656d79dcreate_policy_function$d6e7cc6d-f397-4bdf-974e-9a16922393dd$772b4dd6-870c-4a16-937c-701d5bb5da44precedence_heuristic	cell_id$772b4dd6-870c-4a16-937c-701d5bb5da44downstream_cells_maprun3_1$b7dfc031-6bf6-44cd-b814-05f693a0a27dupstream_cells_mapCoreBasePlutoRunner.create_bondPlutoRunnerCore.applicable@bindBase.getButton$1aaf3827-5851-4156-a7e6-14f5e4d00238precedence_heuristic	cell_id$1aaf3827-5851-4156-a7e6-14f5e4d00238downstream_cells_mapupstream_cells_map@md_strgetindex$d6e7cc6d-f397-4bdf-974e-9a16922393ddprecedence_heuristic	cell_id$d6e7cc6d-f397-4bdf-974e-9a16922393dddownstream_cells_mapcreate_policy_function$9524a3f5-fca3-4ce9-b04d-0cb6c0cd0c90$1067fcc4-cbc6-453c-a996-d420c498619a$66645f1a-b591-43e7-b931-8ed0cc7d6898$11f8290f-f589-49ff-9602-99ccc4192884$3d10f89f-876e-4d25-b8d6-34ce5c99eb8c$0609ad22-0adc-4e4f-afed-b7a46d216576$4481fa33-1ff3-4778-8486-d4d8a15775cd$aa647f3e-a4b2-4825-bb2a-1c2469d2c0eb$b7dfc031-6bf6-44cd-b814-05f693a0a27d$985f0537-2bbe-4dbb-a113-8ac98d2e0a5f$6f914006-1d8d-41f5-ae8a-fbe0b336946c$821ce23a-524b-4203-96d6-4d5b454fe1fdupstream_cells_mapsample_action$a85e7dd3-ea5e-4c77-a18e-f1e190658ae3$1951fc4c-acc4-49a6-a907-7447ff0f430aprecedence_heuristic	cell_id$1951fc4c-acc4-49a6-a907-7447ff0f430adownstream_cells_mapupstream_cells_map@md_strgetindexopmc2$8668ffc3-6c8c-4c25-8d47-9977bef929d2$660ef59c-205c-44c2-9c46-5a74e09497abprecedence_heuristic	cell_id$660ef59c-205c-44c2-9c46-5a74e09497abdownstream_cells_mapWeighted$2646c9a2-46b1-4700-9290-ddc7dc9a59af$020131a1-c68b-403a-9c5e-944edb6220e9$1e6f7e5e-c5ce-479c-abbb-6c388c254626$00cd2194-af13-415a-b725-bb34832e5d9a$5948f670-1203-4b75-8517-f8470f5d01aa$61d8cfc6-a50c-4546-9e1f-dc73d4764bb9$5e012ead-b4f9-45a9-979d-88b0b1086263upstream_cells_mapImportanceMethod$d97f693d-27f2-49be-a549-07a290c95b53$a47474b0-f262-4453-a116-addc3a09119eprecedence_heuristic	cell_id$a47474b0-f262-4453-a116-addc3a09119edownstream_cells_mapq_offpol$2ed0d4bb-bb6e-4adf-ad7c-8ddeb8c20b84upstream_cells_mapmonte_carlo_pred_Q$e67d9deb-a074-48ba-84db-2e6938ea01f8blackjack_mdp$6d765229-2816-4abb-a868-6be919a96530π_rand_blackjack$70d9d39f-020d-4f25-810c-82a143a3335bπ_blackjack1$7fb4244c-828a-49d6-a15b-178fa3a42e00$acb270a1-e2b9-46bc-9a52-9f66f1cca17cprecedence_heuristic	cell_id$acb270a1-e2b9-46bc-9a52-9f66f1cca17cdownstream_cells_mapmcϵs1$1d6eccf0-2731-47fc-9a41-ea8649e290ef$648bfc3f-0649-4401-a97f-89e21057f7b7upstream_cells_map@md_strCore:PlutoUI$77cf7fee-0ad8-4d22-b376-75833307db93Base.get@bindBasePlutoRunnerCheckBoxPlutoRunner.create_bondNumberFieldconfirmCore.applicablePlutoUI.combinegetindex$334b4d77-8784-46be-b9e8-80c0a2244694precedence_heuristic	cell_id$334b4d77-8784-46be-b9e8-80c0a2244694downstream_cells_mapmonte_carlo_ϵsoft$bf19e6cf-1fb5-49c9-974e-1613d90ef4cf$1d6eccf0-2731-47fc-9a41-ea8649e290ef$cde7be85-9344-4526-bcb2-c2c8b3322435upstream_cells_map zero:>zerosislessBoolIntegercopyRealsample_action$a85e7dd3-ea5e-4c77-a18e-f1e190658ae3<Int64-make_ϵsoft_policy!$abdcbbad-747a-41ba-a95d-82404e735793length/Matrix+make_greedy_policy!$2d10281a-a4af-4ea8-b63b-e11f2d0893edMDP_Opaque$21d248f5-edad-4614-8c1c-ae330f9e5a18*$e5384dd0-fad1-4a24-b011-73b062fcfb1bprecedence_heuristic	cell_id$e5384dd0-fad1-4a24-b011-73b062fcfb1bdownstream_cells_mapupstream_cells_map@md_strgetindex$35914757-6af1-4056-bba4-a9996f65f7f7precedence_heuristic	cell_id$35914757-6af1-4056-bba4-a9996f65f7f7downstream_cells_mapupstream_cells_mapmonte_carlo_pred_Q$e67d9deb-a074-48ba-84db-2e6938ea01f8onestate_π_b$82a1f11e-b1b3-4c7d-ab9d-9f6136ae8195onestate_mdp$f071b7e2-3f78-4132-8b84-f810f178c89donestate_π_target$61eb74eb-88e0-42e6-a14b-3730a800694d$cde7be85-9344-4526-bcb2-c2c8b3322435precedence_heuristic	cell_id$cde7be85-9344-4526-bcb2-c2c8b3322435downstream_cells_mapπstar3_racetrack2$6f914006-1d8d-41f5-ae8a-fbe0b336946c$821ce23a-524b-4203-96d6-4d5b454fe1fdQstar3_racetrack2upstream_cells_maptrack2_mdp$e7de31e8-ae95-4616-86a9-a115a5e24330mcϵs2$1117e6c3-2736-46a4-bac2-d3c99c1998b6Float32monte_carlo_ϵsoft$334b4d77-8784-46be-b9e8-80c0a2244694$54f73eb8-dcea-4da0-83af-35720e56ccbc$881ba6c3-0e6a-4bb8-bc14-2e0face560f2precedence_heuristic	cell_id$881ba6c3-0e6a-4bb8-bc14-2e0face560f2downstream_cells_mapupstream_cells_map@md_strgetindex$5c57e4b7-51d6-492d-9fc9-bcdab1dd46f4precedence_heuristic	cell_id$5c57e4b7-51d6-492d-9fc9-bcdab1dd46f4downstream_cells_mapplot_blackjack_policy$627d5aa3-974f-4949-8b65-9500eba1d7ccupstream_cells_mapblackjack_mdp$6d765229-2816-4abb-a868-6be919a96530:-blackjackstates$e87932d9-fbc0-4ea5-a8ee-28eac5eed84fplotheatmapattrzerosFloat64Layout$e0d3d7d1-203f-42fa-8570-8d1d88bf17c2precedence_heuristic	cell_id$e0d3d7d1-203f-42fa-8570-8d1d88bf17c2downstream_cells_mapupstream_cells_map@md_strgetindex$760c5361-02d4-46b7-a05c-fc2d10d93de6precedence_heuristic	cell_id$760c5361-02d4-46b7-a05c-fc2d10d93de6downstream_cells_mapmonte_carlo_pred_V$94be5289-bba7-4490-bdcd-0d217a31c665$892b5d8e-ac51-48f1-8288-65e9f68acd2d$43f9b824-fd56-4d56-84c3-23e2a3a37178$00cd2194-af13-415a-b725-bb34832e5d9a$5948f670-1203-4b75-8517-f8470f5d01aaupstream_cells_map zero:zerosonesIntegernothingVectorsample_action$a85e7dd3-ea5e-4c77-a18e-f1e190658ae3length-/Matrix+check_policy$11723075-d1db-4512-abf2-3fe494a71a3bMDP_Opaque$21d248f5-edad-4614-8c1c-ae330f9e5a18==*AbstractFloat$d55860d1-e4c1-4a79-adbe-b40a6d6283a7precedence_heuristic	cell_id$d55860d1-e4c1-4a79-adbe-b40a6d6283a7downstream_cells_mapinitialize_state_action_value$1b78b25d-3942-4a6b-a2bd-7d97242da9fe$54f73eb8-dcea-4da0-83af-35720e56ccbc$924f4e74-e3a0-42eb-89da-1f9836275588upstream_cells_maplengthones*MDP_Opaque$21d248f5-edad-4614-8c1c-ae330f9e5a18AbstractFloat$06297d75-121a-4178-b45b-83e167efd90dprecedence_heuristic	cell_id$06297d75-121a-4178-b45b-83e167efd90ddownstream_cells_mapjoinlines$e370dbb3-3bd9-4dc8-b8ca-8aad8711905cupstream_cells_map$abe70666-39f8-4f1d-a285-a3a99f696d10precedence_heuristic	cell_id$abe70666-39f8-4f1d-a285-a3a99f696d10downstream_cells_mapupstream_cells_map@md_strgetindex$7ce6e28e-acd7-46d1-87d6-a25f4656d79dprecedence_heuristic	cell_id$7ce6e28e-acd7-46d1-87d6-a25f4656d79ddownstream_cells_maprun2_1$3d10f89f-876e-4d25-b8d6-34ce5c99eb8cupstream_cells_mapCoreBasePlutoRunner.create_bondPlutoRunnerCore.applicable@bindBase.getButton$a85e7dd3-ea5e-4c77-a18e-f1e190658ae3precedence_heuristic	cell_id$a85e7dd3-ea5e-4c77-a18e-f1e190658ae3downstream_cells_mapsample_action$760c5361-02d4-46b7-a05c-fc2d10d93de6$e87932d9-fbc0-4ea5-a8ee-28eac5eed84f$334b4d77-8784-46be-b9e8-80c0a2244694$d11bfcf9-b964-4c67-afdc-53d81f051fd5$acb08e38-fc87-43f4-ac2d-6c6bf0f2e9e6$f071b7e2-3f78-4132-8b84-f810f178c89d$e67d9deb-a074-48ba-84db-2e6938ea01f8$924f4e74-e3a0-42eb-89da-1f9836275588$a0d61852-9942-42de-b554-572c4526a3a8$d6e7cc6d-f397-4bdf-974e-9a16922393ddupstream_cells_map:weightsMatrixsizesampleIntegerAbstractFloat$68f9e0d9-5c9d-4e89-b5ae-f24fd7544a09precedence_heuristic	cell_id$68f9e0d9-5c9d-4e89-b5ae-f24fd7544a09downstream_cells_mapQstar2_racetrack1πstar2_racetrack1$3d10f89f-876e-4d25-b8d6-34ce5c99eb8c$0609ad22-0adc-4e4f-afed-b7a46d216576upstream_cells_maptrack1_mdp$9df79a71-e58a-497b-bb02-debb69144925mces1$989ccacd-b410-4967-bf6a-9244e3be785dmonte_carlo_ES$13cc524c-d983-44f4-8731-0595249fb888$1b78b25d-3942-4a6b-a2bd-7d97242da9fe$ec29865f-3ba3-4bb3-84df-c2b472e03ff2precedence_heuristic	cell_id$ec29865f-3ba3-4bb3-84df-c2b472e03ff2downstream_cells_mapQstar_blackjack$f9bc84ff-c2f9-4ac2-b2ce-34dfcf837a73πstar_blackjack$f9bc84ff-c2f9-4ac2-b2ce-34dfcf837a73upstream_cells_mapblackjack_mdp$6d765229-2816-4abb-a868-6be919a96530monte_carlo_ES$13cc524c-d983-44f4-8731-0595249fb888$1b78b25d-3942-4a6b-a2bd-7d97242da9feπ_blackjack1$7fb4244c-828a-49d6-a15b-178fa3a42e00$1d6eccf0-2731-47fc-9a41-ea8649e290efprecedence_heuristic	cell_id$1d6eccf0-2731-47fc-9a41-ea8649e290efdownstream_cells_mapQstar3_racetrack1πstar3_racetrack1$b7dfc031-6bf6-44cd-b814-05f693a0a27d$985f0537-2bbe-4dbb-a113-8ac98d2e0a5fupstream_cells_maptrack1_mdp$9df79a71-e58a-497b-bb02-debb69144925Float32monte_carlo_ϵsoft$334b4d77-8784-46be-b9e8-80c0a2244694$54f73eb8-dcea-4da0-83af-35720e56ccbcmcϵs1$acb270a1-e2b9-46bc-9a52-9f66f1cca17c$9ca72278-fff6-4b0f-b72c-e0d3768aff73precedence_heuristic	cell_id$9ca72278-fff6-4b0f-b72c-e0d3768aff73downstream_cells_mapupstream_cells_mapfigure5_3$00cd2194-af13-415a-b725-bb34832e5d9a$020131a1-c68b-403a-9c5e-944edb6220e9precedence_heuristic	cell_id$020131a1-c68b-403a-9c5e-944edb6220e9downstream_cells_mapupdatevalue$1e6f7e5e-c5ce-479c-abbb-6c388c254626$61d8cfc6-a50c-4546-9e1f-dc73d4764bb9upstream_cells_map-/*Weighted$660ef59c-205c-44c2-9c46-5a74e09497abReal$c23475f0-c5f0-49ce-a665-f93c8bda0474precedence_heuristic	cell_id$c23475f0-c5f0-49ce-a665-f93c8bda0474downstream_cells_mapmake_blackjack_mdp$6d765229-2816-4abb-a868-6be919a96530upstream_cells_map blackjack_actions$e87932d9-fbc0-4ea5-a8ee-28eac5eed84fdeal$e87932d9-fbc0-4ea5-a8ee-28eac5eed84f>!islessdealer_sim$e87932d9-fbc0-4ea5-a8ee-28eac5eed84flength<Float32Matrix==BlackjackState$e87932d9-fbc0-4ea5-a8ee-28eac5eed84f:playersim$e87932d9-fbc0-4ea5-a8ee-28eac5eed84fblackjackstates$e87932d9-fbc0-4ea5-a8ee-28eac5eed84fBlackjackAction$e87932d9-fbc0-4ea5-a8ee-28eac5eed84fscoregame$e87932d9-fbc0-4ea5-a8ee-28eac5eed84fzerosrandunique_cards$e87932d9-fbc0-4ea5-a8ee-28eac5eed84fpush!-addsum$e87932d9-fbc0-4ea5-a8ee-28eac5eed84fMDP_Opaque$21d248f5-edad-4614-8c1c-ae330f9e5a18$15925cc6-9605-4357-9c2a-cdfe54070989precedence_heuristic	cell_id$15925cc6-9605-4357-9c2a-cdfe54070989downstream_cells_mapupstream_cells_map@md_strgetindex$be7c096c-cc8c-407b-8287-8fb2ee7150a7precedence_heuristic	cell_id$be7c096c-cc8c-407b-8287-8fb2ee7150a7downstream_cells_mapupstream_cells_map@md_strgetindex$9618a093-cdb7-4589-a783-de8e9021b705precedence_heuristic	cell_id$9618a093-cdb7-4589-a783-de8e9021b705downstream_cells_mapupstream_cells_map@md_strgetindex$fa49c253-e016-46a7-ba94-0e7448a7e0aeprecedence_heuristic	cell_id$fa49c253-e016-46a7-ba94-0e7448a7e0aedownstream_cells_mapupstream_cells_map@md_strgetindex$f41dd3e6-81bf-43e4-afc2-fc549b77f610precedence_heuristic	cell_id$f41dd3e6-81bf-43e4-afc2-fc549b77f610downstream_cells_mapπstar2_racetrack2$4481fa33-1ff3-4778-8486-d4d8a15775cd$aa647f3e-a4b2-4825-bb2a-1c2469d2c0ebQstar2_racetrack2upstream_cells_maptrack2_mdp$e7de31e8-ae95-4616-86a9-a115a5e24330mces2$059b1c0f-eb21-4a4a-8aed-64e9ac07b541monte_carlo_ES$13cc524c-d983-44f4-8731-0595249fb888$1b78b25d-3942-4a6b-a2bd-7d97242da9fe$6d765229-2816-4abb-a868-6be919a96530precedence_heuristic	cell_id$6d765229-2816-4abb-a868-6be919a96530downstream_cells_mapblackjack_mdp $94be5289-bba7-4490-bdcd-0d217a31c665$5c57e4b7-51d6-492d-9fc9-bcdab1dd46f4$ec29865f-3ba3-4bb3-84df-c2b472e03ff2$bf19e6cf-1fb5-49c9-974e-1613d90ef4cf$04752549-ffca-4e31-869e-714f835d3e85$e293e184-5938-40b5-a04b-5306760a06ae$70d9d39f-020d-4f25-810c-82a143a3335b$892b5d8e-ac51-48f1-8288-65e9f68acd2d$43f9b824-fd56-4d56-84c3-23e2a3a37178$a59d9c84-d35f-4a9b-9fb6-13e30cdd7c3a$217ecc59-d6e3-48fa-9d6d-700a3947b805$19e42f50-5301-41b9-becb-2368c26b6236$5b32bbc7-dc34-4fc3-bacc-92e55f26a98c$b6eac49e-6742-4594-87a5-821437846b0d$00cd2194-af13-415a-b725-bb34832e5d9a$a47474b0-f262-4453-a116-addc3a09119e$39da4cf9-5265-41bc-83d4-311e86675db7upstream_cells_mapmake_blackjack_mdp$c23475f0-c5f0-49ce-a665-f93c8bda0474$e7de31e8-ae95-4616-86a9-a115a5e24330precedence_heuristic	cell_id$e7de31e8-ae95-4616-86a9-a115a5e24330downstream_cells_maptrack2_mdp$da66b3be-1fe2-4edb-9560-71ce7c0bed12$66645f1a-b591-43e7-b931-8ed0cc7d6898$11f8290f-f589-49ff-9602-99ccc4192884$f41dd3e6-81bf-43e4-afc2-fc549b77f610$4481fa33-1ff3-4778-8486-d4d8a15775cd$aa647f3e-a4b2-4825-bb2a-1c2469d2c0eb$cde7be85-9344-4526-bcb2-c2c8b3322435$6f914006-1d8d-41f5-ae8a-fbe0b336946c$821ce23a-524b-4203-96d6-4d5b454fe1fdupstream_cells_mapmake_track_mdp$a0d61852-9942-42de-b554-572c4526a3a8track2$f7616806-97ab-4b09-accc-4e047691f879$fff54c56-5afe-4d89-9dc5-502d08c89de9precedence_heuristic	cell_id$fff54c56-5afe-4d89-9dc5-502d08c89de9downstream_cells_mapmake_col_set$f7616806-97ab-4b09-accc-4e047691f879upstream_cells_map:Set$9793b5c9-d4ec-492d-a72d-8737bb65c8a5precedence_heuristic	cell_id$9793b5c9-d4ec-492d-a72d-8737bb65c8a5downstream_cells_mapupstream_cells_map@md_strgetindex$1117e6c3-2736-46a4-bac2-d3c99c1998b6precedence_heuristic	cell_id$1117e6c3-2736-46a4-bac2-d3c99c1998b6downstream_cells_mapmcϵs2$cde7be85-9344-4526-bcb2-c2c8b3322435$8d7b9826-b52c-4d5a-8c63-e83a1229a0beupstream_cells_map@md_strCore:PlutoUI$77cf7fee-0ad8-4d22-b376-75833307db93Base.get@bindBasePlutoRunnerCheckBoxPlutoRunner.create_bondNumberFieldconfirmCore.applicablePlutoUI.combinegetindex$5948f670-1203-4b75-8517-f8470f5d01aaprecedence_heuristic	cell_id$5948f670-1203-4b75-8517-f8470f5d01aadownstream_cells_mapfigure_5_4$830d6d61-7259-43e7-8d6d-09bc81818dd9upstream_cells_map '@md_strBase.Threads.==Base.Threads.<=LayoutvcatBase.Threads.*islessonestate_π_b$82a1f11e-b1b3-4c7d-ab9d-9f6136ae8195Base.Threads.threadpoolsizeWeighted$660ef59c-205c-44c2-9c46-5a74e09497abBase.Threads.-VectorBase.Threads.+scatterminBase.Threads.>^Float32Base.Threads.errorBase.Threads.!=@threadsBase.getindex:Base.Threads.threading_runmapreduceonestate_π_target$61eb74eb-88e0-42e6-a14b-3730a800694dBase.Threads.divremBaseBase.Threads.firstindexmonte_carlo_pred_V$760c5361-02d4-46b7-a05c-fc2d10d93de6$d11bfcf9-b964-4c67-afdc-53d81f051fd5-plotattrundefBase.Threads.:onestate_mdp$f071b7e2-3f78-4132-8b84-f810f178c89d*ccallBase.Threads.length$2ed88aa5-fc42-4a57-924d-e918805e2208precedence_heuristic	cell_id$2ed88aa5-fc42-4a57-924d-e918805e2208downstream_cells_mapupstream_cells_map@md_strgetindex$c9bd778c-217a-4664-8cde-841beca10307precedence_heuristic	cell_id$c9bd778c-217a-4664-8cde-841beca10307downstream_cells_mapupstream_cells_mapHypertextLiteral.BypassHypertextLiteral.ResultHypertextLiteral$77cf7fee-0ad8-4d22-b376-75833307db93@htl$605b045d-fe5c-426b-9f55-b7dd1d037c50precedence_heuristic	cell_id$605b045d-fe5c-426b-9f55-b7dd1d037c50downstream_cells_mapupstream_cells_map@md_strmces1$989ccacd-b410-4967-bf6a-9244e3be785dgetindex$88335fca-fd87-487b-9de2-ea7c779b54cfprecedence_heuristic	cell_id$88335fca-fd87-487b-9de2-ea7c779b54cfdownstream_cells_mapupstream_cells_map@md_strgetindex$fd91d00a-f94f-40ff-88a7-9d85f05acc96precedence_heuristic	cell_id$fd91d00a-f94f-40ff-88a7-9d85f05acc96downstream_cells_mapmake_row_set$f7616806-97ab-4b09-accc-4e047691f879upstream_cells_map:Set$a59d9c84-d35f-4a9b-9fb6-13e30cdd7c3aprecedence_heuristic	cell_id$a59d9c84-d35f-4a9b-9fb6-13e30cdd7c3adownstream_cells_mapupstream_cells_mapmonte_carlo_pred_Q$e67d9deb-a074-48ba-84db-2e6938ea01f8blackjack_mdp$6d765229-2816-4abb-a868-6be919a96530Ordinary$4197cc28-b24c-48cb-bd8d-ef998983ad77|>π_rand_blackjack$70d9d39f-020d-4f25-810c-82a143a3335bmeanblackjack_stateindex1$04752549-ffca-4e31-869e-714f835d3e85π_blackjack1$7fb4244c-828a-49d6-a15b-178fa3a42e00$df3c4a33-45f1-4cc2-8c06-d500a0eecc8fprecedence_heuristic	cell_id$df3c4a33-45f1-4cc2-8c06-d500a0eecc8fdownstream_cells_maptrack1$9df79a71-e58a-497b-bb02-debb69144925$5e2420fb-b2cc-49fc-91e3-3de80fba698b$8bcaa31b-8caf-43da-83a0-47e0c04c2a30$3955d71a-3105-445a-868d-66ba0b3dc515$ba044e4f-e2a6-4f96-8756-5b24b1bb5ca2$9524a3f5-fca3-4ce9-b04d-0cb6c0cd0c90$3d10f89f-876e-4d25-b8d6-34ce5c99eb8c$b7dfc031-6bf6-44cd-b814-05f693a0a27dupstream_cells_map:unionSet$e2fc1d47-2ee9-4844-a6b1-16f76531da86precedence_heuristic	cell_id$e2fc1d47-2ee9-4844-a6b1-16f76531da86downstream_cells_maprun3_2$6f914006-1d8d-41f5-ae8a-fbe0b336946cupstream_cells_mapCoreBasePlutoRunner.create_bondPlutoRunnerCore.applicable@bindBase.getButton$2d36ebe3-1a86-4cad-a235-baec726da926precedence_heuristic	cell_id$2d36ebe3-1a86-4cad-a235-baec726da926downstream_cells_mapupstream_cells_map@md_strgetindex$dfc2d648-ec08-49cd-a55f-72a766cad728precedence_heuristic	cell_id$dfc2d648-ec08-49cd-a55f-72a766cad728downstream_cells_mapQstar1_racetrack1πstar1_racetrack1$9524a3f5-fca3-4ce9-b04d-0cb6c0cd0c90$1067fcc4-cbc6-453c-a996-d420c498619aupstream_cells_maptrack1_mdp$9df79a71-e58a-497b-bb02-debb69144925opmc1$846ccb44-a18b-4d87-bbf8-fc59eaf87708off_policy_MC_control$924f4e74-e3a0-42eb-89da-1f9836275588$7ee4e17e-c1a9-4df0-a014-114bebcb4f52precedence_heuristic	cell_id$7ee4e17e-c1a9-4df0-a014-114bebcb4f52downstream_cells_mapmakegridsquare$a307e780-996a-485f-af59-b44982dfceb4upstream_cells_map-+$2d10281a-a4af-4ea8-b63b-e11f2d0893edprecedence_heuristic	cell_id$2d10281a-a4af-4ea8-b63b-e11f2d0893eddownstream_cells_mapmake_greedy_policy!$1d3d509c-b11b-4c57-b100-9bcf0489af2b$13cc524c-d983-44f4-8731-0595249fb888$334b4d77-8784-46be-b9e8-80c0a2244694$924f4e74-e3a0-42eb-89da-1f9836275588upstream_cells_mapextremaexpsumAbstractVectoroneReallength-/*==abs$e87932d9-fbc0-4ea5-a8ee-28eac5eed84fprecedence_heuristic	cell_id$e87932d9-fbc0-4ea5-a8ee-28eac5eed84fdownstream_cells_map BlackjackState$e87932d9-fbc0-4ea5-a8ee-28eac5eed84f$c23475f0-c5f0-49ce-a665-f93c8bda0474$02dd1e77-2a7e-4123-94db-d17b31a8b15ablackjack_actions$c23475f0-c5f0-49ce-a665-f93c8bda0474playersim$c23475f0-c5f0-49ce-a665-f93c8bda0474deal$c23475f0-c5f0-49ce-a665-f93c8bda0474BlackjackAction$e87932d9-fbc0-4ea5-a8ee-28eac5eed84f$c23475f0-c5f0-49ce-a665-f93c8bda0474scoregame$c23475f0-c5f0-49ce-a665-f93c8bda0474blackjackstates$481ad435-cc80-4164-882d-8310b010ca91$c23475f0-c5f0-49ce-a665-f93c8bda0474$a35de859-4046-4f6d-9ea9-b523d21cee5d$5c57e4b7-51d6-492d-9fc9-bcdab1dd46f4dealer_sim$c23475f0-c5f0-49ce-a665-f93c8bda0474Stick$e87932d9-fbc0-4ea5-a8ee-28eac5eed84faddsumaceblackjack_statelookupunique_cards$c23475f0-c5f0-49ce-a665-f93c8bda0474π_blackjack_randomcardsaddsum$c23475f0-c5f0-49ce-a665-f93c8bda0474Hit$e87932d9-fbc0-4ea5-a8ee-28eac5eed84fupstream_cells_map !>islessVectorlengthsample_action$a85e7dd3-ea5e-4c77-a18e-f1e190658ae3<Float32/Matrix==BlackjackState$e87932d9-fbc0-4ea5-a8ee-28eac5eed84f:Stick$e87932d9-fbc0-4ea5-a8ee-28eac5eed84fBlackjackAction$e87932d9-fbc0-4ea5-a8ee-28eac5eed84fcollectonesBoolrandmakelookup$72e9721f-ee17-4557-b090-71728e6c22ceInt64push!->=+Hit$e87932d9-fbc0-4ea5-a8ee-28eac5eed84f$1cc46e33-6885-4d6f-805e-9ff928f1cf23precedence_heuristic	cell_id$1cc46e33-6885-4d6f-805e-9ff928f1cf23downstream_cells_mapracetrackspeeds$f9f6c182-62f8-4a5a-8b43-8716db468427$f506e8ba-b073-4f59-91b4-3fe99822d2a4upstream_cells_mapuniquenormracetrack_velocities$63814164-f305-49b3-ab51-675c822d7b18$f79d97bb-341a-46ad-bdfc-d080af13e2dfprecedence_heuristic	cell_id$f79d97bb-341a-46ad-bdfc-d080af13e2dfdownstream_cells_mapupstream_cells_map@md_strgetindex$6a11daf7-2859-41fa-9c3d-d1f3580dbb5fprecedence_heuristic	cell_id$6a11daf7-2859-41fa-9c3d-d1f3580dbb5fdownstream_cells_mapupstream_cells_map@md_strgetindex$985f0537-2bbe-4dbb-a113-8ac98d2e0a5fprecedence_heuristic	cell_id$985f0537-2bbe-4dbb-a113-8ac98d2e0a5fdownstream_cells_mapupstream_cells_maptrack1_mdp$9df79a71-e58a-497b-bb02-debb69144925πstar3_racetrack1$1d6eccf0-2731-47fc-9a41-ea8649e290efsampleracepolicy$8f38a3e9-1872-4ea6-9a03-87112af4bf07create_policy_function$d6e7cc6d-f397-4bdf-974e-9a16922393dd$217ecc59-d6e3-48fa-9d6d-700a3947b805precedence_heuristic	cell_id$217ecc59-d6e3-48fa-9d6d-700a3947b805downstream_cells_mapupstream_cells_mapmonte_carlo_pred_Q$e67d9deb-a074-48ba-84db-2e6938ea01f8blackjack_mdp$6d765229-2816-4abb-a868-6be919a96530:sumOrdinary$4197cc28-b24c-48cb-bd8d-ef998983ad77|>π_rand_blackjack$70d9d39f-020d-4f25-810c-82a143a3335bmeanblackjack_stateindex1$04752549-ffca-4e31-869e-714f835d3e85π_blackjack1$7fb4244c-828a-49d6-a15b-178fa3a42e00$a35de859-4046-4f6d-9ea9-b523d21cee5dprecedence_heuristic	cell_id$a35de859-4046-4f6d-9ea9-b523d21cee5ddownstream_cells_mapmake_value_grid$94be5289-bba7-4490-bdcd-0d217a31c665$06960937-a87a-4015-bdeb-5d17aa41fe6bupstream_cells_map-blackjackstates$e87932d9-fbc0-4ea5-a8ee-28eac5eed84fFloat32enumeratezeros$12c0cd0b-eb4f-45a0-836b-53b3c5cdafd9precedence_heuristic	cell_id$12c0cd0b-eb4f-45a0-836b-53b3c5cdafd9downstream_cells_mapupstream_cells_map@md_strgetindex$aaa9647c-afb6-44d1-ae1e-a2e957064080precedence_heuristic	cell_id$aaa9647c-afb6-44d1-ae1e-a2e957064080downstream_cells_mapupdatecount$1e6f7e5e-c5ce-479c-abbb-6c388c254626$61d8cfc6-a50c-4546-9e1f-dc73d4764bb9upstream_cells_mapOrdinary$4197cc28-b24c-48cb-bd8d-ef998983ad77oneReal$b57462b6-8f9c-4553-9c05-134ff043b00dprecedence_heuristic	cell_id$b57462b6-8f9c-4553-9c05-134ff043b00ddownstream_cells_mapupstream_cells_map@md_strgetindex$f506e8ba-b073-4f59-91b4-3fe99822d2a4precedence_heuristic	cell_id$f506e8ba-b073-4f59-91b4-3fe99822d2a4downstream_cells_mapscalelookup$d2625507-4787-4b1c-9a91-108012e42cc7upstream_cells_mapDictInt64racetrackspeeds$1cc46e33-6885-4d6f-805e-9ff928f1cf23/*maxspeed$f9f6c182-62f8-4a5a-8b43-8716db468427=>round$bf19e6cf-1fb5-49c9-974e-1613d90ef4cfprecedence_heuristic	cell_id$bf19e6cf-1fb5-49c9-974e-1613d90ef4cfdownstream_cells_mapπstar_blackjack2$b040f245-b2d6-4ec6-aa7f-511c54aabd0dQstar_blackjack2$b040f245-b2d6-4ec6-aa7f-511c54aabd0dupstream_cells_mapblackjack_mdp$6d765229-2816-4abb-a868-6be919a96530monte_carlo_ϵsoft$334b4d77-8784-46be-b9e8-80c0a2244694$54f73eb8-dcea-4da0-83af-35720e56ccbc$77cf7fee-0ad8-4d22-b376-75833307db93precedence_heuristiccell_id$77cf7fee-0ad8-4d22-b376-75833307db93downstream_cells_mapStatisticsStatsBaseLinearAlgebraPlutoUI$acb270a1-e2b9-46bc-9a52-9f66f1cca17c$1117e6c3-2736-46a4-bac2-d3c99c1998b6HypertextLiteral$a68b4965-c392-47e5-9b29-93e7ada9990a$2572e35c-e6a3-4562-aa0f-6a5ab32d39ea$c9bd778c-217a-4664-8cde-841beca10307$a307e780-996a-485f-af59-b44982dfceb4$154edd83-350d-4acf-adfb-6a2d20599b53$e370dbb3-3bd9-4dc8-b8ca-8aad8711905c$8bcaa31b-8caf-43da-83a0-47e0c04c2a30$ba044e4f-e2a6-4f96-8756-5b24b1bb5ca2ThreadsPlutoPlotlyLaTeXStringsupstream_cells_mapTableOfContents$d11bfcf9-b964-4c67-afdc-53d81f051fd5precedence_heuristic	cell_id$d11bfcf9-b964-4c67-afdc-53d81f051fd5downstream_cells_mapmonte_carlo_pred_V$94be5289-bba7-4490-bdcd-0d217a31c665$892b5d8e-ac51-48f1-8288-65e9f68acd2d$43f9b824-fd56-4d56-84c3-23e2a3a37178$00cd2194-af13-415a-b725-bb34832e5d9a$5948f670-1203-4b75-8517-f8470f5d01aaupstream_cells_map zero@assertVectorlengthsample_action$a85e7dd3-ea5e-4c77-a18e-f1e190658ae3throwMatrixAssertionError!===AbstractFloat:Ordinary$4197cc28-b24c-48cb-bd8d-ef998983ad77ImportanceMethod$d97f693d-27f2-49be-a549-07a290c95b53zerosonesBoolupdateV!$1e6f7e5e-c5ce-479c-abbb-6c388c254626Integerall+check_policy$11723075-d1db-4512-abf2-3fe494a71a3b*MDP_Opaque$21d248f5-edad-4614-8c1c-ae330f9e5a18$19e42f50-5301-41b9-becb-2368c26b6236precedence_heuristic	cell_id$19e42f50-5301-41b9-becb-2368c26b6236downstream_cells_mapupstream_cells_mapmonte_carlo_pred_Q$e67d9deb-a074-48ba-84db-2e6938ea01f8blackjack_mdp$6d765229-2816-4abb-a868-6be919a96530:Ordinary$4197cc28-b24c-48cb-bd8d-ef998983ad77|>π_rand_blackjack$70d9d39f-020d-4f25-810c-82a143a3335bmeanblackjack_stateindex1$04752549-ffca-4e31-869e-714f835d3e85π_blackjack1$7fb4244c-828a-49d6-a15b-178fa3a42e00$924f4e74-e3a0-42eb-89da-1f9836275588precedence_heuristic	cell_id$924f4e74-e3a0-42eb-89da-1f9836275588downstream_cells_mapoff_policy_MC_control$39da4cf9-5265-41bc-83d4-311e86675db7$dfc2d648-ec08-49cd-a55f-72a766cad728$da66b3be-1fe2-4edb-9560-71ce7c0bed12upstream_cells_map zero:zerosoneIntegerlengthsample_action$a85e7dd3-ea5e-4c77-a18e-f1e190658ae3make_random_policy$b2115f33-f8e2-452e-9b0e-90610f0f09b1create_greedy_policy$1d3d509c-b11b-4c57-b100-9bcf0489af2b-/Matrix+make_greedy_policy!$2d10281a-a4af-4ea8-b63b-e11f2d0893edMDP_Opaque$21d248f5-edad-4614-8c1c-ae330f9e5a18==initialize_state_action_value$d55860d1-e4c1-4a79-adbe-b40a6d6283a7*AbstractFloat$6dc0de46-2164-4580-b186-a73cb5b5167dprecedence_heuristic	cell_id$6dc0de46-2164-4580-b186-a73cb5b5167ddownstream_cells_mapproject_path$658ceeaa-1b45-47bd-a364-eaa1759d17acupstream_cells_map<:isless+clamp==randSet$63814164-f305-49b3-ab51-675c822d7b18precedence_heuristic	cell_id$63814164-f305-49b3-ab51-675c822d7b18downstream_cells_mapracetrack_velocities$1cc46e33-6885-4d6f-805e-9ff928f1cf23$a0d61852-9942-42de-b554-572c4526a3a8$e370dbb3-3bd9-4dc8-b8ca-8aad8711905cupstream_cells_map:$4337b83f-b648-4b55-9d2a-4fffcf701111precedence_heuristic	cell_id$4337b83f-b648-4b55-9d2a-4fffcf701111downstream_cells_mapupstream_cells_mapBaseBase.Docs.HTML@html_str$1b78b25d-3942-4a6b-a2bd-7d97242da9feprecedence_heuristic	cell_id$1b78b25d-3942-4a6b-a2bd-7d97242da9fedownstream_cells_mapmonte_carlo_ES$ec29865f-3ba3-4bb3-84df-c2b472e03ff2$68f9e0d9-5c9d-4e89-b5ae-f24fd7544a09$f41dd3e6-81bf-43e4-afc2-fc549b77f610upstream_cells_mapmake_random_policy$b2115f33-f8e2-452e-9b0e-90610f0f09b1zeroMatrixMDP_Opaque$21d248f5-edad-4614-8c1c-ae330f9e5a18initialize_state_action_value$d55860d1-e4c1-4a79-adbe-b40a6d6283a7oneReal$9524a3f5-fca3-4ce9-b04d-0cb6c0cd0c90precedence_heuristic	cell_id$9524a3f5-fca3-4ce9-b04d-0cb6c0cd0c90downstream_cells_mapupstream_cells_maptrack1_mdp$9df79a71-e58a-497b-bb02-debb69144925track1$df3c4a33-45f1-4cc2-8c06-d500a0eecc8frun1_1$833bb53c-bc2b-47fb-9429-d0f6d92efb42showrace$154edd83-350d-4acf-adfb-6a2d20599b53πstar1_racetrack1$dfc2d648-ec08-49cd-a55f-72a766cad728create_policy_function$d6e7cc6d-f397-4bdf-974e-9a16922393dd$2ed0d4bb-bb6e-4adf-ad7c-8ddeb8c20b84precedence_heuristic	cell_id$2ed0d4bb-bb6e-4adf-ad7c-8ddeb8c20b84downstream_cells_mapupstream_cells_map:q_offpol$a47474b0-f262-4453-a116-addc3a09119eblackjack_stateindex1$04752549-ffca-4e31-869e-714f835d3e85$a0d61852-9942-42de-b554-572c4526a3a8precedence_heuristic	cell_id$a0d61852-9942-42de-b554-572c4526a3a8downstream_cells_mapmake_track_mdp$9df79a71-e58a-497b-bb02-debb69144925$e7de31e8-ae95-4616-86a9-a115a5e24330upstream_cells_maprace_track_episode$658ceeaa-1b45-47bd-a364-eaa1759d17acracetrack_velocities$63814164-f305-49b3-ab51-675c822d7b18sample_action$a85e7dd3-ea5e-4c77-a18e-f1e190658ae3Infunionracetrack_actions$bb617e58-2700-4f0d-b8c8-3a266142fb70MDP_Opaque$21d248f5-edad-4614-8c1c-ae330f9e5a18randmakelookup$72e9721f-ee17-4557-b090-71728e6c22ce$bb617e58-2700-4f0d-b8c8-3a266142fb70precedence_heuristic	cell_id$bb617e58-2700-4f0d-b8c8-3a266142fb70downstream_cells_mapracetrack_actions$a0d61852-9942-42de-b554-572c4526a3a8$8f38a3e9-1872-4ea6-9a03-87112af4bf07$e370dbb3-3bd9-4dc8-b8ca-8aad8711905c$0dfd7afb-127c-4afd-8374-3c9a20a9ee76$3955d71a-3105-445a-868d-66ba0b3dc515$ff9276eb-2151-4a6f-8257-8348047a9f4eupstream_cells_map:$0d9c5d60-878a-45bb-8707-275cf10be41fprecedence_heuristic	cell_id$0d9c5d60-878a-45bb-8707-275cf10be41fdownstream_cells_maprun2_2$4481fa33-1ff3-4778-8486-d4d8a15775cdupstream_cells_mapCoreBasePlutoRunner.create_bondPlutoRunnerCore.applicable@bindBase.getButton$b6eac49e-6742-4594-87a5-821437846b0dprecedence_heuristic	cell_id$b6eac49e-6742-4594-87a5-821437846b0ddownstream_cells_maptest$847a074c-1d23-4de3-a039-322aeb9f7613upstream_cells_mapmonte_carlo_pred_Q$e67d9deb-a074-48ba-84db-2e6938ea01f8blackjack_mdp$6d765229-2816-4abb-a868-6be919a96530:sumOrdinary$4197cc28-b24c-48cb-bd8d-ef998983ad77mode|>blackjack_stateindex1$04752549-ffca-4e31-869e-714f835d3e85median-π_rand_blackjack$70d9d39f-020d-4f25-810c-82a143a3335b==meanπ_blackjack1$7fb4244c-828a-49d6-a15b-178fa3a42e00$61d8cfc6-a50c-4546-9e1f-dc73d4764bb9precedence_heuristic	cell_id$61d8cfc6-a50c-4546-9e1f-dc73d4764bb9downstream_cells_mapupdateQ!$e67d9deb-a074-48ba-84db-2e6938ea01f8upstream_cells_map zeroImportanceMethod$d97f693d-27f2-49be-a549-07a290c95b53oneWeighted$660ef59c-205c-44c2-9c46-5a74e09497abVectorlengthisaRealupdatecount$aaa9647c-afb6-44d1-ae1e-a2e957064080$2646c9a2-46b1-4700-9290-ddc7dc9a59af-updatevalue$c8f3f7e3-be7e-4615-a667-d9f789928883$020131a1-c68b-403a-9c5e-944edb6220e9/Matrix+*==$847a074c-1d23-4de3-a039-322aeb9f7613precedence_heuristic	cell_id$847a074c-1d23-4de3-a039-322aeb9f7613downstream_cells_mapupstream_cells_maptest$b6eac49e-6742-4594-87a5-821437846b0d$d2625507-4787-4b1c-9a91-108012e42cc7precedence_heuristic	cell_id$d2625507-4787-4b1c-9a91-108012e42cc7downstream_cells_mapmake_rotation_style$e370dbb3-3bd9-4dc8-b8ca-8aad8711905cupstream_cells_mapatandscalelookup$f506e8ba-b073-4f59-91b4-3fe99822d2a4norm==$94be5289-bba7-4490-bdcd-0d217a31c665precedence_heuristic	cell_id$94be5289-bba7-4490-bdcd-0d217a31c665downstream_cells_mapeval_blackjack_policy$a68b4965-c392-47e5-9b29-93e7ada9990aupstream_cells_mapmonte_carlo_pred_V$760c5361-02d4-46b7-a05c-fc2d10d93de6$d11bfcf9-b964-4c67-afdc-53d81f051fd5blackjack_mdp$6d765229-2816-4abb-a868-6be919a96530make_value_grid$a35de859-4046-4f6d-9ea9-b523d21cee5d$f7616806-97ab-4b09-accc-4e047691f879precedence_heuristic	cell_id$f7616806-97ab-4b09-accc-4e047691f879downstream_cells_maptrack2$e7de31e8-ae95-4616-86a9-a115a5e24330$8bcaa31b-8caf-43da-83a0-47e0c04c2a30$ff9276eb-2151-4a6f-8257-8348047a9f4e$ba044e4f-e2a6-4f96-8756-5b24b1bb5ca2$66645f1a-b591-43e7-b931-8ed0cc7d6898$11f8290f-f589-49ff-9602-99ccc4192884$4481fa33-1ff3-4778-8486-d4d8a15775cd$aa647f3e-a4b2-4825-bb2a-1c2469d2c0eb$6f914006-1d8d-41f5-ae8a-fbe0b336946c$821ce23a-524b-4203-96d6-4d5b454fe1fdupstream_cells_map:make_col_set$fff54c56-5afe-4d89-9dc5-502d08c89de9zipunionmake_row_set$fd91d00a-f94f-40ff-88a7-9d85f05acc96$70d9d39f-020d-4f25-810c-82a143a3335bprecedence_heuristic	cell_id$70d9d39f-020d-4f25-810c-82a143a3335bdownstream_cells_mapπ_rand_blackjack$8faca500-b80d-4b50-88b6-683d18a1286b$892b5d8e-ac51-48f1-8288-65e9f68acd2d$43f9b824-fd56-4d56-84c3-23e2a3a37178$a59d9c84-d35f-4a9b-9fb6-13e30cdd7c3a$217ecc59-d6e3-48fa-9d6d-700a3947b805$19e42f50-5301-41b9-becb-2368c26b6236$5b32bbc7-dc34-4fc3-bacc-92e55f26a98c$b6eac49e-6742-4594-87a5-821437846b0d$00cd2194-af13-415a-b725-bb34832e5d9a$a47474b0-f262-4453-a116-addc3a09119eupstream_cells_mapmake_random_policy$b2115f33-f8e2-452e-9b0e-90610f0f09b1blackjack_mdp$6d765229-2816-4abb-a868-6be919a96530$780f2fd9-49c3-48bc-b790-dde5be1dc81bprecedence_heuristic	cell_id$780f2fd9-49c3-48bc-b790-dde5be1dc81bdownstream_cells_mapupstream_cells_maptrack1_mdp$9df79a71-e58a-497b-bb02-debb69144925$833bb53c-bc2b-47fb-9429-d0f6d92efb42precedence_heuristic	cell_id$833bb53c-bc2b-47fb-9429-d0f6d92efb42downstream_cells_maprun1_1$9524a3f5-fca3-4ce9-b04d-0cb6c0cd0c90upstream_cells_mapCoreBasePlutoRunner.create_bondPlutoRunnerCore.applicable@bindBase.getButton$e370dbb3-3bd9-4dc8-b8ca-8aad8711905cprecedence_heuristic	cell_id$e370dbb3-3bd9-4dc8-b8ca-8aad8711905cdownstream_cells_mapupstream_cells_mapmake_rotation_style$d2625507-4787-4b1c-9a91-108012e42cc7HypertextLiteral.Bypassmapreduceracetrack_actions$bb617e58-2700-4f0d-b8c8-3a266142fb70make_action_style$ba8a5804-4be3-43fe-95d7-c957ce02a1d4@htlHypertextLiteral.ResultHypertextLiteral$77cf7fee-0ad8-4d22-b376-75833307db93joinlines$06297d75-121a-4178-b45b-83e167efd90dHypertextLiteral.StyleTagracetrack_velocities$63814164-f305-49b3-ab51-675c822d7b18$2646c9a2-46b1-4700-9290-ddc7dc9a59afprecedence_heuristic	cell_id$2646c9a2-46b1-4700-9290-ddc7dc9a59afdownstream_cells_mapupdatecount$1e6f7e5e-c5ce-479c-abbb-6c388c254626$61d8cfc6-a50c-4546-9e1f-dc73d4764bb9upstream_cells_mapWeighted$660ef59c-205c-44c2-9c46-5a74e09497ab$892b5d8e-ac51-48f1-8288-65e9f68acd2dprecedence_heuristic	cell_id$892b5d8e-ac51-48f1-8288-65e9f68acd2ddownstream_cells_mapupstream_cells_mapblackjack_mdp$6d765229-2816-4abb-a868-6be919a96530:sumOrdinary$4197cc28-b24c-48cb-bd8d-ef998983ad77|>blackjack_stateindex1$04752549-ffca-4e31-869e-714f835d3e85monte_carlo_pred_V$760c5361-02d4-46b7-a05c-fc2d10d93de6$d11bfcf9-b964-4c67-afdc-53d81f051fd5/countπ_rand_blackjack$70d9d39f-020d-4f25-810c-82a143a3335b==meanπ_blackjack1$7fb4244c-828a-49d6-a15b-178fa3a42e00$acb08e38-fc87-43f4-ac2d-6c6bf0f2e9e6precedence_heuristic	cell_id$acb08e38-fc87-43f4-ac2d-6c6bf0f2e9e6downstream_cells_mapestimate_mdp_state$e293e184-5938-40b5-a04b-5306760a06aeupstream_cells_mapsample_action$a85e7dd3-ea5e-4c77-a18e-f1e190658ae3:MatrixzeroslastAbstractFloat$fca388bd-eb8b-41e2-8da0-87b9386629c1precedence_heuristic	cell_id$fca388bd-eb8b-41e2-8da0-87b9386629c1downstream_cells_mapupstream_cells_map@md_strgetindexcell_execution_order $77cf7fee-0ad8-4d22-b376-75833307db93$826139cc-b52e-11ec-0d47-25ab689851fd$a85e7dd3-ea5e-4c77-a18e-f1e190658ae3$72e9721f-ee17-4557-b090-71728e6c22ce$21d248f5-edad-4614-8c1c-ae330f9e5a18$b2115f33-f8e2-452e-9b0e-90610f0f09b1$202eb066-877d-4537-85b2-31b41db8eca0$d55860d1-e4c1-4a79-adbe-b40a6d6283a7$11723075-d1db-4512-abf2-3fe494a71a3b$760c5361-02d4-46b7-a05c-fc2d10d93de6$6a11daf7-2859-41fa-9c3d-d1f3580dbb5f$e87932d9-fbc0-4ea5-a8ee-28eac5eed84f$481ad435-cc80-4164-882d-8310b010ca91$7fb4244c-828a-49d6-a15b-178fa3a42e00$c23475f0-c5f0-49ce-a665-f93c8bda0474$6d765229-2816-4abb-a868-6be919a96530$a35de859-4046-4f6d-9ea9-b523d21cee5d$01683e11-a368-45bc-abbc-bbd5c94d7b22$d766d44e-3684-497c-814e-8f71740cb232$e5384dd0-fad1-4a24-b011-73b062fcfb1b$30809344-b4ab-468b-b4b7-5ef3dca5ffc7$f406be9e-3e3f-4b55-99b0-4858c774ed96$be7c096c-cc8c-407b-8287-8fb2ee7150a7$2572e35c-e6a3-4562-aa0f-6a5ab32d39ea$47daf83b-8fe9-4491-b9ae-84bd269d5546$2d10281a-a4af-4ea8-b63b-e11f2d0893ed$1d3d509c-b11b-4c57-b100-9bcf0489af2b$13cc524c-d983-44f4-8731-0595249fb888$1b78b25d-3942-4a6b-a2bd-7d97242da9fe$9618a093-cdb7-4589-a783-de8e9021b705$5c57e4b7-51d6-492d-9fc9-bcdab1dd46f4$06960937-a87a-4015-bdeb-5d17aa41fe6b$627d5aa3-974f-4949-8b65-9500eba1d7cc$ec29865f-3ba3-4bb3-84df-c2b472e03ff2$9fe42679-dce3-4ee3-b565-eed4ff7d8e4d$f9bc84ff-c2f9-4ac2-b2ce-34dfcf837a73$c883748c-76b9-4086-8698-b40df51390da$e2a720b0-a8c4-43a2-bf34-750ff3323004$abdcbbad-747a-41ba-a95d-82404e735793$334b4d77-8784-46be-b9e8-80c0a2244694$54f73eb8-dcea-4da0-83af-35720e56ccbc$bf19e6cf-1fb5-49c9-974e-1613d90ef4cf$3ee31af5-b19c-49dc-8fbf-f07e93d1f0c5$b040f245-b2d6-4ec6-aa7f-511c54aabd0d$12c0cd0b-eb4f-45a0-836b-53b3c5cdafd9$9793b5c9-d4ec-492d-a72d-8737bb65c8a5$15925cc6-9605-4357-9c2a-cdfe54070989$d97f693d-27f2-49be-a549-07a290c95b53$660ef59c-205c-44c2-9c46-5a74e09497ab$4197cc28-b24c-48cb-bd8d-ef998983ad77$aaa9647c-afb6-44d1-ae1e-a2e957064080$2646c9a2-46b1-4700-9290-ddc7dc9a59af$c8f3f7e3-be7e-4615-a667-d9f789928883$020131a1-c68b-403a-9c5e-944edb6220e9$1e6f7e5e-c5ce-479c-abbb-6c388c254626$d11bfcf9-b964-4c67-afdc-53d81f051fd5$94be5289-bba7-4490-bdcd-0d217a31c665$a68b4965-c392-47e5-9b29-93e7ada9990a$82284c63-2306-4469-9b1a-a5ec87037e79$cede8090-5b1a-436b-a184-fca5c4d3de48$c9bd778c-217a-4664-8cde-841beca10307$b39d1ea0-86a2-4215-ae73-e4492f3f2f00$02dd1e77-2a7e-4123-94db-d17b31a8b15a$04752549-ffca-4e31-869e-714f835d3e85$acb08e38-fc87-43f4-ac2d-6c6bf0f2e9e6$e293e184-5938-40b5-a04b-5306760a06ae$d16ac2a8-1a5a-4ded-9285-d2c6cd550066$70d9d39f-020d-4f25-810c-82a143a3335b$8faca500-b80d-4b50-88b6-683d18a1286b$892b5d8e-ac51-48f1-8288-65e9f68acd2d$43f9b824-fd56-4d56-84c3-23e2a3a37178$00cd2194-af13-415a-b725-bb34832e5d9a$9ca72278-fff6-4b0f-b72c-e0d3768aff73$e10378eb-12b3-4468-9c22-1838107da450$f071b7e2-3f78-4132-8b84-f810f178c89d$61eb74eb-88e0-42e6-a14b-3730a800694d$82a1f11e-b1b3-4c7d-ab9d-9f6136ae8195$5948f670-1203-4b75-8517-f8470f5d01aa$830d6d61-7259-43e7-8d6d-09bc81818dd9$881ba6c3-0e6a-4bb8-bc14-2e0face560f2$6979db32-670d-466a-9a6e-97c2d8527f3d$bf33230e-342b-4486-89ac-9667438de503$09b67730-39e7-4209-8117-6bc3adfb342a$fca388bd-eb8b-41e2-8da0-87b9386629c1$b57462b6-8f9c-4553-9c05-134ff043b00d$fa49c253-e016-46a7-ba94-0e7448a7e0ae$6496c993-6d47-4a6e-a497-2a2de172fbc3$61d8cfc6-a50c-4546-9e1f-dc73d4764bb9$e67d9deb-a074-48ba-84db-2e6938ea01f8$a59d9c84-d35f-4a9b-9fb6-13e30cdd7c3a$217ecc59-d6e3-48fa-9d6d-700a3947b805$19e42f50-5301-41b9-becb-2368c26b6236$5b32bbc7-dc34-4fc3-bacc-92e55f26a98c$b6eac49e-6742-4594-87a5-821437846b0d$847a074c-1d23-4de3-a039-322aeb9f7613$a47474b0-f262-4453-a116-addc3a09119e$2ed0d4bb-bb6e-4adf-ad7c-8ddeb8c20b84$35914757-6af1-4056-bba4-a9996f65f7f7$5e012ead-b4f9-45a9-979d-88b0b1086263$7c9486cd-1916-4e13-b415-fb113bd9e04b$924f4e74-e3a0-42eb-89da-1f9836275588$39da4cf9-5265-41bc-83d4-311e86675db7$0bd705cb-ad38-4cbb-b8fc-7e0617635282$418c045d-90c7-42d8-9126-90185f7e197b$ab10ccd7-75ba-475c-af26-f8b36daaf880$cebb79b7-c9d6-4b79-ba0e-b2f3c7587724$67e535c7-437a-49ba-b5ab-9dfe63fe4aaa$63814164-f305-49b3-ab51-675c822d7b18$1cc46e33-6885-4d6f-805e-9ff928f1cf23$f9f6c182-62f8-4a5a-8b43-8716db468427$f506e8ba-b073-4f59-91b4-3fe99822d2a4$bb617e58-2700-4f0d-b8c8-3a266142fb70$6dc0de46-2164-4580-b186-a73cb5b5167d$fd91d00a-f94f-40ff-88a7-9d85f05acc96$fff54c56-5afe-4d89-9dc5-502d08c89de9$658ceeaa-1b45-47bd-a364-eaa1759d17ac$df3c4a33-45f1-4cc2-8c06-d500a0eecc8f$f7616806-97ab-4b09-accc-4e047691f879$a0d61852-9942-42de-b554-572c4526a3a8$9df79a71-e58a-497b-bb02-debb69144925$e7de31e8-ae95-4616-86a9-a115a5e24330$5e2420fb-b2cc-49fc-91e3-3de80fba698b$d6e7cc6d-f397-4bdf-974e-9a16922393dd$8f38a3e9-1872-4ea6-9a03-87112af4bf07$a0eb6939-11bb-458d-bee3-9ed763819f62$7ee4e17e-c1a9-4df0-a014-114bebcb4f52$c8be6951-b6ec-4444-8c7f-ca5db6681571$a307e780-996a-485f-af59-b44982dfceb4$154edd83-350d-4acf-adfb-6a2d20599b53$d2625507-4787-4b1c-9a91-108012e42cc7$ba8a5804-4be3-43fe-95d7-c957ce02a1d4$06297d75-121a-4178-b45b-83e167efd90d$e370dbb3-3bd9-4dc8-b8ca-8aad8711905c$cd928f87-2832-4595-8ce5-79b69cc56bd9$8bcaa31b-8caf-43da-83a0-47e0c04c2a30$1aaf3827-5851-4156-a7e6-14f5e4d00238$0dfd7afb-127c-4afd-8374-3c9a20a9ee76$3955d71a-3105-445a-868d-66ba0b3dc515$ff9276eb-2151-4a6f-8257-8348047a9f4e$2d36ebe3-1a86-4cad-a235-baec726da926$ba044e4f-e2a6-4f96-8756-5b24b1bb5ca2$6a96304b-add3-4135-8ccf-46cc23859d53$b352d98e-0854-45e3-ac73-8ef434525563$846ccb44-a18b-4d87-bbf8-fc59eaf87708$dfc2d648-ec08-49cd-a55f-72a766cad728$833bb53c-bc2b-47fb-9429-d0f6d92efb42$887de995-04e8-4d84-88d7-ad096a5747df$9524a3f5-fca3-4ce9-b04d-0cb6c0cd0c90$1067fcc4-cbc6-453c-a996-d420c498619a$e0d3d7d1-203f-42fa-8570-8d1d88bf17c2$8668ffc3-6c8c-4c25-8d47-9977bef929d2$da66b3be-1fe2-4edb-9560-71ce7c0bed12$7cdf4142-82fe-4aa6-9665-84a1eef5d038$1951fc4c-acc4-49a6-a907-7447ff0f430a$66645f1a-b591-43e7-b931-8ed0cc7d6898$11f8290f-f589-49ff-9602-99ccc4192884$14536b70-35f0-46ba-93fc-3365a1e8c15c$e89706f1-0c6a-4da4-82a1-ccf153f2e186$5834c5e0-8a04-47ea-aab8-881c73d8fd4f$989ccacd-b410-4967-bf6a-9244e3be785d$68f9e0d9-5c9d-4e89-b5ae-f24fd7544a09$605b045d-fe5c-426b-9f55-b7dd1d037c50$7ce6e28e-acd7-46d1-87d6-a25f4656d79d$3d10f89f-876e-4d25-b8d6-34ce5c99eb8c$0609ad22-0adc-4e4f-afed-b7a46d216576$2ed88aa5-fc42-4a57-924d-e918805e2208$059b1c0f-eb21-4a4a-8aed-64e9ac07b541$f41dd3e6-81bf-43e4-afc2-fc549b77f610$0d9c5d60-878a-45bb-8707-275cf10be41f$edb4ad06-5e6e-48c4-9ee4-ae0b92927a91$4481fa33-1ff3-4778-8486-d4d8a15775cd$aa647f3e-a4b2-4825-bb2a-1c2469d2c0eb$780f2fd9-49c3-48bc-b790-dde5be1dc81b$ffd1e39d-e66b-40a3-8ad1-c9480d371fe8$f79d97bb-341a-46ad-bdfc-d080af13e2df$6d6e8916-9b36-4af1-b77d-86cb6a416f88$acb270a1-e2b9-46bc-9a52-9f66f1cca17c$1d6eccf0-2731-47fc-9a41-ea8649e290ef$772b4dd6-870c-4a16-937c-701d5bb5da44$648bfc3f-0649-4401-a97f-89e21057f7b7$b7dfc031-6bf6-44cd-b814-05f693a0a27d$985f0537-2bbe-4dbb-a113-8ac98d2e0a5f$755be8f1-9d9e-4afd-8a70-07fab78e4333$1117e6c3-2736-46a4-bac2-d3c99c1998b6$cde7be85-9344-4526-bcb2-c2c8b3322435$e2fc1d47-2ee9-4844-a6b1-16f76531da86$8d7b9826-b52c-4d5a-8c63-e83a1229a0be$6f914006-1d8d-41f5-ae8a-fbe0b336946c$821ce23a-524b-4203-96d6-4d5b454fe1fd$1b02e593-d791-424c-b956-62cc480fcf40$859354fe-7f40-4658-bf12-b5ee20a815a7$88335fca-fd87-487b-9de2-ea7c779b54cf$abe70666-39f8-4f1d-a285-a3a99f696d10$dc57a71f-e44c-4385-ad2a-e6c14d5e5201$2e57e4b5-d228-4ce3-b9d8-cf4375bb7c50$4337b83f-b648-4b55-9d2a-4fffcf701111last_hot_reload_time        shortpath!Chapter_05_Monte_Carlo_Methods.jlprocess_statusreadypath٬/home/runner/work/Reinforcement-Learning-Sutton-Barto-Exercise-Solutions/Reinforcement-Learning-Sutton-Barto-Exercise-Solutions/Chapter-05/Chapter_05_Monte_Carlo_Methods.jlpluto_versionv0.20.8last_save_timeA"ycell_order $826139cc-b52e-11ec-0d47-25ab689851fd$a85e7dd3-ea5e-4c77-a18e-f1e190658ae3$72e9721f-ee17-4557-b090-71728e6c22ce$21d248f5-edad-4614-8c1c-ae330f9e5a18$b2115f33-f8e2-452e-9b0e-90610f0f09b1$202eb066-877d-4537-85b2-31b41db8eca0$d55860d1-e4c1-4a79-adbe-b40a6d6283a7$11723075-d1db-4512-abf2-3fe494a71a3b$760c5361-02d4-46b7-a05c-fc2d10d93de6$6a11daf7-2859-41fa-9c3d-d1f3580dbb5f$e87932d9-fbc0-4ea5-a8ee-28eac5eed84f$481ad435-cc80-4164-882d-8310b010ca91$7fb4244c-828a-49d6-a15b-178fa3a42e00$c23475f0-c5f0-49ce-a665-f93c8bda0474$6d765229-2816-4abb-a868-6be919a96530$a35de859-4046-4f6d-9ea9-b523d21cee5d$94be5289-bba7-4490-bdcd-0d217a31c665$01683e11-a368-45bc-abbc-bbd5c94d7b22$a68b4965-c392-47e5-9b29-93e7ada9990a$d766d44e-3684-497c-814e-8f71740cb232$82284c63-2306-4469-9b1a-a5ec87037e79$e5384dd0-fad1-4a24-b011-73b062fcfb1b$30809344-b4ab-468b-b4b7-5ef3dca5ffc7$f406be9e-3e3f-4b55-99b0-4858c774ed96$be7c096c-cc8c-407b-8287-8fb2ee7150a7$2572e35c-e6a3-4562-aa0f-6a5ab32d39ea$47daf83b-8fe9-4491-b9ae-84bd269d5546$2d10281a-a4af-4ea8-b63b-e11f2d0893ed$1d3d509c-b11b-4c57-b100-9bcf0489af2b$13cc524c-d983-44f4-8731-0595249fb888$1b78b25d-3942-4a6b-a2bd-7d97242da9fe$9618a093-cdb7-4589-a783-de8e9021b705$5c57e4b7-51d6-492d-9fc9-bcdab1dd46f4$06960937-a87a-4015-bdeb-5d17aa41fe6b$627d5aa3-974f-4949-8b65-9500eba1d7cc$ec29865f-3ba3-4bb3-84df-c2b472e03ff2$9fe42679-dce3-4ee3-b565-eed4ff7d8e4d$f9bc84ff-c2f9-4ac2-b2ce-34dfcf837a73$c883748c-76b9-4086-8698-b40df51390da$e2a720b0-a8c4-43a2-bf34-750ff3323004$abdcbbad-747a-41ba-a95d-82404e735793$334b4d77-8784-46be-b9e8-80c0a2244694$54f73eb8-dcea-4da0-83af-35720e56ccbc$bf19e6cf-1fb5-49c9-974e-1613d90ef4cf$3ee31af5-b19c-49dc-8fbf-f07e93d1f0c5$b040f245-b2d6-4ec6-aa7f-511c54aabd0d$12c0cd0b-eb4f-45a0-836b-53b3c5cdafd9$9793b5c9-d4ec-492d-a72d-8737bb65c8a5$15925cc6-9605-4357-9c2a-cdfe54070989$d97f693d-27f2-49be-a549-07a290c95b53$660ef59c-205c-44c2-9c46-5a74e09497ab$4197cc28-b24c-48cb-bd8d-ef998983ad77$aaa9647c-afb6-44d1-ae1e-a2e957064080$2646c9a2-46b1-4700-9290-ddc7dc9a59af$c8f3f7e3-be7e-4615-a667-d9f789928883$020131a1-c68b-403a-9c5e-944edb6220e9$1e6f7e5e-c5ce-479c-abbb-6c388c254626$d11bfcf9-b964-4c67-afdc-53d81f051fd5$cede8090-5b1a-436b-a184-fca5c4d3de48$c9bd778c-217a-4664-8cde-841beca10307$b39d1ea0-86a2-4215-ae73-e4492f3f2f00$02dd1e77-2a7e-4123-94db-d17b31a8b15a$04752549-ffca-4e31-869e-714f835d3e85$acb08e38-fc87-43f4-ac2d-6c6bf0f2e9e6$e293e184-5938-40b5-a04b-5306760a06ae$d16ac2a8-1a5a-4ded-9285-d2c6cd550066$70d9d39f-020d-4f25-810c-82a143a3335b$8faca500-b80d-4b50-88b6-683d18a1286b$892b5d8e-ac51-48f1-8288-65e9f68acd2d$43f9b824-fd56-4d56-84c3-23e2a3a37178$a59d9c84-d35f-4a9b-9fb6-13e30cdd7c3a$217ecc59-d6e3-48fa-9d6d-700a3947b805$19e42f50-5301-41b9-becb-2368c26b6236$5b32bbc7-dc34-4fc3-bacc-92e55f26a98c$b6eac49e-6742-4594-87a5-821437846b0d$847a074c-1d23-4de3-a039-322aeb9f7613$00cd2194-af13-415a-b725-bb34832e5d9a$9ca72278-fff6-4b0f-b72c-e0d3768aff73$e10378eb-12b3-4468-9c22-1838107da450$f071b7e2-3f78-4132-8b84-f810f178c89d$61eb74eb-88e0-42e6-a14b-3730a800694d$82a1f11e-b1b3-4c7d-ab9d-9f6136ae8195$5948f670-1203-4b75-8517-f8470f5d01aa$830d6d61-7259-43e7-8d6d-09bc81818dd9$881ba6c3-0e6a-4bb8-bc14-2e0face560f2$6979db32-670d-466a-9a6e-97c2d8527f3d$bf33230e-342b-4486-89ac-9667438de503$09b67730-39e7-4209-8117-6bc3adfb342a$fca388bd-eb8b-41e2-8da0-87b9386629c1$b57462b6-8f9c-4553-9c05-134ff043b00d$fa49c253-e016-46a7-ba94-0e7448a7e0ae$6496c993-6d47-4a6e-a497-2a2de172fbc3$61d8cfc6-a50c-4546-9e1f-dc73d4764bb9$e67d9deb-a074-48ba-84db-2e6938ea01f8$a47474b0-f262-4453-a116-addc3a09119e$2ed0d4bb-bb6e-4adf-ad7c-8ddeb8c20b84$35914757-6af1-4056-bba4-a9996f65f7f7$5e012ead-b4f9-45a9-979d-88b0b1086263$7c9486cd-1916-4e13-b415-fb113bd9e04b$924f4e74-e3a0-42eb-89da-1f9836275588$39da4cf9-5265-41bc-83d4-311e86675db7$0bd705cb-ad38-4cbb-b8fc-7e0617635282$418c045d-90c7-42d8-9126-90185f7e197b$ab10ccd7-75ba-475c-af26-f8b36daaf880$cebb79b7-c9d6-4b79-ba0e-b2f3c7587724$67e535c7-437a-49ba-b5ab-9dfe63fe4aaa$63814164-f305-49b3-ab51-675c822d7b18$1cc46e33-6885-4d6f-805e-9ff928f1cf23$f9f6c182-62f8-4a5a-8b43-8716db468427$f506e8ba-b073-4f59-91b4-3fe99822d2a4$bb617e58-2700-4f0d-b8c8-3a266142fb70$6dc0de46-2164-4580-b186-a73cb5b5167d$fd91d00a-f94f-40ff-88a7-9d85f05acc96$fff54c56-5afe-4d89-9dc5-502d08c89de9$658ceeaa-1b45-47bd-a364-eaa1759d17ac$df3c4a33-45f1-4cc2-8c06-d500a0eecc8f$f7616806-97ab-4b09-accc-4e047691f879$a0d61852-9942-42de-b554-572c4526a3a8$9df79a71-e58a-497b-bb02-debb69144925$e7de31e8-ae95-4616-86a9-a115a5e24330$5e2420fb-b2cc-49fc-91e3-3de80fba698b$d6e7cc6d-f397-4bdf-974e-9a16922393dd$8f38a3e9-1872-4ea6-9a03-87112af4bf07$a0eb6939-11bb-458d-bee3-9ed763819f62$7ee4e17e-c1a9-4df0-a014-114bebcb4f52$c8be6951-b6ec-4444-8c7f-ca5db6681571$a307e780-996a-485f-af59-b44982dfceb4$154edd83-350d-4acf-adfb-6a2d20599b53$d2625507-4787-4b1c-9a91-108012e42cc7$ba8a5804-4be3-43fe-95d7-c957ce02a1d4$06297d75-121a-4178-b45b-83e167efd90d$e370dbb3-3bd9-4dc8-b8ca-8aad8711905c$cd928f87-2832-4595-8ce5-79b69cc56bd9$8bcaa31b-8caf-43da-83a0-47e0c04c2a30$1aaf3827-5851-4156-a7e6-14f5e4d00238$0dfd7afb-127c-4afd-8374-3c9a20a9ee76$3955d71a-3105-445a-868d-66ba0b3dc515$ff9276eb-2151-4a6f-8257-8348047a9f4e$2d36ebe3-1a86-4cad-a235-baec726da926$ba044e4f-e2a6-4f96-8756-5b24b1bb5ca2$6a96304b-add3-4135-8ccf-46cc23859d53$b352d98e-0854-45e3-ac73-8ef434525563$dfc2d648-ec08-49cd-a55f-72a766cad728$846ccb44-a18b-4d87-bbf8-fc59eaf87708$833bb53c-bc2b-47fb-9429-d0f6d92efb42$887de995-04e8-4d84-88d7-ad096a5747df$9524a3f5-fca3-4ce9-b04d-0cb6c0cd0c90$1067fcc4-cbc6-453c-a996-d420c498619a$e0d3d7d1-203f-42fa-8570-8d1d88bf17c2$da66b3be-1fe2-4edb-9560-71ce7c0bed12$8668ffc3-6c8c-4c25-8d47-9977bef929d2$7cdf4142-82fe-4aa6-9665-84a1eef5d038$1951fc4c-acc4-49a6-a907-7447ff0f430a$66645f1a-b591-43e7-b931-8ed0cc7d6898$11f8290f-f589-49ff-9602-99ccc4192884$14536b70-35f0-46ba-93fc-3365a1e8c15c$e89706f1-0c6a-4da4-82a1-ccf153f2e186$5834c5e0-8a04-47ea-aab8-881c73d8fd4f$68f9e0d9-5c9d-4e89-b5ae-f24fd7544a09$989ccacd-b410-4967-bf6a-9244e3be785d$605b045d-fe5c-426b-9f55-b7dd1d037c50$7ce6e28e-acd7-46d1-87d6-a25f4656d79d$3d10f89f-876e-4d25-b8d6-34ce5c99eb8c$0609ad22-0adc-4e4f-afed-b7a46d216576$2ed88aa5-fc42-4a57-924d-e918805e2208$f41dd3e6-81bf-43e4-afc2-fc549b77f610$059b1c0f-eb21-4a4a-8aed-64e9ac07b541$0d9c5d60-878a-45bb-8707-275cf10be41f$edb4ad06-5e6e-48c4-9ee4-ae0b92927a91$4481fa33-1ff3-4778-8486-d4d8a15775cd$aa647f3e-a4b2-4825-bb2a-1c2469d2c0eb$780f2fd9-49c3-48bc-b790-dde5be1dc81b$ffd1e39d-e66b-40a3-8ad1-c9480d371fe8$f79d97bb-341a-46ad-bdfc-d080af13e2df$6d6e8916-9b36-4af1-b77d-86cb6a416f88$1d6eccf0-2731-47fc-9a41-ea8649e290ef$acb270a1-e2b9-46bc-9a52-9f66f1cca17c$772b4dd6-870c-4a16-937c-701d5bb5da44$648bfc3f-0649-4401-a97f-89e21057f7b7$b7dfc031-6bf6-44cd-b814-05f693a0a27d$985f0537-2bbe-4dbb-a113-8ac98d2e0a5f$755be8f1-9d9e-4afd-8a70-07fab78e4333$cde7be85-9344-4526-bcb2-c2c8b3322435$1117e6c3-2736-46a4-bac2-d3c99c1998b6$e2fc1d47-2ee9-4844-a6b1-16f76531da86$8d7b9826-b52c-4d5a-8c63-e83a1229a0be$6f914006-1d8d-41f5-ae8a-fbe0b336946c$821ce23a-524b-4203-96d6-4d5b454fe1fd$1b02e593-d791-424c-b956-62cc480fcf40$859354fe-7f40-4658-bf12-b5ee20a815a7$88335fca-fd87-487b-9de2-ea7c779b54cf$abe70666-39f8-4f1d-a285-a3a99f696d10$dc57a71f-e44c-4385-ad2a-e6c14d5e5201$2e57e4b5-d228-4ce3-b9d8-cf4375bb7c50$77cf7fee-0ad8-4d22-b376-75833307db93$4337b83f-b648-4b55-9d2a-4fffcf701111published_objects 5c6e0de0c-3901-11f0-234e-bd09c571f662/317eb0286b9488bclayoutautosize¥xaxistickvals  ?   AtitletextDealer showingticktextA10templatelayout coloraxiscolorbarticksoutlinewidth    xaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhitehovermodeclosestpaper_bgcolorwhitegeoshowlakesèshowlandélandcolor#E5ECF6bgcolorwhitesubunitcolorwhitelakecolorwhitecolorscalesequential    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921diverging    #8e0152=ͧ#c51b7d>Lͧ#de77ae>#f1b6da>ͧ#fde0ef?   #f7f7f7?#e6f5d0?333#b8e186?Lͧ#7fbc41?fff#4d9221?  #276419sequentialminus    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921yaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhiteshapedefaultslinecolor#2a3f5fhoverlabelalignleftmapboxstylelightpolarangularaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6radialaxisgridcolorwhitetickslinecolorwhiteautotypenumbersstrictfontcolor#2a3f5fternaryaaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6caxisgridcolorwhitetickslinecolorwhitebaxisgridcolorwhitetickslinecolorwhiteannotationdefaultsarrowhead    arrowwidth?  arrowcolor#2a3f5fplot_bgcolor#E5ECF6titlex=Lͥscenexaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitezaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhiteyaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitecolorway#636efa#EF553B#00cc96#ab63fa#FFA15A#19d3f3#FF6692#B6E880#FF97FF#FECB52data scatterpolargltypescatterpolarglmarkercolorbarticksoutlinewidth    carpetbaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitetypecarpetaaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitescatterpolartypescatterpolarmarkercolorbarticksoutlinewidth    parcoordslinecolorbarticksoutlinewidth    typeparcoordsscattertypescattermarkercolorbarticksoutlinewidth    histogram2dcontourcolorbarticksoutlinewidth    typehistogram2dcontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcolorbarticksoutlinewidth    typecontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattercarpettypescattercarpetmarkercolorbarticksoutlinewidth    mesh3dcolorbarticksoutlinewidth    typemesh3dsurfacecolorbarticksoutlinewidth    typesurfacecolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattermapboxtypescattermapboxmarkercolorbarticksoutlinewidth    scattergeotypescattergeomarkercolorbarticksoutlinewidth    histogramtypehistogrammarkercolorbarticksoutlinewidth    pietypepieautomarginêchoroplethcolorbarticksoutlinewidth    typechoroplethheatmapglcolorbarticksoutlinewidth    typeheatmapglcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921bartypebarerror_ycolor#2a3f5ferror_xcolor#2a3f5fmarkerlinecolor#E5ECF6width?   heatmapcolorbarticksoutlinewidth    typeheatmapcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcarpetcolorbarticksoutlinewidth    typecontourcarpettabletypetableheaderlinecolorwhitefillcolor#C8D4E3cellslinecolorwhitefillcolor#EBF0F8scatter3dlinecolorbarticksoutlinewidth    typescatter3dmarkercolorbarticksoutlinewidth    barpolartypebarpolarmarkerlinecolor#E5ECF6width?   scattergltypescatterglmarkercolorbarticksoutlinewidth    histogram2dcolorbarticksoutlinewidth    typehistogram2dcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scatterternarytypescatterternarymarkercolorbarticksoutlinewidth    heightC  marginl    b    r    tBp  titleyaxistickvals  @A  AtitletextPlayer sumticktext  @A  AwidthC  configshowLink¨editableªresponsiveêstaticPlotªscrollZoomæframesdatazmax?  y(  @A  PA  `A  pA  A  A  A  A  A  AtypeheatmapcolorscaleBlueredzminʿ  z(1緾þľrľ۾^Y󽸸>*?('=U\=i<<Egg c>U>B$?&v?(\=`=B#<G<;b<na>m>&?<@x?(߳>0==5l=/H=uP=ȷ$>H>(?=x?(8>$Z>8>=L==uS>>c$*?tw?(F7>Y9>F>>9=9=N>%?>y1?]x?(->>: >-=$zO=݄V6=f>_r?EG? wz?(v=oL<;3G)=_?I?hz?(\3>k򂽉Xǽ.+f>B?b{?(+ty*c)nI>aPEv3>6c?transposeéshowscaleáx(  ?   @  @@  @  @  @  @   A  A   A5c6e0de0c-3901-11f0-234e-bd09c571f662/298eb806dc8714d9layoutxaxistickvals(  ?   @  @@  @  @  @  @   A  A   AtitletextDealer showingticktextA@   @@  @  @  @  @  A   A  A   templatelayout coloraxiscolorbarticksoutlinewidth    xaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhitehovermodeclosestpaper_bgcolorwhitegeoshowlakesèshowlandélandcolor#E5ECF6bgcolorwhitesubunitcolorwhitelakecolorwhitecolorscalesequential    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921diverging    #8e0152=ͧ#c51b7d>Lͧ#de77ae>#f1b6da>ͧ#fde0ef?   #f7f7f7?#e6f5d0?333#b8e186?Lͧ#7fbc41?fff#4d9221?  #276419sequentialminus    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921yaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhiteshapedefaultslinecolor#2a3f5fhoverlabelalignleftmapboxstylelightpolarangularaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6radialaxisgridcolorwhitetickslinecolorwhiteautotypenumbersstrictfontcolor#2a3f5fternaryaaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6caxisgridcolorwhitetickslinecolorwhitebaxisgridcolorwhitetickslinecolorwhiteannotationdefaultsarrowhead    arrowwidth?  arrowcolor#2a3f5fplot_bgcolor#E5ECF6titlex=Lͥscenexaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitezaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhiteyaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitecolorway#636efa#EF553B#00cc96#ab63fa#FFA15A#19d3f3#FF6692#B6E880#FF97FF#FECB52data scatterpolargltypescatterpolarglmarkercolorbarticksoutlinewidth    carpetbaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitetypecarpetaaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitescatterpolartypescatterpolarmarkercolorbarticksoutlinewidth    parcoordslinecolorbarticksoutlinewidth    typeparcoordsscattertypescattermarkercolorbarticksoutlinewidth    histogram2dcontourcolorbarticksoutlinewidth    typehistogram2dcontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcolorbarticksoutlinewidth    typecontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattercarpettypescattercarpetmarkercolorbarticksoutlinewidth    mesh3dcolorbarticksoutlinewidth    typemesh3dsurfacecolorbarticksoutlinewidth    typesurfacecolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattermapboxtypescattermapboxmarkercolorbarticksoutlinewidth    scattergeotypescattergeomarkercolorbarticksoutlinewidth    histogramtypehistogrammarkercolorbarticksoutlinewidth    pietypepieautomarginêchoroplethcolorbarticksoutlinewidth    typechoroplethheatmapglcolorbarticksoutlinewidth    typeheatmapglcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921bartypebarerror_ycolor#2a3f5ferror_xcolor#2a3f5fmarkerlinecolor#E5ECF6width?   heatmapcolorbarticksoutlinewidth    typeheatmapcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcarpetcolorbarticksoutlinewidth    typecontourcarpettabletypetableheaderlinecolorwhitefillcolor#C8D4E3cellslinecolorwhitefillcolor#EBF0F8scatter3dlinecolorbarticksoutlinewidth    typescatter3dmarkercolorbarticksoutlinewidth    barpolartypebarpolarmarkerlinecolor#E5ECF6width?   scattergltypescatterglmarkercolorbarticksoutlinewidth    histogram2dcolorbarticksoutlinewidth    typehistogram2dcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scatterternarytypescatterternarymarkercolorbarticksoutlinewidth    heightC  marginl    b    rA   tA  yaxistickvals(  @A  PA  `A  pA  A  A  A  A  A  AtitletextPlayer sumticktext(  @A  PA  `A  pA  A  A  A  A  A  AwidthC  configshowLink¨editableªresponsiveêstaticPlotªscrollZoomæframesdatazmax?  y(  @A  PA  `A  pA  A  A  A  A  A  AtypeheatmapcolorscaleGreyszminʿ  z(  ?  ?  ?  ?  ?          (  ?                  (  ?                  (                    (  ?                  (                    (  ?  ?  ?  ?  ?          (  ?  ?  ?  ?  ?          (  ?  ?  ?  ?            (  ?  ?  ?  ?            transposeéshowscale¡x(  ?   @  @@  @  @  @  @   A  A   A5c6e0de0c-3901-11f0-234e-bd09c571f662/c2f9f46c95453d02layoutautosize¥xaxistickvals  ?   AtitletextticktextA10templatelayout coloraxiscolorbarticksoutlinewidth    xaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhitehovermodeclosestpaper_bgcolorwhitegeoshowlakesèshowlandélandcolor#E5ECF6bgcolorwhitesubunitcolorwhitelakecolorwhitecolorscalesequential    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921diverging    #8e0152=ͧ#c51b7d>Lͧ#de77ae>#f1b6da>ͧ#fde0ef?   #f7f7f7?#e6f5d0?333#b8e186?Lͧ#7fbc41?fff#4d9221?  #276419sequentialminus    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921yaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhiteshapedefaultslinecolor#2a3f5fhoverlabelalignleftmapboxstylelightpolarangularaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6radialaxisgridcolorwhitetickslinecolorwhiteautotypenumbersstrictfontcolor#2a3f5fternaryaaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6caxisgridcolorwhitetickslinecolorwhitebaxisgridcolorwhitetickslinecolorwhiteannotationdefaultsarrowhead    arrowwidth?  arrowcolor#2a3f5fplot_bgcolor#E5ECF6titlex=Lͥscenexaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitezaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhiteyaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitecolorway#636efa#EF553B#00cc96#ab63fa#FFA15A#19d3f3#FF6692#B6E880#FF97FF#FECB52data scatterpolargltypescatterpolarglmarkercolorbarticksoutlinewidth    carpetbaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitetypecarpetaaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitescatterpolartypescatterpolarmarkercolorbarticksoutlinewidth    parcoordslinecolorbarticksoutlinewidth    typeparcoordsscattertypescattermarkercolorbarticksoutlinewidth    histogram2dcontourcolorbarticksoutlinewidth    typehistogram2dcontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcolorbarticksoutlinewidth    typecontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattercarpettypescattercarpetmarkercolorbarticksoutlinewidth    mesh3dcolorbarticksoutlinewidth    typemesh3dsurfacecolorbarticksoutlinewidth    typesurfacecolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattermapboxtypescattermapboxmarkercolorbarticksoutlinewidth    scattergeotypescattergeomarkercolorbarticksoutlinewidth    histogramtypehistogrammarkercolorbarticksoutlinewidth    pietypepieautomarginêchoroplethcolorbarticksoutlinewidth    typechoroplethheatmapglcolorbarticksoutlinewidth    typeheatmapglcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921bartypebarerror_ycolor#2a3f5ferror_xcolor#2a3f5fmarkerlinecolor#E5ECF6width?   heatmapcolorbarticksoutlinewidth    typeheatmapcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcarpetcolorbarticksoutlinewidth    typecontourcarpettabletypetableheaderlinecolorwhitefillcolor#C8D4E3cellslinecolorwhitefillcolor#EBF0F8scatter3dlinecolorbarticksoutlinewidth    typescatter3dmarkercolorbarticksoutlinewidth    barpolartypebarpolarmarkerlinecolor#E5ECF6width?   scattergltypescatterglmarkercolorbarticksoutlinewidth    histogram2dcolorbarticksoutlinewidth    typehistogram2dcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scatterternarytypescatterternarymarkercolorbarticksoutlinewidth    heightC  marginl    b    r    tBp  titleAfter 10,000 episodesyaxistickvals  @A  Atitletextticktext  @A  AwidthC  configshowLink¨editableªresponsiveêstaticPlotªscrollZoomæframesdatazmax?  y(  @A  PA  `A  pA  A  A  A  A  A  AtypeheatmapcolorscaleBlueredzminʿ  z($IҾz $o0_6=8?(&VXޗǾZվ.--˲!ҾrþR ?#,w?(-ؾRY;㽼Sԛi/!?z?(    @&R׾Lb*ɾ7)?_z?(ܾ.6MӾtdO袋.PD?a,y?(mgf      1ƾȾף0?t?(	c ̌Qf?}}?(?ྉzӛgf#Ҿp=J?~t?(;1$᤾ȍC2?#,w?(ף ݗǾ0>xؾQ>N?transposeéshowscale¡x(  ?   @  @@  @  @  @  @   A  A   A5c6e0de0c-3901-11f0-234e-bd09c571f662/49c525f145d8c899layoutxaxistypelogtitletextSteps to Finish Racetemplatelayout coloraxiscolorbarticksoutlinewidth    xaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhitehovermodeclosestpaper_bgcolorwhitegeoshowlakesèshowlandélandcolor#E5ECF6bgcolorwhitesubunitcolorwhitelakecolorwhitecolorscalesequential    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921diverging    #8e0152=ͧ#c51b7d>Lͧ#de77ae>#f1b6da>ͧ#fde0ef?   #f7f7f7?#e6f5d0?333#b8e186?Lͧ#7fbc41?fff#4d9221?  #276419sequentialminus    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921yaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhiteshapedefaultslinecolor#2a3f5fhoverlabelalignleftmapboxstylelightpolarangularaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6radialaxisgridcolorwhitetickslinecolorwhiteautotypenumbersstrictfontcolor#2a3f5fternaryaaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6caxisgridcolorwhitetickslinecolorwhitebaxisgridcolorwhitetickslinecolorwhiteannotationdefaultsarrowhead    arrowwidth?  arrowcolor#2a3f5fplot_bgcolor#E5ECF6titlex=Lͥscenexaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitezaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhiteyaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitecolorway#636efa#EF553B#00cc96#ab63fa#FFA15A#19d3f3#FF6692#B6E880#FF97FF#FECB52data scatterpolargltypescatterpolarglmarkercolorbarticksoutlinewidth    carpetbaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitetypecarpetaaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitescatterpolartypescatterpolarmarkercolorbarticksoutlinewidth    parcoordslinecolorbarticksoutlinewidth    typeparcoordsscattertypescattermarkercolorbarticksoutlinewidth    histogram2dcontourcolorbarticksoutlinewidth    typehistogram2dcontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcolorbarticksoutlinewidth    typecontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattercarpettypescattercarpetmarkercolorbarticksoutlinewidth    mesh3dcolorbarticksoutlinewidth    typemesh3dsurfacecolorbarticksoutlinewidth    typesurfacecolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattermapboxtypescattermapboxmarkercolorbarticksoutlinewidth    scattergeotypescattergeomarkercolorbarticksoutlinewidth    histogramtypehistogrammarkercolorbarticksoutlinewidth    pietypepieautomarginêchoroplethcolorbarticksoutlinewidth    typechoroplethheatmapglcolorbarticksoutlinewidth    typeheatmapglcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921bartypebarerror_ycolor#2a3f5ferror_xcolor#2a3f5fmarkerlinecolor#E5ECF6width?   heatmapcolorbarticksoutlinewidth    typeheatmapcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcarpetcolorbarticksoutlinewidth    typecontourcarpettabletypetableheaderlinecolorwhitefillcolor#C8D4E3cellslinecolorwhitefillcolor#EBF0F8scatter3dlinecolorbarticksoutlinewidth    typescatter3dmarkercolorbarticksoutlinewidth    barpolartypebarpolarmarkerlinecolor#E5ECF6width?   scattergltypescatterglmarkercolorbarticksoutlinewidth    histogram2dcolorbarticksoutlinewidth    typehistogram2dcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scatterternarytypescatterternarymarkercolorbarticksoutlinewidth    marginlBH  bBH  rBH  tBp  yaxistitletextPercent of EpisodesconfigshowLink¨editableªresponsiveêstaticPlotªscrollZoomæframesdatayYh:Yh
;Yh;Yh;o;6;6;Yh
<o-<o-<zO><O<`<6r<<Yh<d<d<[<o<zO<zO<<<C<<<6<!<=Yh
=Yh
===!b=d= =,(=,(=o-=U1=5=B=B=B=F=BIK=O=S=CX=`=`=<e=i=Xm=6r=މv=!z=c0==u==>=Yh======8=!b==d=ߝ==H2=[==,=ت=o=,=U===ҷ=7=%=zO=y==^===BI=r====i=l=l=M===1=<=tf===X==6==`=މ==!=c0=c0= >>>u>E >>)>>>S	>Yh
>)}>>˦>>=>=>>>#>8>PM>!b>v>>>d>>>> >w!>G#>G#>[$>&>&>['>,(>)>*>+>o->@.>,/>U1>U1>j2>$4>$4>5>Ž6>7>f8>79>;>%<>:=>zO>>Kd?>y@>A>B>^D>^D>/E>F>
H>r4J>r4J>^L>^L>rM>N>O>&Q>&Q>R>S>U>iV>:.W>CX>WY>lZ>}[>M\>]>^>`>`>aa>1c>(d><e>Qf>tfg>E{h>i>l>l>l>Xm>)n>p>!q>lKs>lKs>=`t>މv>މv>w>Py>Py>!z>{>}>~>c0>>>k7>>;L>ւ>a>u>u>>>>~>)>O>>> Ɉ>S>݉>Yh>)}>)}>>>b>˦>31>>F>lЏ>Z>=>o>v>v>>G>#>>8>PM>PM>ז>!b>>v>Z>>+>>*>d>?>4ʜ>ߝ>ߝ>mi>>>~>>>w>ৡ>H2>>G>ѣ>[>R>p>">>>[>$>,>9>é>eN>ت>6c>>x>o>׌>@>>,>y>@>I˰>U>>j>>	>	>$>>>]3>Ž>-H>ҷ>\>f>q>7>>>p>%>A>:>Ž>zO>پ>Kd>>y>>>T>>%->A>A>^>/>/>k>>h>
>8>>	>r4>ھ>BI>>^>{>r>L>>>>&>V>;>&>P>>_e>>0z>>>i>ң>:.>>C>s>W>D>l>>}>>M>>>5>>WJ>>>>s>a>Ɉ>1>>(>k><>;>Q>>tf>>E{>>>~>O/>O/>>D>>X>X>m>)>>>b>!>3>6>>lK>>=`>u>u>v>މ>F>>)>>P>P>R>!>g>>Z|>>*>>>̺>̺>" ? ? ?7 ?k7?|???p?p???a?@?u?0?u??yE?yE????JZ?~??)?o?O??>?? ?T	?S	?	?	?$#
?Yh
?
?
?7?)}?^??L??.?b?a?˦??31?gv?? ?F?8?l??Z?	?=?q*?o?ٴ??B??v???T?G?{?#?h??K?8?}???PM????!b?U??1?v?&?Z?F???+?_[??*?*?0p?d????? ?4?i?T?љ??9$?mi???
9?>~?r? ?M ? ?C ?w!?b!?!?H2"?H2"?|w"?"?#?M#?M#?#?$?[$?$?R$?+%?p%?%?"%?W@&?&?'?'?'U'?['?'?$(?i(?,(?`(?9)?~)?)?1	*?eN*?*?*?+?6c+?j+?+?2,?x,?;,?o-?G-?׌-?-?@.?t\.?.?.?,/?Dq/?y/?/?@0?0?I0?}1?U1?1?1?N%2?j2?2?2?:3?S3?3?	4?$4?$4?X4?c5?c5?5?)5?]36?x6?Ž6?7?-H7?b7?7?8?\8?28?f8?,9?q9?9?79?kA:?:?:?;?<V;?p;?;?%<?k<?A<?u<?:=?=?=?zO>?zO>?>?>???Kd??????3@?y@?O@?A?HA?A? A?TB?]B?B?B?%-C?YrC?C?AD?AD?*D?^D?VE?VE?E?/E?c&F?kF?˰F?F?4;G?hG?G?
H?PH?8H?mH?I?dI?	I?=I?r4J?yJ?ھJ?K?BIK?vK?K?L?^L?GL?{L?-M?rM?M?LM?BN?N?N?O?QWO?O?O?&P?"lP?VP?P?;Q?Q?&Q?[R?PR?ÕR?R?_eS?_eS?S?S?4T?0zT?dT?U?IU?U?5U?iV?^V?ңV?V?:.W?nsW?W?W?CX??X?sX?Y?WY?Y?DY?x'Z?lZ?Z?Z?H<[?}[?[?\?Q\?M\?\? ]?]?]?R]?5^?z^?^?#_?WJ_?_?_?`?(_`?\`?`?.a?sa?-a?aa?Cb?Ɉb?b?1c?fXc?c?c?(d?6md?kd?d?<e?e?;e?of?Qf?ؖf?f?@!g?tfg?g?g?6h?E{h?yh?i?Ji?i?Ji?~j?_j?j?j?O/k?tk?k?k?Dl?Tl?l?m?Xm?$m?Xm?(n?mn?n?)n?]=o?o?o?p?.Rp?bp?p?!q?fq?3q?gq?6r?{r?r?8s?lKs?s?s?t?=`t?qt?t?/u?uu?Au?vu?Dv?މv?v?Fw?zYw?w?w?)x?Knx?x?x?=y?y?Py?z?Rz?z?!z?U"{?g{?{?{?&7|?Z||?|?}?K}?*}?_}?~?`~?~?/~?c0?u?̺?  ?typescatternameOff policy MC Controlx  `A  pA  A  A  A  A  A  A  B  B  $B  <B  HB  TB  lB  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B   C  C  
C  C  C  C  C  C  C  C  C  C  C   C  &C  'C  /C  1C  1C  6C  7C  8C  9C  :C  DC  GC  JC  NC  aC  iC  mC  qC  tC  uC C C C C  C C  C C  C  C  C  C C  C  C  C  C C  C C C C C  C  C  C  C  C  C  C  C C  C  C C  C  C C C C C C C  C C C  C  C  C  C  C C C  C C C  C  C  C C C  C C  C  C  D  D @D D @D D D D  D 	D @
D  D @D @D @D D D  D  D D D D @D @D D  D @D D @D D D D D  D  D !D "D 'D (D )D @,D @.D .D @/D /D @0D 0D 3D 3D 3D 4D 5D 8D 9D 9D @:D @:D :D  <D @=D @?D @?D ?D @D @D BD BD  CD @ED ED  FD FD @GD  JD  LD  LD @LD MD  OD PD  RD  SD SD  TD UD UD UD XD XD YD  ZD ]D ]D @_D _D _D  `D `D `D `D aD aD @dD dD  eD  eD @gD  iD iD  jD jD kD  lD oD oD  pD pD  tD tD @vD @yD  zD  {D }D D D D `D D  D  D D D D @D `D D D D D D @D D @D D D D D D @D `D D D @D D D D D  D  D @D D @D @D `D D D @D D  D  D `D D  D D D  D D D  D `D D D  D  D @D @D  D D D D D  D `D D  D D `D D D D  D @D D  D D `D D D D  D D D @D D  D D  D  D D  D  D  D `D D @D  D `D  D D D D D D D  D  D D D D  D `D D  D `D D D  D D  D D D  D D  D  D D `D  D  D D D @D D  D D  D  D `D `D D D @D D D D `D `D `D  D @D D D D  D  D D D `D D D  D @D  D @D D D  D @D D @D `D `D `D `D D D  D @D  D D p E  E  E  E  E PE PE E E 0E 0E E  E E E  E `E E E E E E  E 0E 0
E @
E `
E 
E 
E 
E @E E E E E E `E E E E E  E E pE E @E 0E `E pE pE E pE pE E E 0E `E E E E E PE pE E E @E PE E E E E E E 0E pE E E  E E  E pE E E @E E E E  E  !E @!E !E !E 0"E `"E "E #E p$E  %E  &E `&E p&E &E &E  'E @'E 'E 'E (E )E @)E )E  *E @*E P*E +E +E +E 0,E `,E 0-E  .E `.E .E 0/E 0E @0E 0E 0E 0E  1E  1E 1E 1E 2E 2E @3E p3E 3E 5E  5E P5E 5E 6E  7E `7E 9E @:E p:E :E :E @;E P;E `;E ;E ;E ;E ;E ;E  =E 0=E =E =E >E >E @?E `?E p?E ?E `AE pAE AE CE  DE DE DE DE DE `EE  GE GE GE  HE PHE `HE HE `IE PJE JE KE  KE 0KE PKE `KE  ME `ME ME NE @OE POE OE OE QE QE QE `SE SE SE TE UE VE WE WE WE YE @[E [E [E P\E p\E \E ]E  ]E @^E ^E ^E ^E  _E  _E  `E @`E  aE 0aE PaE aE aE aE bE pcE cE dE dE eE fE  gE @gE @hE hE @iE jE jE jE 0kE kE kE @lE lE nE nE 0pE pE pE `qE qE sE tE  uE  vE pvE PwE `zE @{E @|E @}E ~E @~E 0E pE E E E HE E E E E E E @E PE E E 8E E 8E E E E E HE `E hE E ؄E E E E (E PE E ȇE E E 0E HE E  E E E ؋E E @E E (E ȎE hE E E E E ȐE @E HE E E ؑE E E E E E xE E 0E  E XE E E E E E E HE PE xE E ȚE E МE E PE E E  E hE ȟE E PE E xE E  E XE E PE E E E 0E E ФE E (E E E E E E E E E @E 8E xE E HE hE E E XE ȰE E E hE ȱE E 8E E @E E hE ȷE E 8E XE E 8E E E (E 0E hE pE E E 0E HE E @E HE E E E E E 0E @E E E pE E @E E `E E (E XE 0E E (E pE E pE E E XE E xE  E @E E E (E E 8E 8E E E hE E E E E XE E @E hE E XE E hE pE E E HE hF F F HF F F PF 
F dF F F F F F F XF dF F F FyDZ(:<I;<I;Z(;q;;;Z(<e<q'<|w8<<I<Z<j<{<Z(<<e<O<q<|w<|w<<<<<<<d<<#)<<=Z(=Y
==#=e=O=O=.#=q'=+=0=9F4=|w8=<=@=DE=<I=mM=PU=PU=Z=db=db=[f=j=#)s=#)s=fZw={===Z(=Z(=@=>r=>r===#=Ԕ=e=J7=J7=J7=O=h=.=ϙ=q=˩==U==-=9F=^=|w===`===D=#=<=)U=m=k======4=2=wK=|=|=[==?=?===A=A=fZ=s==J== >>h>Z(>Z(>Z(>4>@>LM	>Y
>e>>r>~>0>0>>ү>#>s>>>e>>>X>*>*>J7>C><\ ><\ >t">t">.#>$>ϙ%> &>q'>(>)>+>+>U->U->/>0>G!1>-2>93>9F4>R5>^6>+k7>|w8>̓9><><><>=>`>>?>@>RA>B>C>F>F>#G>70H><I>HJ>)UK>yaL>zN>zN>kO>P>Q>^R>S>T>PU>V>W>BX>Z>[>&]>&]>2^>&?_>wK`>Wa>db>ipc>|d>
e>[f>g>h>j>j>k>?l>1p>1p>1p>q>r>#)s>t5t>Au>Nv>fZw>fx>sy>Xz>{>|>J}>>>d>>p>>@}>h>>>ᕄ>2>2>Z(>Ӻ>Ӻ>Ӻ>$ǈ>$ǈ>LM>uӉ>Y>ߊ>e>>>r>g>~>>>>0>Y>)>)>ү>5>KB>KB>sȓ>N>Z>Z>>=g>e>s>>>>/>X>>>Ѥ>*>!>J7>r>C>ɞ>O>֟><\>d>h>>t>>.>V>>>ϙ>>H,>H,>q>8>>D>˩>:Q>cת>>>i>>}>}>}>>Ύ>>>G!>o>>>9>>9F>a̴>R>^>^>>+k>T>|w>>̓>>>F>n>">>.>>8;>`>G>Ϳ>S>>*`>R>{l>>>>>D>m>>>>><><><>>H> >)U>Q>ya>>m>>z>C >k>>>>>5%>^>1>>=>>'J>xV>xV>>>>o>B>j{>>>>>4>\>&>2>2>>&?>N>wK>>W>>@>@>ip>|>|>>
>3>[>>>'>>%4>M>u@>>L>>Y>?>he>>q>>	~>1>Z>>>>>#)>L>t5>>A>>N>>>fZ>>f>>s>0>X>>>>>">J>s*>>6>>! ?d ? ? ?-?p??+:?+:?@}?T?h?????R???	?_?2?Z(?Z(?nk???4?w?Ӻ??@?$?$?8
	?LM	?`	?u	?
?Y
?
?
?e?e??*/?*/?S?S?g?{;?~???G????T?0?E?Y?m`???)?l?ү??5?y?#?7?KB?_???N????Z???)$?=g?Q?z0?z0????<????I?/?C?X?lU????a?Ѥ??*?n?!?5?J7?r?r? ?C????O???( ?<\ ?P ?d ?x%!?!?!?!?1"?t"?"?"?>#?.#?B#?V$?jJ$?$?$?%?V%?ϙ%?%?&?c&? &?4&?H,'?\o'?q'?'?8(?{(?(?)?D)?)?)?&*?:Q*?O*?c*?w+?]+?+?+?&,?i,?,?,?3-?-v-?A-?U-?i?.?}.?.?K/?K/?Ύ/?0?0?
X0?0?30?G!1?[d1?o1?1?-2?p2?2?2?93?|3?3?%4?9F4?M4?a4?v5?R5?5?5?6?^6?6?6?(7?+k7??7?T7?h48?|w8?8?8?@9?̓9?9?	:?	M:?:?2:?F;?ZY;?n;?;?"<?e<?<?<?.=?q=?=?$=?8;>?L~>?`>?t??G??????@?S@?@?@?A?*`A?>A?RA?f)B?{lB?B?B?5C?C?C?C?BD?D?0D?DE?YNE?mE?E?F?ZF?F?F?fG?fG?G?"G?70H?KsH?_H?sH?<I?I?I?J?HJ?J? J?K?)UK?=K?QK?eL?yaL?L?L?*M?mM?ްM?M?7N?zN?/N?C O?WCO?kO?O?P?OP?P?P?Q?[Q?Q?!Q?5%R?IhR?^R?rR?1S?tS?S?S?=T?T?T?U?'JU?;U?PU?dV?xVV?V?V?W?bW?ݥW?W?,X?oX?.X?BX?V8Y?j{Y?~Y?Z?Z?Z?Z?[?P[?[? [?4\?H]\?\\?p\?&]?i]?]?]?2^?u^?^?^?&?_?:_?N_?c`?wK`?`?`?a?Wa?ܚa?a?!b?db?,b?@b?U-c?ipc?}c?c?9d?|d?οd?e?Ee?
e?e?3f?GRf?[f?of?g?^g?g?g?'h?jh?h?h?%4i?9wi?Mi?ai?u@j?j?j?	k?Lk?ڏk?k?l?Yl?+l??l?S"m?hem?|m?m?.n?qn?̴n?n?:o?	~o?o?1p?EGp?Zp?np?q?Sq?q?q?r?_r?r?r?#)s?8ls?Ls?`s?t5t?xt?t?t?Au?لu?u?v?Nv?*v?>v?Rw?fZw?zw?w?#x?fx?˩x?x?/y?sy?y?0y?D<z?Xz?lz?{?H{?{?{?|?T|?|?|?"}?6a}?J}?_}?s*~?m~?~?~?6?y??  ?typescatternameRandom PolicyxD  A  A  A  A  A  A  A  A  B  B  $B  (B  0B  PB  lB  xB  |B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B   C  C  C  C  C  C  C  "C  $C  *C  3C  3C  5C  6C  6C  8C  ;C  ?C  ?C  CC  GC  IC  JC  MC  MC  QC  WC  WC  ]C  hC  jC  lC  mC  pC  pC  pC  rC  sC  vC  xC  yC  }C  C  C C  C C  C C C C  C  C  C C C  C C  C  C  C  C  C  C C C C C  C  C C  C C C C C C C C C C C C  C C C  C  C  C C  C  C C  C  C  C  C  C C  C  C C  C  C C C  C C  C  C  C  C C C  C  C  C C C C  C C  C C C  C  C C  C  C C  C C  C C  D  D D  D  D  D D D D  	D @	D D D D D @D D D D D  D D D  D D  D @D D D @D  D D @D @D D D D D @D D D D D   D @ D  D  D  "D "D "D @$D $D $D $D $D %D %D  &D @&D @)D  +D @+D ,D -D @.D  0D  1D @1D  2D  2D @7D 7D 8D  9D  :D  =D =D ?D AD CD CD @DD DD DD DD  ED  ED @FD HD HD @ID ID  KD @KD KD @LD LD  MD MD ND OD  SD  SD SD SD  TD  TD TD  UD @UD @UD @WD  XD  ZD @ZD  ]D ]D ^D  _D @_D _D @`D `D  aD @bD cD eD fD @gD hD iD kD @lD lD @mD @pD pD rD sD  tD  tD  vD vD vD vD zD  |D |D |D  }D  ~D  D @D @D  D  D  D  D  D D D D  D @D  D @D @D `D @D D D @D D D D  D D  D D D D D  D @D D  D @D D D @D D  D D D  D  D D  D D D  D `D  D @D D  D  D  D  D  D D D  D D `D D D  D D `D D D @D D `D  D D  D D  D D D D D D D D D  D D  D D D `D D  D D D D D `D `D D  D `D D @D `D `D D D D `D D  D @D `D D  D  D D D  D D D D D  D D  D @D D  D @D D D D D D  D D D @D `D D D  D @D `D  D D D D  D D D D D  D D  D @D `D D  D D D D D `D `D D D D  D D  D  D  D D  D D  D @D D  D D D D @D @D `D  D  D D D  D  D D `D D D  D  D  E E E E  E E E E E pE E E PE E E E E  	E @	E 	E 	E 	E 
E E `E  E @E E @E E E E E PE E E E 0E E E E  E  E @E E pE E E E E E E PE @E E E E  E E PE `E E E E PE E E E E @E `E E E E E `E E   E   E 0 E  E  E @!E `!E !E `"E "E #E #E #E $E $E $E  %E %E &E p'E 'E 'E p(E p(E `)E )E )E )E )E  *E  *E *E *E *E  +E P+E +E ,E 0,E ,E -E -E -E .E .E .E 0/E P/E /E /E 0E p1E 1E `2E @3E  4E 4E 05E @5E 5E  6E @7E 8E 8E 9E 9E 9E P:E p:E  ;E p;E <E  >E  ?E P?E ?E PAE AE AE @CE PCE FE 0GE `GE GE GE @HE HE HE pIE IE JE PKE `KE KE KE @LE LE LE ME ME PNE pNE NE OE OE PQE QE QE @RE RE SE SE  TE 0TE @TE TE TE UE UE VE WE pWE 0XE PXE YE ZE 0ZE ZE [E 0\E \E @]E ]E ]E ^E ``E `E  aE  aE aE aE aE  cE dE dE dE eE eE eE eE fE hE  jE kE kE kE kE mE mE `nE  oE @oE pE pE pE qE qE rE  sE sE uE  vE @vE @wE wE  yE {E }E ~E pE E hE pE ЀE E HE (E PE pE E E E 8E E E E  E E @E XE E ЈE `E E E xE E (E PE xE E 8E E @E HE hE E ȏE E HE E E (E XE E  E PE PE pE xE E E E ЖE E E E 8E E E E E  E 8E E  E HE XE E E E E  E XE E ؠE E  E HE hE E HE HE XE E E  E 0E hE pE E 0E HE `E E E E E 8E HE  E PE E PE `E E E (E кE  E XE E hE E (E 8E E E E E (E E E E E E E 0E E E xE E  E E E PE E E HE  E E E E PE E 8E E @E E E E E xE E xE E E E E E (E E E P F |F F F F ,F HF F F F xF F F 8	F 
F 
F 
F 
F 
F DF F F XF F \F F ,F F5c6e0de0c-3901-11f0-234e-bd09c571f662/4632010f9ca3f26elayoutxaxistickvals(  ?   @  @@  @  @  @  @   A  A   AtitletextDealer showingticktextA@   @@  @  @  @  @  A   A  A   templatelayout coloraxiscolorbarticksoutlinewidth    xaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhitehovermodeclosestpaper_bgcolorwhitegeoshowlakesèshowlandélandcolor#E5ECF6bgcolorwhitesubunitcolorwhitelakecolorwhitecolorscalesequential    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921diverging    #8e0152=ͧ#c51b7d>Lͧ#de77ae>#f1b6da>ͧ#fde0ef?   #f7f7f7?#e6f5d0?333#b8e186?Lͧ#7fbc41?fff#4d9221?  #276419sequentialminus    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921yaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhiteshapedefaultslinecolor#2a3f5fhoverlabelalignleftmapboxstylelightpolarangularaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6radialaxisgridcolorwhitetickslinecolorwhiteautotypenumbersstrictfontcolor#2a3f5fternaryaaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6caxisgridcolorwhitetickslinecolorwhitebaxisgridcolorwhitetickslinecolorwhiteannotationdefaultsarrowhead    arrowwidth?  arrowcolor#2a3f5fplot_bgcolor#E5ECF6titlex=Lͥscenexaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitezaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhiteyaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitecolorway#636efa#EF553B#00cc96#ab63fa#FFA15A#19d3f3#FF6692#B6E880#FF97FF#FECB52data scatterpolargltypescatterpolarglmarkercolorbarticksoutlinewidth    carpetbaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitetypecarpetaaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitescatterpolartypescatterpolarmarkercolorbarticksoutlinewidth    parcoordslinecolorbarticksoutlinewidth    typeparcoordsscattertypescattermarkercolorbarticksoutlinewidth    histogram2dcontourcolorbarticksoutlinewidth    typehistogram2dcontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcolorbarticksoutlinewidth    typecontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattercarpettypescattercarpetmarkercolorbarticksoutlinewidth    mesh3dcolorbarticksoutlinewidth    typemesh3dsurfacecolorbarticksoutlinewidth    typesurfacecolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattermapboxtypescattermapboxmarkercolorbarticksoutlinewidth    scattergeotypescattergeomarkercolorbarticksoutlinewidth    histogramtypehistogrammarkercolorbarticksoutlinewidth    pietypepieautomarginêchoroplethcolorbarticksoutlinewidth    typechoroplethheatmapglcolorbarticksoutlinewidth    typeheatmapglcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921bartypebarerror_ycolor#2a3f5ferror_xcolor#2a3f5fmarkerlinecolor#E5ECF6width?   heatmapcolorbarticksoutlinewidth    typeheatmapcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcarpetcolorbarticksoutlinewidth    typecontourcarpettabletypetableheaderlinecolorwhitefillcolor#C8D4E3cellslinecolorwhitefillcolor#EBF0F8scatter3dlinecolorbarticksoutlinewidth    typescatter3dmarkercolorbarticksoutlinewidth    barpolartypebarpolarmarkerlinecolor#E5ECF6width?   scattergltypescatterglmarkercolorbarticksoutlinewidth    histogram2dcolorbarticksoutlinewidth    typehistogram2dcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scatterternarytypescatterternarymarkercolorbarticksoutlinewidth    heightC  marginl    b    rA   tA  yaxistickvals(  @A  PA  `A  pA  A  A  A  A  A  AtitletextPlayer sumticktext(  @A  PA  `A  pA  A  A  A  A  A  AwidthC  configshowLink¨editableªresponsiveêstaticPlotªscrollZoomæframesdatazmax?  y(  @A  PA  `A  pA  A  A  A  A  A  AtypeheatmapcolorscaleGreyszminʿ  z(fff?fff?fff?fff?fff?fffffffffffffff(fff?fffffffffffffffffffffffffff(ffffffffffffffffffffffffffffff(ffffffffffffffffffffffffffffff(ffffffffffffffffffffffffffffff(ffffffffffffffffffffffffffffff(fff?fff?fff?fff?fff?fffffffffffffff(fff?fff?fff?fff?fff?fffffffffffffff(fff?fff?fff?fff?ffffffffffffffffff(fff?fff?fff?ffffffffffffffffffffftransposeéshowscale¡x(  ?   @  @@  @  @  @  @   A  A   A5c6e0de0c-3901-11f0-234e-bd09c571f662/6a054f00f0376f57layoutxaxistypelogtitletextSteps to Finish Racetemplatelayout coloraxiscolorbarticksoutlinewidth    xaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhitehovermodeclosestpaper_bgcolorwhitegeoshowlakesèshowlandélandcolor#E5ECF6bgcolorwhitesubunitcolorwhitelakecolorwhitecolorscalesequential    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921diverging    #8e0152=ͧ#c51b7d>Lͧ#de77ae>#f1b6da>ͧ#fde0ef?   #f7f7f7?#e6f5d0?333#b8e186?Lͧ#7fbc41?fff#4d9221?  #276419sequentialminus    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921yaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhiteshapedefaultslinecolor#2a3f5fhoverlabelalignleftmapboxstylelightpolarangularaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6radialaxisgridcolorwhitetickslinecolorwhiteautotypenumbersstrictfontcolor#2a3f5fternaryaaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6caxisgridcolorwhitetickslinecolorwhitebaxisgridcolorwhitetickslinecolorwhiteannotationdefaultsarrowhead    arrowwidth?  arrowcolor#2a3f5fplot_bgcolor#E5ECF6titlex=Lͥscenexaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitezaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhiteyaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitecolorway#636efa#EF553B#00cc96#ab63fa#FFA15A#19d3f3#FF6692#B6E880#FF97FF#FECB52data scatterpolargltypescatterpolarglmarkercolorbarticksoutlinewidth    carpetbaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitetypecarpetaaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitescatterpolartypescatterpolarmarkercolorbarticksoutlinewidth    parcoordslinecolorbarticksoutlinewidth    typeparcoordsscattertypescattermarkercolorbarticksoutlinewidth    histogram2dcontourcolorbarticksoutlinewidth    typehistogram2dcontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcolorbarticksoutlinewidth    typecontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattercarpettypescattercarpetmarkercolorbarticksoutlinewidth    mesh3dcolorbarticksoutlinewidth    typemesh3dsurfacecolorbarticksoutlinewidth    typesurfacecolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattermapboxtypescattermapboxmarkercolorbarticksoutlinewidth    scattergeotypescattergeomarkercolorbarticksoutlinewidth    histogramtypehistogrammarkercolorbarticksoutlinewidth    pietypepieautomarginêchoroplethcolorbarticksoutlinewidth    typechoroplethheatmapglcolorbarticksoutlinewidth    typeheatmapglcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921bartypebarerror_ycolor#2a3f5ferror_xcolor#2a3f5fmarkerlinecolor#E5ECF6width?   heatmapcolorbarticksoutlinewidth    typeheatmapcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcarpetcolorbarticksoutlinewidth    typecontourcarpettabletypetableheaderlinecolorwhitefillcolor#C8D4E3cellslinecolorwhitefillcolor#EBF0F8scatter3dlinecolorbarticksoutlinewidth    typescatter3dmarkercolorbarticksoutlinewidth    barpolartypebarpolarmarkerlinecolor#E5ECF6width?   scattergltypescatterglmarkercolorbarticksoutlinewidth    histogram2dcolorbarticksoutlinewidth    typehistogram2dcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scatterternarytypescatterternarymarkercolorbarticksoutlinewidth    marginlBH  bBH  rBH  tBp  yaxistitletextPercent of EpisodesconfigshowLink¨editableªresponsiveêstaticPlotªscrollZoomæframesdatayo:o;\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\==========h=h=h=h=h=h=h=h=h=h=h=h=Nb>Nb>Nb>Nb>Nb>Nb>Nb>Nb>Nb>Nb>Nb>Nb>Nb>Nb>Nb>Nb>Nb>Nb>Nb>Nb>Nb>Nb>Nb>Nb>Nb>P>P>P>P>P>P>P>
#>
#>
#>
#>
#>
#>
#>
#>
#>
#>
#>
#>Q8>Q8>Q8>Q8>Q8>Q8>Q8>Q8>Q8>Q8>Q8>Q8>Q8>Q8>Q8>Q8>Q8>Q8>Q8>Q8>7A>7A>7A>7A>7A>7A>7A>7A>7A>J>J>J>J>J>J>J>J>J>T>T>T>T>T>T>T>T>T>T>Ga>Ga>Ga>Ga>Ga>Ga>Ga>Ga>Ga>Ga>Ga>Ga>q>q>q>q>q>q>q>q>q>q>q>q>q>q>q>q>Hz>Hz>Hz>Hz>Hz>Hz>Hz>Hz>Hz>>>>>>>>>>>>>L7>L7>L7>L7>L7>L7>L7>L7>L7>L7>L7>O>O>O>O>O>O>O>O>z>z>z>z>z>z>z>z>z>z>z>z>z>z>>>>>>>>>>>>G>G>G>G>G>G>G>G>G>G>G>G>G>G>l>l>l>l>l>l>l>l>l>l>l>l>V>V>V>V>V>V>V>V>V>V>V>&>&>&>&>&>&>&>&>µ>µ>µ>µ>µ>µ>µ>µ>µ>H>H>H>H>H>H>H>H>H>H>>>>>>>>>>>>>>>>>>>^>^>^>^>^>^>^>^>^>^>^>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>z>z>z>z>z>z>z>z>z>z>>>>>>>>>>>>>>>>>>>>>>>>>y>y>y>y>y>y>y>y>y>y>y>y>x>x>x>x>x>D>D>D>D>D>D> > > > > > > >j>j>j>j>j>j>j>j>j>E>E>E>#>#>#>#>#>#>#>>>>>>> ? ? ? ? ? ? ? ???????????????????y?y?y?y?y?y?y?????L7	?L7	?L7	?L7	?L7	?
?
?
?
?
?
?V?V?V?V?V?V?V?V?V???????????`?`?`?`?`?33?33?33?33?33?33?33?33?33????????E?E?E?E?E?K?K?K?K?Q?Q?Q?Q?5^?5^?5^?5^?5^?5^?5^?5^?j?j?j?j?j?j?j?j???d;?d;?d;?d;?d;?d;?d;?d;?d;? ? ? ? ? ?%!?%!?J"?J"?J"?J"?
#?
#?
#?
#?
#?
#?
#?B`%?B`%?B`%?B`%?B`%?B`%?$&?$&?$&?+'?+'?+'?+'?r(?r(?r(?r(?r(?)?)?)?)?)?)?+?+?+?+?C+?,?,?,?,?,?,?h-?h-?h-?;/?;/?;/?;/?;/?;/?;/?;/?;/?ף0?ף0?ף0?n2?n2?n2?n2?n2?n2?n2?333?333?333?F3?F3?X94?X94?}?5?}?5?}?5?}?5?6?6?6?K7?K7?K7?K7?K7?8?8?8?8?8?8?:?:?:?:?:?:?:?";?";?m;?m;?m;?/=?/=?/=?/=?/=??5>??5>??5>??5>?R>?R>?d;??d;??w??w??%A?%A?%A?%A?%A?7A?7A?JB?JB?SC?SC?SC?SC?SC?D?D?D?E?E?E?E?ffF?ffF?ffF?ffF?ffF?G?G?G?G?G?G?L7I?L7I?L7I?L7I?L7I?xI?I?I?J?J?J?IL?IL?IL?IL?IL?IL?L?L?M?M?M?M?{N?N?N?N?O?O?O?;O?NbP?NbP?ףP?`P?shQ?shQ?Q?Q?!R?!R?!R?33S?33S?tS?FS?zT?zT?zT?U?U?U?U?V?V?EV?+V?KW?KW?KW?uX?uX?uX?uX?uX?#Y?#Y?#Y?#Y?#Y?Zd[?Zd[?Zd[?Zd[?Zd[?Zd[?[?(\?(\?/]?/]?/]?/]?]?]?]?^?^?^?^?|_?|_?w_?  `?`?`?Ga?Ga?Ga?7a?Jb?Jb?\b?\b?c?c?c?c?
c?Zd?Zd?d?/d?e?ˡe?ˡe?$f?$f?f?f?lg?lg?lg?g?'1h?'1h?rh?L7i?L7i?L7i?^i?^i?i?q=j?~j?j?k?k?k?1l?1l?Il?l?l?Om?Om?hm?m?Vn?Vn?o?o?o?)\o? p? p? p?ףp?ףp?`p?&q?q?q?q?-r?nr?!r?r?33s?ts?zt?zt?zt?zt?jt?t?}?u?u?u?v?Ev?v?v?=
w?Kw?Pw?Qx?Qx?Qx?ux?x?y?Xy?y?#y?z?5^z?z?Hz?"{?Zd{?{?m{?(|?j|?|?|?/}?p}?-}?}??5~?v~?R~?~?d;?|?w?  ?typescatternameMonte Carlo ϵ-Softx  `A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A   B   B   B   B   B   B   B   B   B   B   B   B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B   B   B   B   B   B   B   B   B  $B  $B  $B  $B  $B  $B  $B  $B  $B  (B  (B  (B  (B  (B  (B  (B  (B  (B  (B  ,B  ,B  ,B  ,B  ,B  ,B  0B  0B  0B  0B  0B  0B  0B  0B  0B  0B  0B  0B  4B  4B  4B  4B  4B  4B  4B  4B  4B  4B  4B  8B  8B  8B  8B  8B  8B  8B  8B  8B  8B  8B  <B  <B  <B  <B  <B  <B  <B  <B  <B  <B  @B  @B  @B  @B  @B  @B  @B  @B  @B  @B  @B  DB  DB  DB  DB  DB  DB  DB  DB  DB  DB  DB  DB  DB  HB  HB  HB  HB  HB  HB  HB  HB  HB  HB  HB  HB  LB  LB  LB  LB  LB  PB  PB  PB  PB  PB  PB  TB  TB  TB  TB  TB  TB  TB  XB  XB  XB  XB  XB  XB  XB  XB  XB  \B  \B  \B  `B  `B  `B  `B  `B  `B  `B  dB  dB  dB  dB  dB  dB  hB  hB  hB  hB  hB  hB  hB  hB  lB  lB  lB  lB  lB  lB  lB  lB  lB  lB  lB  lB  pB  pB  pB  pB  pB  pB  tB  tB  tB  tB  tB  tB  tB  xB  xB  xB  xB  |B  |B  |B  |B  |B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B   C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  	C  
C  
C  
C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C   C  !C  !C  "C  "C  #C  #C  #C  #C  &C  'C  'C  (C  )C  *C  +C  +C  ,C  ,C  .C  .C  /C  /C  /C  0C  1C  1C  4C  6C  6C  6C  8C  8C  9C  ;C  <C  =C  >C  ?C  ?C  @C  @C  AC  BC  BC  CC  CC  DC  FC  GC  GC  HC  HC  HC  JC  LC  LC  LC  MC  MC  OC  PC  QC  QC  RC  UC  XC  YC  [C  ^C  `C  bC  bC  bC  bC  cC  eC  gC  jC  kC  lC  mC  qC  qC  sC  tC  vC  xC  xC  xC  zC  |C  C  C C  C C C  C C C  C C C  C  C C  C C  C C  C  C  C  C C C C C 
DyL1:1;1;1;Z;I;K;w<w<Z'<8<Y<Y<Kj<{<1<T@<w<<Z<ฯ<<&u<<<<<<<<=1=B
=eo=eo=w===+#=Ή+=Ή+=/=3=8=F<=&u@=7D=IH=ZM=l1Q=~`U=Y=]=a=f=Kj=zn=r=
v=-7=-7=ʃ=ʃ=1==B=(=T@=W=eo==w==͚===4C=4C=4C=Z=Ή=Ή=W=ฯ=iб====.=F=]=&u==7==I==Z==l1=H=x=x====)==L4=L4=L4=^c=^c=z=o===
====-7=[ >>>>1>1>>>~	>B
>>(>4>T@>L>W>c>eo>*{>>>w>;>>>>M>>>>^ >#!>">+#>p7$>4C%>N&>Z'>f(>Fr)>
~*>Ή+>,>.>.>/>0>i1>-2>3>4>z5>>7>8>"9>P:;>P:;>F<>Q=>]>>bi?>&u@>A>B>7D>7D>E>F>IH>IH>I>J>K>ZM>N>O>%P>0=R>0=R>TT>TT>~`U>BlV>xW>˃X>Y>SZ>]>]>]>e^>)_>`>a>vb>;d>(g>(g>(g>L4h>@i>Kj>Wk>"om>"om>zn>o>r>r>r>s>t>Eu>
v>w>x>{>{>|>}>h+~>-7>[>[>=->>9>㾂>ʃ>ʃ>P>lք>1>1>h>>s>>>~>`>$>$>>颋>(>>4>q>T@>6Ǝ>L>я>W>ݐ>c>>eo>G>>>>>>>Y$>Y$>;>0>>;>>G>͚>jS>Mٛ>>>j>>v>>|>^>@>#>>>ɥ>+>>p7>R>4C>ɥ>N>Ԧ>Z>>f>Fr>Fr>(>>>Ή>>>u>W>9'>>2>ฯ>>>İ>iб>iб>KV>b>b>>m>>y>z>\>!>!>>圸>">>.>n>P:>2>F>˼>Q>]>]>>D>D>&u>>>>>>s>U>7>>>5>>A>>gM>I>+Y>>d>>p>>x|>Z>=>>>>ş>%>l1>l1>N>0=>H>H>T>T>>~`>`>Bl>$>>>˃>	>>S>S>6!>>,>ܲ>8>>e>e>GP>)>>>g>>s>v>Y>;>>>>>>(>j>L4>@>@>>K>>W>^c>^c>@>"o>>z> >>>o>R>4>$>>/>>;>>cG>E>'S>
>^>>j>>uv>W>9>>>>>>>h+>K>-7>>y! ?jd ?[ ?L ?=-?.p???9?{???D????P?{?l?]?@?@?"%?"%?h???0?s?ȶ??<???~	?oH	?`	?Q	?B
?3T
?$
?
??_???(?k???4?w?q?c?T@?E?6?'	?L?	???W?Κ??c?c???t,?V?V?G?88?*{???C???O?O????[?w?h?Y$?Jg?;?,?0?s???;?~???G??y?y?jS?\?M?/_?/_? ??(?j???3??????|?m?OK ?OK ?@ ?1 ?#!?W!?!?!?"?b"?ɥ"?"?+#?n#?#?#?az$?az$?R$?C %?4C%?%%?%?&?N&?&?&?'?Z'?'?'?#(?f(?r(?c(?T/)?Fr)?7)?()?;*?
~*?*?+?F+?Ή+?+?,?R,?,?,?u-?f^-?W-?H-?9'.?*j.?.?.?2/?u/?/?/?>0?0?0?1?J1?x1?i1?Z2?KV2?<2?-2?3?b3? 3?3?*4?m4?Ű4?4?65?y5?5?z5?kB6?\6?M6?>7?0N7?7?7?8?Y8?8?8?"9?e9?9?9?.:?}q:?n:?_:?P:;?A};?2;?#<?F<?<?<?=?ʔ=?ʔ=?=?>?]>?>?>?p&??bi??S??D??52@?&u@?@?@?=A?A?A?B?IB?B?B?C?UC?sC?dC?UD?FaD?7D?)D?*E?E?E?E?5F?xF?F?F?AG?G?G?v
H?gMH?XH?:I?:I?+YI?I?I?!J?dJ?J?J?-K?pK?K?K?9L?x|L?iL?ZM?LEM?=M?.M?N?QN?N?O?O?\O?şO?O?%P?hP?P?{P?l1Q?]tQ?NQ??Q?0=R?R?R?S?HS?S?S?T?TT?T?T?U?~`U?oU?`U?Q)V?BlV?3V?$V?5W?xW?W?W?@X?˃X?X?	Y?LY?Y?Y?qZ?bXZ?SZ?EZ?6![?'d[?[?	[?,\?o\?ܲ\?\?8]?{]?]?^?t^?t^?e^?V_?GP_?8_?)_?`?\`?`?`?$a?ga?a?a?0b?sb?b?vb?h<c?Yc?Jc?;d?,Hd?d?d?e?Se?e?e?_f?_f?f?f?(g?ykg?jg?[g?L4h?=wh?/h? h?@i?i?i?j?Kj?Ǝj?j?k?Wk?k?|k?m l?^cl?Ol?@l?1,m?"om?m?m?7n?zn?ؽn? o?Co?o?o?p?~Op?op?`p?Rq?C[q?4q?%q?$r?gr?r?r?/s?rs?s?s?;t?~t?t?ru?cGu?Tu?Eu?6v?'Sv?v?
v?w?^w?ݡw?w?'x?jx?x?x?3y?uvy?fy?Wy?H?z?9z?*z?{?K{?{?{?|?V|?|?|?}?b}?}?w}?h+~?Yn~?K~?<~?-7?z??  ?typescatternameRandom PolicyxL  `A  A  A  A  A  A   B  B  B  B  (B  <B  <B  PB  XB  `B  tB  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  C  C  C  C  C  C  C  C  C  C  C  "C  )C  *C  -C  .C  1C  1C  6C  6C  9C  =C  @C  DC  EC  GC  NC  PC  TC  VC  YC  aC  aC  eC  eC  eC  fC  kC  kC  mC  pC  rC  wC  xC  xC  {C  |C  }C  C C  C C  C C C C C C  C  C C  C C  C C  C  C  C C C  C C  C C C  C C  C C C C  C C  C  C  C  C  C  C  C C C C  C C C  C  C  C  C C C C C  C  C C C C C C C C C  C  C C  C  C C  C C  C  C  C C  C  C C  C  C  C C  D D D D  D 	D 
D D  D D  D  D D D @D @D  D  D  D @D D @D @D D D  D  D @D D D  D @D D @D @D @D D  D D  D @#D @$D 'D 'D 'D  (D (D  )D *D .D .D /D 0D @1D @1D @1D  5D  6D @7D  9D :D  <D @>D @>D >D ?D @D @AD AD AD @DD DD @FD HD ID ID KD LD  ND  ND @ND @OD @QD RD RD VD  WD XD XD ZD @[D @\D  ]D ]D ]D ^D _D @aD aD bD cD @dD  hD hD  iD @jD @jD  lD @lD lD  mD @mD @mD mD nD @oD @pD pD @qD  uD uD vD yD yD @zD zD  ~D @~D ~D D `D D D D  D  D D  D  D @D D  D  D  D @D `D D D `D @D @D D  D @D D @D D D D  D @D `D D D  D D D @D `D D @D D D  D  D  D @D D D  D `D D @D D @D `D  D  D `D D D D  D @D D D D D D @D D D  D  D D  D  D D D @D @D D D D  D @D D  D D D D  D  D  D D D `D `D D D  D D  D  D @D  D  D @D  D D D D `D D D `D D D D D  D @D D D  D  D D `D @D `D D  D D D @D D  D @D D D  D D  D  D D D D D  D  D D D `D D  D  D D D D  D D D @D `D D  D `D `D D  D `D D  D D  D D D D D  D `D D `D @D D  D `D `D D D D  D D D D D  D D D D D  E 0E @E @E E E @E PE E E E  E 0E `E pE E E  E E 0E @E E @E 	E 0	E 	E 	E @
E 0E E E E E E E @E  E 0E @E E `E  E E E E  E @E E E @E E E E E  E pE E E  E `E E E pE pE E E E  E E E PE E E 0E E E @ E ` E  E  E !E @"E "E #E $E $E $E @%E %E 'E 'E 'E p(E *E p*E  +E P+E p+E +E +E @,E p,E ,E @-E -E -E -E  .E 0.E `.E  0E @1E p1E @2E 2E `3E 3E 3E 4E P4E p4E p4E  6E P6E 6E 7E 8E 09E  :E :E :E ;E ;E <E  =E 0=E >E 0?E  @E AE AE BE BE  CE  DE pDE DE 0EE EE EE FE PFE FE `GE GE GE  HE @HE `HE HE HE `IE  JE JE JE `LE LE NE  OE OE  QE RE RE SE @TE pTE TE  VE VE @WE PWE pWE WE  XE PXE `XE XE XE 0YE YE PZE `ZE ZE ZE  [E  [E P]E ]E ^E P_E p_E _E _E P`E `E  bE bE  cE cE 0cE cE  dE @dE eE eE  fE 0fE 0fE 0gE PgE gE gE  hE 0kE kE plE nE oE pE qE rE rE  sE  sE psE PtE tE tE puE vE wE PxE xE PyE yE {E |E |E |E @}E }E 0~E  E  E E (E E ȀE ؀E (E E E E E HE PE `E E  E @E pE E E E  E hE E ȅE E hE E E E E E E E E 8E `E xE E XE E 8E PE pE HE HE E E E PE `E ȐE HE PE E E E 0E 0E E xE  E E E E E pE E E E E E XE E 8E XE E  E `E E E ȟE  E РE ؠE @E ءE E  E (E (E 8E E xE ФE E  E E (E E E  E 8E hE E  E E ЫE XE E E E E pE hE E E 0E E E E HE E E E ضE E pE E E E E 8E мE xE ȾE E E E E XE 0E E XE E pE E `E E E HE HE `E hE E 0E E E HE E E E  E `E E E @E E @E E E `E E E hE E 0E xE E E E E E E pE E E E E E E  E E @ F t F XF `F F F F tF F F F F  	F 
F F 8F F DF F F F F F $F F F5c6e0de0c-3901-11f0-234e-bd09c571f662/7b3f5adc32cbaebflayoutxaxistickvals(  ?   @  @@  @  @  @  @   A  A   AtitletextDealer showingticktextA@   @@  @  @  @  @  A   A  A   templatelayout coloraxiscolorbarticksoutlinewidth    xaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhitehovermodeclosestpaper_bgcolorwhitegeoshowlakesèshowlandélandcolor#E5ECF6bgcolorwhitesubunitcolorwhitelakecolorwhitecolorscalesequential    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921diverging    #8e0152=ͧ#c51b7d>Lͧ#de77ae>#f1b6da>ͧ#fde0ef?   #f7f7f7?#e6f5d0?333#b8e186?Lͧ#7fbc41?fff#4d9221?  #276419sequentialminus    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921yaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhiteshapedefaultslinecolor#2a3f5fhoverlabelalignleftmapboxstylelightpolarangularaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6radialaxisgridcolorwhitetickslinecolorwhiteautotypenumbersstrictfontcolor#2a3f5fternaryaaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6caxisgridcolorwhitetickslinecolorwhitebaxisgridcolorwhitetickslinecolorwhiteannotationdefaultsarrowhead    arrowwidth?  arrowcolor#2a3f5fplot_bgcolor#E5ECF6titlex=Lͥscenexaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitezaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhiteyaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitecolorway#636efa#EF553B#00cc96#ab63fa#FFA15A#19d3f3#FF6692#B6E880#FF97FF#FECB52data scatterpolargltypescatterpolarglmarkercolorbarticksoutlinewidth    carpetbaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitetypecarpetaaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitescatterpolartypescatterpolarmarkercolorbarticksoutlinewidth    parcoordslinecolorbarticksoutlinewidth    typeparcoordsscattertypescattermarkercolorbarticksoutlinewidth    histogram2dcontourcolorbarticksoutlinewidth    typehistogram2dcontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcolorbarticksoutlinewidth    typecontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattercarpettypescattercarpetmarkercolorbarticksoutlinewidth    mesh3dcolorbarticksoutlinewidth    typemesh3dsurfacecolorbarticksoutlinewidth    typesurfacecolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattermapboxtypescattermapboxmarkercolorbarticksoutlinewidth    scattergeotypescattergeomarkercolorbarticksoutlinewidth    histogramtypehistogrammarkercolorbarticksoutlinewidth    pietypepieautomarginêchoroplethcolorbarticksoutlinewidth    typechoroplethheatmapglcolorbarticksoutlinewidth    typeheatmapglcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921bartypebarerror_ycolor#2a3f5ferror_xcolor#2a3f5fmarkerlinecolor#E5ECF6width?   heatmapcolorbarticksoutlinewidth    typeheatmapcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcarpetcolorbarticksoutlinewidth    typecontourcarpettabletypetableheaderlinecolorwhitefillcolor#C8D4E3cellslinecolorwhitefillcolor#EBF0F8scatter3dlinecolorbarticksoutlinewidth    typescatter3dmarkercolorbarticksoutlinewidth    barpolartypebarpolarmarkerlinecolor#E5ECF6width?   scattergltypescatterglmarkercolorbarticksoutlinewidth    histogram2dcolorbarticksoutlinewidth    typehistogram2dcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scatterternarytypescatterternarymarkercolorbarticksoutlinewidth    heightC  marginl    b    rA   tA  yaxistickvals(  @A  PA  `A  pA  A  A  A  A  A  AtitletextPlayer sumticktext(  @A  PA  `A  pA  A  A  A  A  A  AwidthC  configshowLink¨editableªresponsiveêstaticPlotªscrollZoomæframesdatazmax?  y(  @A  PA  `A  pA  A  A  A  A  A  AtypeheatmapcolorscaleGreyszminʿ  z(  ?  ?  ?  ?  ?  ?  ?      (  ?  ?  ?  ?  ?  ?        (  ?  ?  ?  ?  ?  ?        (  ?  ?  ?  ?  ?  ?        (  ?  ?  ?  ?  ?  ?        (  ?  ?  ?  ?  ?  ?        (  ?  ?  ?  ?  ?  ?        (  ?  ?  ?  ?  ?  ?        (  ?  ?  ?  ?  ?  ?  ?      (  ?  ?  ?  ?  ?  ?  ?      transposeéshowscale¡x(  ?   @  @@  @  @  @  @   A  A   A5c6e0de0c-3901-11f0-234e-bd09c571f662/58d51ac87604fe9clayoutxaxistypelogtitletextEpisodestemplatelayout coloraxiscolorbarticksoutlinewidth    xaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhitehovermodeclosestpaper_bgcolorwhitegeoshowlakesèshowlandélandcolor#E5ECF6bgcolorwhitesubunitcolorwhitelakecolorwhitecolorscalesequential    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921diverging    #8e0152=ͧ#c51b7d>Lͧ#de77ae>#f1b6da>ͧ#fde0ef?   #f7f7f7?#e6f5d0?333#b8e186?Lͧ#7fbc41?fff#4d9221?  #276419sequentialminus    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921yaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhiteshapedefaultslinecolor#2a3f5fhoverlabelalignleftmapboxstylelightpolarangularaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6radialaxisgridcolorwhitetickslinecolorwhiteautotypenumbersstrictfontcolor#2a3f5fternaryaaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6caxisgridcolorwhitetickslinecolorwhitebaxisgridcolorwhitetickslinecolorwhiteannotationdefaultsarrowhead    arrowwidth?  arrowcolor#2a3f5fplot_bgcolor#E5ECF6titlex=Lͥscenexaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitezaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhiteyaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitecolorway#636efa#EF553B#00cc96#ab63fa#FFA15A#19d3f3#FF6692#B6E880#FF97FF#FECB52data scatterpolargltypescatterpolarglmarkercolorbarticksoutlinewidth    carpetbaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitetypecarpetaaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitescatterpolartypescatterpolarmarkercolorbarticksoutlinewidth    parcoordslinecolorbarticksoutlinewidth    typeparcoordsscattertypescattermarkercolorbarticksoutlinewidth    histogram2dcontourcolorbarticksoutlinewidth    typehistogram2dcontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcolorbarticksoutlinewidth    typecontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattercarpettypescattercarpetmarkercolorbarticksoutlinewidth    mesh3dcolorbarticksoutlinewidth    typemesh3dsurfacecolorbarticksoutlinewidth    typesurfacecolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattermapboxtypescattermapboxmarkercolorbarticksoutlinewidth    scattergeotypescattergeomarkercolorbarticksoutlinewidth    histogramtypehistogrammarkercolorbarticksoutlinewidth    pietypepieautomarginêchoroplethcolorbarticksoutlinewidth    typechoroplethheatmapglcolorbarticksoutlinewidth    typeheatmapglcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921bartypebarerror_ycolor#2a3f5ferror_xcolor#2a3f5fmarkerlinecolor#E5ECF6width?   heatmapcolorbarticksoutlinewidth    typeheatmapcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcarpetcolorbarticksoutlinewidth    typecontourcarpettabletypetableheaderlinecolorwhitefillcolor#C8D4E3cellslinecolorwhitefillcolor#EBF0F8scatter3dlinecolorbarticksoutlinewidth    typescatter3dmarkercolorbarticksoutlinewidth    barpolartypebarpolarmarkerlinecolor#E5ECF6width?   scattergltypescatterglmarkercolorbarticksoutlinewidth    histogram2dcolorbarticksoutlinewidth    typehistogram2dcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scatterternarytypescatterternarymarkercolorbarticksoutlinewidth    legendyʾLͫorientationhmarginlBH  bBH  rBH  tBp  yaxisrange̽  @titletext.Mean square error <br> (average over 100 runs)titleconfigshowLink¨editableªresponsiveêstaticPlotªscrollZoomæframesdatayȜ@L@X/?7:? ?Ƚ?l!?:s?)
e?P?N+??]8?^>t>C#>~>B>ú>g>>y>>ȉ>>h>xk>f>>l>$r>ʭc>k_>U>[>3k>Fd>]>s^>;P[>81X>zN>AA>ݯ;>7e)>Q>u>d>">>>W>>h>>>,>V>N>0>>>>f>	>V>i
>>q{>=>}>m
>.>W>=OI==T==D===7=G=ќ====)=>=!==&=`===N====d=|=0==_=J=}X== =ð=c"==f=_=Ѧ=ѧ=<=<=߹=y=%=㽙=3==:=&=
N=?=/[=9=婈=І=k=6=L=_ =_=Cr=]====|=/Օ=g=v=u=̳==7=/=\=^=#=tP===%=ք=Qǅ=܇=ۄ=,6==hs|=D{=@wx=q=z=Z}={=-#y=u=t=:p=n=k=_k=hg=f=wf=8bj=i=f=d=<a=7a=$#h=f=fb=Ț^=j=(g=j=}l=i=6g=d=R8a=\=\=%_=}^=?p_=lL]=[=fZ=W= S=}	Y=.-W=%+U=zR=P=)K=]G=H=M=cM=aK=;3K=L=W!L=H=6I=dJ=YJ=J=J=vI=L=#AO={O=O=K=-J=\D=VD=|V@=?=pA=??===f;=>=@;=[;=ʀ;=F:=4;=7=:=7=7=6=4=[6=E5=2=8=6=3=)1=1=82=2/=Sr1=lS0=81=.=&.=S0=[/=D/=/=Ѽ.=a-=w.=\3.=1=1=.=+-=e:-=M]-=+=O*=@W*=~)=_'=%={%=&=%$=@%=7e%='=V$=$=o&=̹&=!'=30%=ы$=!=\=n==_=mW=," =!=c===Y=ӽ=L'=c=>=}=?=K======4-=TI=S==-
==!====%====r1==ϣ==Q>===W%==e==5=9====Uz=f
=u==@=`=o~=ܨ==F=e=|= D=F=]=͔=@==f==T=z==T=Dl=> =3G<<<n3<?<L
<:<7<j<(<<rr<<<e<x<
< J<Q<<]<؉<,s<f<6<3<g<Q<4O<-<d<C<<q<C<s<-*<Q<q1<:<<?<<3<D<<=<d<6<n<-r<#<<<<<8W<s<ԅ<<]<<R<<<j<<<f<}<8e<!<]<̏<6L<v<.<<6<L<<-<I<<F<<+<w<<8<-J<_<<j< <<.<׋<<<<*(<Cm<<e<v<
S<<)<@<(-<&<5<<H;<C<ӽ<Ϋ<<	<<ھ<X<m<\<w<ѷ<w<{8<<..<(<H˴<<ض<`<չ<<< <m<<4j<f<<\<LM<#<Sl<w<ɲ<<\_<s<-<ǭ<<m@<h<)R<\<}y<곩<|<c[<<rӧ<m<<
<3<<Ц<Iæ<-ڤ<Ǥ<Q<2<#0<Q<x<M]<<Tz<S<&<z<2<K#<I<ޠ<<;<7<<<<'<<.<Tg<ƙ<Q<<<כ<Ś<<r<=<VD<	<b<<Z<<+\<ޞ<K<FI<()<L<;<D<t><1<`<<<]<O<}S<*͘<Uy<<$<<l<x< <<dz<]<9<_Z<'<_̑<t><<<ȕ<)<t<<<Α<ÿ<<<<<:<<H<`<C<Qx< <#<ܥ<a<<ć<·<<3ω<4؈<VB<]<芇<Vr<z؈<OZ<<(<<V<1<U<崃<d&<<<둃<q<b*<؆<ق<ш<<<@<4<p<{<lB<7:<<v<!<ހ<<&D}<N{<]Vx<,s<#r<q<o<o<m<Ml<l<k<i<@h<f<g<g<e<9f<Rd<b<U`<_<_<^<]<*H^<2^<mm]<l[<:*Z<Y<X<@jY<*W<,;W<vZ<]\<NZ<Z<[<\<Z<!SZ<[<2X<֤V<HW<@.Y<R0X<QW<DT<U<T<U<[U<]=U<S<nS<۱R<	Q<!Q<CP<S<R<T<sR<pR<TS<U<:T<CT<XT<sS<T<SQ<O<P<O<N<fN<L<ĆJ<qJ<7J<K<wL<wK<_jH<D<qC<C<E<D<B<]C<A<L@<RA<
A<@<oA<TA<?<.?<l><t<<=<Of=<i=<:<<4<<l<<B<C<B<C<NC<D<ێE<7E<I<J<,H<E<hD<߇C<B<A<2A@<?@<@<*@<(Q@<؟><M></></=<9<:<<<D=<=<<<
=<><?<[@<J?<Z><h=<w ?<$><?<><lK@<?<Q]=<; ><F8=<S=<U=<<<=<O=<]<<<<o5;<79<8<F7<z6<H7<<58<7<F2<$2<K5<4<:6<4< 6<e8<o8<	9<m)9<|8<8<8<d8<6<(6<f9<;<!<</;<z8<:8<8<7<_7<;7<7<;/6<5<`5<5<H6<Q5<c6<:o5<86<ғ5<3<1<{T2<4<x4<3<h2<A;3<W2<
3<1<2<_2<r1<4<4<ir5<//7<y8<?6<6<.6<7<[<7<6<5<n4<34<^4<p3< 00<.<</<0<Ɏ.<,<d+<+<$-<,<4-<-<}.<0<?P0<.<,<j,<ʤ.<M.<h-<]-<a/<\,<4+<(<#*<*<'<'<i%<%<&<&<'<='<3$<f#< "<<!< <\ <f <!<c!<%!<!<C<<0<?E<M<<z^<<<<V<<^<A<t<a<h<<ǫ<<.<<J<<<<<<`<<R'<<<<<<<4<(<<<d<Y<EH<C<<,<6<&<:<(,<<?<fp<<I<9M<H<<l<<<k<>n<<L<.<C<é<|<<M<<<<$J<vK<I]<<z<<V<<<Sy<<T<<<<'<[<<^i<C<M<7K<V<<r<<<w<<5<<<<<XD<<F2<;<_<"b<<a<X<.<ّ<l<<W<<<b<,<B< <1<q<qV<-<<5J<<D}<<<v<N<<O)<ݶ<<<Q<<<[<d<<6<q<<<{<J.<<'<<W<ɹ<<XN<<j<Q<ɨ<i<<c<6<T<j<<<,{<<<[r<]X<(~<<<y<.<k<1&<H<F<[<<<<<9<<T<<*<ކ<<x<Ć<(<<y	<[
<jP
<Y
<
<qO	<q
<<	<(	<c<<<<<<n<T<_<@<<$y<D<,<<~<F<O<qS<<6<<<N<,<~<<<e<<< <:<<o<<t<<B<A<<"<<Wq<q<<7<<u<I<-<<<<4<<r <S;;`V;;Ù;;$ <f <3 <_;;SM;r ;8;;;;t; ;^] <L;c <;p;ou;; <3;$; <<,<t <Ԍ <Q <E < <# < <4<-< < < < <7;r;;t;;N;;;^;;VM;Mf;#;(;Z;A;?;;@;P;; < < < <;,;`;;N;;;g;;/;\;;O;tO;n;j;|;;
F;φ;p;E;QK;;;-;;Ņ;v;#1;7;f+;;X;;w;wB;@;;;=;;*;ݒ;3;rd;zV;W;];A;O;;;;;l;I;;;ŵ;P;);V-;I&;;;;T;;L;;#;;c;;;;*.;;l;;;v;;ڳ;;lL;%;L;;;(,;;;D;k;t;sm;K;(7;;3;S;e;s{;X_;>;X;;9;~;:;C;5;WE;a;p;;a;I;j;A;W;z;.;;;.;;n;64;ɼ;\;H;S[;;@;;;Z;;;o;;);?;;d;{=;n;J;?;m;M;`;7;e;e;X;@;+;
;;R;b;;;;Zc;;;V;S;֛;;2;t;!;;;;;1;a$;;;S;s;;;:z;.;/;4E;&;);8;h;:;F;;.;;;;;});g;S;;;Zg;;W; ;r;;];;0;[;Î;;p; ;;;;;;;:;A;6;N;
;q;Ŗ;;;;;;!	;?;;~;c;;;;q;:p;;;6;֚;;L;l;w;;Q;;;;w;3;V;R;d*;8;,;=;;j;C;L;t;:;:;
;;w;;;y;.;;n;y;q; `;;f;;;;;G;;S;2; ;Ҏ;N;&;(;$;!b;`;A;7;[;1;a;; ;F5;;8;=;;H};܇;}1;;;;$r;;`;Q;V;9;F; ;h;C;;<;h4;#;o;;;;@x;;;N;_;H;;6;;s;;;;s;;;,;;;0;x9;;Ħ;>;D;	;;Ʋ;F;;N
;:5;;FU;w,;;;?;[;	;;AP;.0;.;;;s;;|;X_;==;0;.;;}[;;;;j;~;;;;];
;;O;4;C;c;d;;;_;e;i;4;k;;X\;&z;j;;O;?;,;;-;H;;);;=;;b;;8;;;;;T;;;C;z;;$;;|;l;7|;<;\;[;;;;vL; ;4;y;(׻;L;Z;3F;ͷ;t;;)&;L;Z;;;c;&!;7/;T;#a;;E;y;;^;;;X;;;;wĶ;iN;ŵ;ߵ;F+;`);!Y;p;;\z;1P;M;O9;m2;,;;Z;Z;;n;;;;6;!_;;D;n;X;=;$;;ò;;aX;H;;;د;<;FŮ;{;o#;
;_:;Mԭ;[_;X;4;z;L;;h;	;舘;3!;]&;<d;n®;㺮;[;w׭;f;z;#;K;ᝪ;![;۪;;ڧ;F;M;Ϩ;";;;Hת;A;=;;Ҽ;W;I;;_;;H;i; ;w;QΩ;@;l%;`;ڦ;E;ά;;DӦ;;;J;V;;Dͨ;e;!;S;Dϧ;83;;A;{;ƌ;k;A;o;;r;Ƀ;w;L;6֨;R;;ŏ;;;;t;[;4;7;n;;`;ؠ;ZZ;(̟;H;xD;;;;Jҝ;o;;<;};ߛ;2;޸;];(;F;j;G;L;D;Q;,;;;;z;H?;k;D;A	;*;4;}Й;/;`Η;:;;;n;9;;;';	;	;ra;};T;J;ƨ;;;֗;W;o;#;ؕ;+;@;Ta;;c;7;>;kݕ;;:D;g;Y;<2;;D;&;;ʜ;;_;;d;A;{;-;Ԕ;;;;tҒ;];J[;;Aԓ;A;u;ѕ;ǖ;`;/1;i;4;k;g;B;Z;ݰ;XF;ܔ;=;;,;;;;;?;ɓ;R; ;s;ƛ;D;';);c!;; ;ҕ;w;c;ٔ;m;2; ;F;0ܔ;$;D;Δ;3;O;;;Ε;̔;ك;
8;;;;|;ϔ;cƔ;C;&;-;;;-6;};s;};q;;U@;y;b;z;ޖ;p;Cr;8;-&;Ae;;;b';;;S;#;;;;VC;Ք;{;ړ;CÔ;;;P;s;	Җ;;6;t*;A;;ĕ;i;B;c;QI;M;;;AK;ޓ;z;Ғ;x;;2;đ;TE;e;B;_;3;;';\;?;;y^;;ڎ;Ӎ;;;$0;.;;];CF;Fn;; y;;΍;y;1;;!;T;;Z;Q;%3;͋;T;o;D;ļ;Jq;6;S;Ջ;;J;>{;ڌ;;p;z;;;Z،;J;G;Ř;;ċ;Ê;̊;h;e;q;a6;;Uމ;=;v;%;A,;<;PF;C;;m;a;;;׊;;;	M;	5;;`;;};Z1;z;;";L;f;l;D5;;*;;a;P;z;v;q;FӉ;T͉;쳈;];ca;;J;I;]؆;?;߷;V;; ;x;P;ͅ;	;/;Q;-;;z;;);;ك;A;;*;.;L;;τ;e;=;;˄;ͧ;袄;0;V;;娅;;4;0;I;a;;6;Y;8Ј;;W;l;%J;#;B`;;n;h;/;kم;_4;\s;- ;9-;;`ކ;;m;ٗ;n;,;	;J;5;;3;!.;-;l;6و;_;;k;@;T;v*;݉;ˑ;;h3;_;D;;;AP;=;;;z;M;輻;;胈;ȇ;q;\;я;;;-;I;#;O;;;@;	;;;0;O;;e;P;";(;T;;AӅ;05;;ׄ;C;m;g;n;W;Z;;Ճ;Rh;S; J;Ƃ; ;;|6;ۂ;;;KT;*";P[;l;͂;S;#;m;;;!;";;7I;E;X$;a;c;Q;=J;o;|;|;O;Z;;z;|H;vA;;v;W;X^;en;@;;3;;zv;C`;~;l};};|;}8|;S{;qz;};};`}; d|;S!|;|;F'{;.z;A{;Jjz;y;y;x;w;Tv;v;>x;]y;Dy;y;x;Iw;sw;v;u;v;#v;ذv;v;u;t;rt;t;&u;su;u;$w;46w;w;Zv;u;u;Wu;<t;:s;r;r;q;!p;h%o;s;{s;r;r;r;q;7Gr;ar;[q;Lq;q;-q;fq;o;.Do;n;VEn;m;7m;l;m;ehm;Nl;[k;3m;l;D9m;x m;o;o;&Io;Wo;{1o;2o;n;1Ql;)rm;n;#m;q0m;ԥm;m;n;nm;l;ul;bm;Mm;͕l; l;l;l;rk;ol;k;}n;vOo;bn;Qn;3n;/m;)Nm;Fvm;wn;hzo;Zo;n;!n;n;n;no;}-n;[o;Fq;Ap;Cq;>p;p;:p;Co;$#o;S_p;o;m;m;[Wm;l;Mil;j;i;j;Vj;l;l;n;7n;Jm;n;,n;Xur;wp;|dp;һq;zZr;Dq;p;q;_p;Tp;Wn;o;n;(m;m;n;rk;m;*Fl;nl;m;1m;*k;k;k;l;Vm;m;hl;k;
k;\l; ?l;&Sk;j;j;\j;xi;& i;Ng;̴f;f;rxf;%]e;e;Cf;,Af;f;f;&f;e;e; c;8|b;wc;=d;ad;d;b;qa;`;`;oO`;Z_;^;_;lP_;-`;F`;\`;1`;_;_;h_;͓_;_;7~`;ӆ_;t!_;<_;_;^;@	^;];y_;e_;A_;`;.C_;^;_;_;8Z`;J_;^;M^;ؒ^;<];o\;f];^;Iq_;N_;:_;a;/a;O`;_;8_;`;x_;r_;`;`;`;vl`;
C`;`;,_;^_;>_;τ^;];c];&];];];\;j\;0^;\;|];];2]; H\;8A];-\;[;)[;Y;4Y;[;جY;XX;7%X;=LW;IV;}W;VV;XU;7U; U;T;8S;S;QS;R;-S;S;R;lR;-$P;!&P;O;rO;eO;(O;ZN;[O;O;WP;TzP;LO;Q;jQ;Q;P;OP;(5P;)Q;͞Q;)Q;P;`O;HQ;P;P;TQ;/P;8O;O;O;O;OZP;Q;2O;.O;rAP;/P;MO;xYM;v6M;L;sL;|lL;4K;L;L;M;؉N;nM;vK;_K;K;}K;{J;J;}L;lL;SL;ɣM;L;ʊK;dL;K;M;M;WM;HM; L;eL;QuL;TK;jJ;QL;lK;sJ;TJ;CzI;9I;H;aI;I;J;#J;rJ;fJ;#J;)J;J;K;]L;L;uL;M;M;M;=M;wM;M;iM;LL;M;AM;zL;ML;zaL;PL;sK;ĜL;
L;uL;	JL;vL;!L;-L;eK;aK;XK;1L;K;`iJ;T)J;7J;
I;H;mK;9H; CH;]H;H;*II;I;:I;[pG;wG;nH;RH;1G;M6F;F;[F;vF;]F;vE;QD;AD;vD;KE;D;3D;D;5E;HE;8E;D;ԋD;E;nD;,C;DB;CB;;B;A;A;A;A;A;A;xmA;΃A;,B;xA;$@;JA;A;-B;;B;QA;wA;@;@@;>;@;6@;|@;O @;&?;?;>;i<;<;J:;s:;9;9;d9;9;*9;z8;9;w9;:;9;9;͊9;	y9;=g9;d9;c8;V:;}:;=[:;;;o;;:;w:;[:;9;9;_9;):;f:;M|;;C:; ;;9;T:;:;O:;:;
9;:;L:;3:;C:;|9;:;8;;3:;q:;s:;m:;:;͆9;R"9;8;8;8;7;7;ɻ8;8;/L8;s8;lH8;8;7;ι8;8;C8;d8;i8;rg8;K7;xt7;?r6;W6;L7;T6;5;z@6;ZL6;5;r6;]<7;dI7;[8;7;37;r6;5;^5;*O6;H+7;6;N6;|7;wN6;7;Y6;K6;6;L6;6;8?6;(6;a5;75;6;N7;7;7;7;wc7;r7;N%7;H7;7;ř6;`6;T6;5;5;q5;o6;5;6;|6;Ɇ6;3;3;@3;2;2;{2;162;|1;l1;1;\1;1;/;.;w0;_/;/;%/;Ӹ/;x0;{/;/;/;ܜ/;a0;/;l/;.;u/;4/;s/;?/;s.;2/;!.;Q	/;i.;@F.;-;cx-;-;_.;/;@w1;11;X1;_0;0;0;NS0;{/;w/;mY/;f.;(0;/0;/;0;)0;1;54;3;2;!2;x1;%1;2;%-3;3;/M3;T4;4;/4;3;|4;4;3;L3;3;3;3;d3;4;L3;rb3;1;91;h0;?0;0;K/;-;
-;c0-;.P-;H-;x-;.;FT-;,;4\-;n,;P+;`#+;x`+;|+;*;*;;P*;ә);(;(;}););e););6*;K*;w*;+;	*;P*;`);x*;of*;a);:);Dh*;@*;*;߅*;N+;h+;~+;+;.b+;2+;+;*;@+;(+;*;!*;Ny*;[*;);_);%|);s);(;`);=(;C9);	(;;}(;S);i);*;sE*;2);[(;&);G(;?(;J,);(;t(;z);Fu);*;*;,*;7+;,;+;+;ө,;+;*;+;#+;+;w+;Q*;"+;+;H*;);V);xN);c(;>(;(;
';&;^';';&;h';&(';';T&;(;O);-P););A);w);(;=(;(;#.(;';qo';2';';I';&;6&;c%;K%;$;$;}$;&$;%;%;%;c%;$;N%;r%;Hd&;x&;J&;)&;r&;&;';';p';7';%;%;%;$;[%;?%;A`&;%;%;%;	%;%;$;$;P%;H$;a#;#;#;3#;$;ޮ#;#;$;$;\$;%;A%;-I%;/u$;i#;!#;,";B";e";";";";";<L#;($;x$;=$;$;";Й#;ڍ#;#;#;?R#;4#;A#;#;#;\$;4%;$;$;$;$;$;?$;#;s#;
#;2";E";y";i ;6 ;;w;;;S;;e;>;q;;Q!;,!;h!;!;!;O_!;h!;
!; ;U|!;P!;!;";@";8";#;#;k#;y#;#;$;`
%;ry%;%;&;N';4q&;y&;M &;%;	%; E$;$;#;Z2#;y`#;=#;#;.$;$$;}$;!;)";=!;!;x!;!;@x!;!; ;s ;Q!;6`!;t!; ;$";g@#;V ;;V;W;;X;:;c;ϧ;ژ;;s;;;j;q@;;TW ;;h;{;;;d;I!;!;S";";J";";";.";";/";W";=";";
A";:#;R";;,";W*";";"; ;> ; ;3;gt;q;;;'; ;f:!;!;v!;V!;B!;|!;";";!;;G";M";";f#;6$;#;$#;J";u@#;";#;(x#;|~";";:!;!;B!;!;!; ;Х ;Y ;} ;!;!;c ;
!;k!;J ; ;; ;b;,;;;d;;;;:;T;;.;h=;!;;;;;N;;U;1$;;SE;];\ ;d;-m;$;;8;;w;>;;H{;Η;;;̧;;;;|;+;;;;K;,r;Q;ʶ;;;Ӛ;%;@;;i[;y;2;}Q;o;-;);W;;;;i;];K;8k;;J;;;S;(&;V;,;;L;M;p2;F;B;Z;;;;&;q;};S#;Xp;r;6;N;Q; ;L;;; u;=W;o;δ;#;;;';X;;;SM;s;;z;;; ;m;;l{;;y;&B;,;\;;%;+;;u;;x;4;Z;^;;+;;Hq;;F;5;}1;;W;k;G;;;O;;);/;Qu;k;-;|;9;c;7$;mS;1;;;;;v;8;1;z;8;*;;9;(;#W;<;;8;/?;;1-;Ĕ;#;Q	;O;L;0;,;g;;;;l;;;;;e;d;t#;YY;j;M-;7;N;g;;[;g;>;;];a;`;T
;&;)
;
;fv
;Ob
;/
;

;0P
;+;
;Se;;m;K;
;D
;S
;
;V	
;	;n	;?	;;;Y;O;;	;;;G;W;J;;;oV;;;	;	;L	;]<
;
;	;F;X
;
;Υ	;;Ђ	;	;^
;
;&;؂;0;s;6;l";;;Q;;>;;;b;r;T;ڒ;(;;k;j;7;;;4;;;;;;;a;;_;;;R;	;];y;(m;Fm;!o
;
;
;(
;ԕ
;[
;<;ث;;;;;L;xu;l
;*;;s;;;{;3;WD;:;x3;G;9;;ݫ;;;~;;<>;];W\;k;Z;;;A;;;1;&;5;2;;d;j;T;W;';5;Tw;z;;`;-y;;;;;;;_;?;_;9;=];;;g;:;`;4;V;;65;o;;=k;E;;;e;j;;=;F;b;́;!&;#;;;Ɠ;R;;wN;L;;;};;{;j;*;\;$t;Xi;:;;];R;V;$;;x;eW;2;CR;;;;1;;;;;;;ڦ;߯; p;=;;;l;;; ;;D; .;i;;o;;;wQ;?;;~;ȃ;;;8;M;&;x);y2;t;!;;;;];U
;;st;[;C;!;,{;A];4;;;;5;q;V;,;;YZ;a);;.;;;;֝;5};; ;e;;A;;;8;:;=;;4;f;;;;|y;;;
;c;;;;;L8;B;1;O;[};Ff;Z};!W;9;;l;
;N
;؉
;(
;C
;Q
;m|	;;Y;	;9	;@
;
;
;(	;U	;w	;	;f	;&	;kc	;;;z;;;;!;;!O;Y;;n;;7;;ܗ;; ;;E;;@;";H;F ;x1;_;9b;;;^;4%;  ;;,;	;:;[;;;9;S;K;;;+;6;d;;;J;+;^;;;;1y;;;;;y;p;~;;;S;TX;;ʢ;
;
J;T;È;;o;;;;;%;=;;;;d;p;w;n;w;;Hl;*;47;(;T;;;;v;3;X ; ;::=j:_::,: ;O ; ;{ ;. ;ڇ ;@ ;F ;r:!0:::ͺ:::t::r5::%i::C:T: :h]:r::;2:::P::Q:(?:`:-`:O:OE:s::::Ի:? ;a: ;:V::e:: ;" ;*: ; ;/ ;Y ; ;d ; ;Eq ;H ;Z ;$ ; ; ;-;t;;;ڞ;=;v#;;
;,;ض;;;;!;-P; ;#;ߓ;;d;;A;;e?;N;;;/;;z;4;M2;m;O;;;;/; ;3];[;Ñ;-;;K;;;;;;;`,;_v;Y;.;];;?;=;c;;s;D;l;.;c;B;;*.;W;x7;;{;*;;u;;;;J;);u;c;;;G;2;;F%;Q;a;; Q; ;g ;;LY;;;;[;;;u ; ;u ;F ; ;(:::":]:*:o:U::<::J:X5::::l::D:':l:s-:l:o::6:w&:J:::]:|:!::\:4::-:}S:(:y:tc:4::e:ܚ:d::l:.:Y:::=:e:Z::zF:z9:I:e:W:):	::::&::r::4:/_:J:E::w:Q:L:q::::-:\M:M::	:%:ڢ:-:HG:::W:}:}:@:m:y:D:T:o:$:::FZ::.:?:o:d::::T::1K:MW:: ::?:s:!: :V:wr:%&:::@::::	:v:6:|:w:@::7::a:M::_: ::$::1:O<:;::t:H}:e:A: :::::4v:{o:	::Y:p:F:E:;:P:::8i::Dd::::nS:0: ":P:R:[r:z:=::F:	:c&:Q:J:J5:
:: : :	b:;:w:c:W:X:4?:(:::::*:=:2::z:i:::M:	:f:0:::`:U:,::!:Z:8&:l:  :1:f:t:::E:v{:AX:3::\:F:`:5:.:=:s:e::Ϋ:Dh:::N:<:F::\7::e5:2:U::S:C:!:1:,K::{:4q:Q:4m:::Y:R-:c::C::S:N:l:c:Ou:H:_:Z:h:΀:[:3(::I3::#::ҙ::f:::]:v::I:#: y:W|::s::O:1:c::,:):::]:Fq:[:}:M:::L:::M:w:67:	::C::::::):h::c[:|2:L::r::ݟ::w%::&::?:}l:':V:=:::"::(:q::):::	[::H::OT:D:f::::=:t:J::k::[:R2::::E:V:d:a@:Ç:ZU::%:a::4:`:
<:S:̟:ƻ:I:?8:oH::/:::?:7:4H:Q:Tf::d::':m:Z:::h:z):m(::W::N::9 ;MB ;,::+ ;:P ; ::T:L:x::\::2E ;߰ ;Ρ ;+ ;JP;B; ;:o*:^ ; ;d ;
 ;c:\:F:wG:Z:::_8 ;3:C:7P:}p::}n:z::%::{:$D:dC::+:h:F:s:ϥ:-:v::<:@:::o:::Q::::m:-:?::}:::IF::::<:.:::rk::S:Mc:l:::6:t+:C:n :
:I:::f:]::	:
:O:{H:B:8~: :: ::S:H::::.:::9:ײ:h:h5::\:m:::ϔ::*:F{:(::r:::%:M:L:DN::3:M:n::T:r::0:@::D: ::&:]::::j::3:m::s:::T:O:o:V:::?:-:
:~:f: :9:U:^::::<:,:lv:{:(:I::QH:L:J:a:O<:y:*::Q:\N:֓::e:r::ez:]:::&:|:$:}:	B::l:-::$:B:,:::::::::o:s::{:i:::7:e?::`7:f:":X::::::7G:':W:$:::<::q:RF:A	:,Y:::$R:o:N:c::':::{::B:<::C:w:!::ܵ:P::q:XH::::7::::@:!:r:jt:p:#::s:z:,:y:a:s"::H:S:f:	::h:V:q:n:[;:o:o:::|<:?:5:M7:_|:::: :2:+::E:c::!:;:z:aC:D:Zh:g::c:m:zi::::[:L::6::::F::*::w::::{@:r:.:::/I:_:^:8:/::J:]:a4: :::n: :x;:4:ԯ:f:1:::
:]:h::	::Do:N::ҩ:{:.:&$:i::-:O:c:S::m:::{:Y:::?a:Wp::1X:?>:p::]>::4:b::Y:a::oq:[[::x:j: :&:l:ɭ::.:qv:%::i:C:T:::m::j:O}::O::4::::ڒ:۾:D::Q:K:K:f:K:e:: ::
C:*::D::::::::5:':,:9:3:}r:4::::::$i:j: :::::(:CH:@8:1:_:D2:
:;::V:M:v:	:*:ex:.:&7::B:g::-:M:E::vt:Mj:K:TE: ::::3:#:nd:A::(:{: ::ɉ::od::ę:+::(:Q:j:o::4:::c:I:	:w:ĥ::ť:Ѻ::#:%z:$:j:z::q%:d:v:2:n:(::v:t::1*:::::S: ?::6::F:q:::}:j:2:l:<l::)0::?:B::v::e:9::::8:::::_:#:_:w:X:::e::s,:p:o:.:q:3:::*:S#::7::4:3::s:MF:Og:1l:6:&:/7:6:::y:::?:_:<>:sV:V:w::m:`l:I:$:1:
X:::|@:A:fH:8|::R
:/I:::{:D:::o:@::^:4z:M:2.:
:D :+::::i::N :A:\:	:HB:,::C::J(:f:::@:+::F:j:3^:d:N:D:_:::CP:I:T:K::@:S::>: B:;:::e_:D:с:::D::<{:7:::: ::::]:n::q:M:,.:D:::::!:B:ʉ::	]:o:::c:R:F:{::,:	::: :t:J:W:Ȇ::::W::):l:`:q:>::d::|`:ݤ:`:4;:)::Ϋ:::)
:::Q	:J::::O:]_:|::":[g:]w:{:::F:2: ::/:r_::}n:O::`:::O::T:w:K:J:Ő:/:::D:ll::!:M::+:2p:::s:Z:i::F:!::Z:=:;:G:	h:H?::S:h:{:%:<i::i:A:#::O:::{::aJ:.:sV:::WF::fY:::v:xX:ݱ::*:M::|:=::Y:!P:(:#W:Z:::=:;#:RV:o:Ԟ:hw:Z:jc:F:s:`:::A:{v:c::::a?: 7:I:X:Ϸ::>:o::::T: :OP::nY:b:ʷ:w:}z::ؕ:*:::.:8:::vO:C::%:f::L::4:/:a:f$:r:::J:f~::l::s:ܛ::8:mT:G::H:mg:O:r:::a::^:k::%P:Q:+:ך:::0:S:d:Q:*::L]:f::(:O::::]:ZO:Q:E:::_:w::/::X5:`::::r!:#O:7:Q:h::V:׿:<:@::}P::::(:z:2:<:o:$:=: :[:Ȕ::{::[: {::ڼ::&:::;:޽::B:o:e::K:d:s6:4:::::r5:N::A:::A:::F:c:f:6:j::j}:2:1:d":B:N:3:H: :/:::ד:H::::Լ:/:,U:9::7:=::墼:b:.:::=:xt:::T:ND:ڹ:/:j:ַ:$::::Ӆ:3n:G:3:CE:L::Wߵ:;
:V::Ft:wR::R:2::	B:T:<:\::β:D=:,\:6::S::N:Z;:[:N::<]:":m:::A:g:̯:8ׯ:,:Z:!:}:7:
:c_:}:ᰯ:::::e:?:y:b:<b:T:&Z:}:::;h::":Hk:q:e:$a:_@:!:<Ϯ::~:{T:4L:: z:&$:软::.: |:} :̯:<:ɯ:zί:!i:ͳ:`*:::Җ::46:::	::(::|;:x:D:H:M:T:|6::2:f:J::1::e::/v:3:#ث::A:X<:=v:	:	::@:ު:":	:Â:Mv:X:::W:ʃ:s::.:2:G:c:C:FS:`:n::&$: :7:zo:S:r:թ::3:ʨ::::I:B:L:l̨:o:z0:_:z:::::F:3):	:h:܁:S::$::O:O:צ::?N::::
::)::t:S:/թ::s :(ʩ::v:T:ũ:::©::ԁ:6:鱩:#ʩ:d:x:֫:W6:R˨::/::͑::d:ݩ:C:oΨ: :=:is:݂:.d::::2:h:::ת::##:7ͪ::J:;:|S:~::܌:ʪ::,x:#o:K:V::G:R::=:F:::x::  :/:Z:Jث:Ԗ::::::x:ѥ:%:叫:,:c٪:![:]<:J:Ɛ::4:ê::8:P:{:+:x:_:!:O|:}::h:@:::*x:v:e:d:ZS:::.Ԩ::M::R
:t:ߦ::z:)::n8:::::2:>:R::o:v:]:c:x9::W:Y:p:f:*:D:R|::7?:i:`::I*::ԥ::-::eȥ:N:3Ǥ::Rw: :g:2:$[::葤:R:F:k:EI:ģ::	d:0':H:t::[:h::س:-K:1G:/:l:c:С:i:&L:Sנ:e:!:I:jo:2ס:X&:f::z:z::g:8:S:rt:HG::::r:::s:٠:ˋ: :h:d:	Y:v:/%::4Q::h:::턟:s&:8::~:-:jL::G:zj:W:q:!U:~:i:j:'p:펝::xu:/:X:o::ӛ::A::~:f|:H:g::	::m:N:#n:J:ݲ:?z::ꛜ:Q8::V:B:^:T$:=::	::aI:O::2ٙ:-:XR::L::ё::.ܚ:ٚ:[:1:@Ә::":6Y:5::淘::::O:Ი:f:.:::p:_:]::p:uR:.::ӛ:n::e:Y:d:S:%:	:d:
:G::::::0:M:Z>:b:⊓:::Ɠ:*K:1:s::F:ҙ::v::Ɠ::d:Sw:vʒ:":
ő:[?:lA:": :R:B::a!:֐:ԉ:::á:sS:::uߐ:j:e:X:K:x:,::ŏ:|:ώ::L1:7׎:]:؎:I:u: :M::::G::3::|:*:Aݎ:z:l:r|:Z:M
:ʏ:H:w:歎:0:P:;:H:::#:M::7:϶:*:o::sH:점:::y~::4`:̏:J:͕:G:4:#:T:Ȼ::T::3:H:p:f:G:::V:2׌:<::L׌:w:#::::::?:p:s\:dZ:#L::]]::'0:x7:r/: ::@:3::/:::H:L:V:8::有:\X:Ԉ:B:m::m:f:L:,:>?:b:r:׆::::::AA:ȏ:d::=:q::6:|w:ƅ::::::ņ:Ɔ:}ˆ:㘆:zh:::ݝ:VƆ:Zt:l:v:,<:ʅ:t:m::{::倅:::3:!::IІ:!:$::,M:$::^y:X:O1::Ɔ:JZ:P:d:s:Q:)#:R:Z:,+::߂:y::A:}:7:K-:DI::_:jd:&-:8:;:3:":$z:Վ::	/::9φ:}:|:?:F::8#:t:Ӈ:G:?:8:{::ۇ:4d:J`:Z::t::T:a:訇:V:{:Ǉ:: ʇ:ɇ:i:c[:"::@:n::Ç:Jև::Vi:o:g:L:A:M:_::A6:5:χ:,:	::::d::F:Ö::G::Ȝ:0݆:&Ć:X:߲::Fm:Y:&:Ҳ:$r:O:虆:D8:\::::Շ::u::&:!	:>:l::ڈ::є:!r:*]:::b:ȃ:܊::(F:%j:ҋ::eY:T:w::UĊ:O::z7::m:!:y:::K:N:-:ډ:̉:!>:0:|ڈ:8:B:Ň:̇:AƇ:Ƈ::z:y::ȇ:ɇ:<::}d:R#:<::':+:Z:C::F::?q:q:i:g-:X:':::2::3:rI:z@:|:⣄::?U::dk::X:: *:3:ς:::$:,l:V:N:/:h:D:݃:ˆ:::Y:::^:-:j:'q:::O::7$:*:ބ:݄:bӄ:: y:5:Ã:Ń::*:a/:5:6:ߙ:f:B:U:]::6: :S:P:Es::+::0G:[;:=::h:"%::):a::9+:G:P:[e:M::璁:ց:j:C,::a:::r9:|:>x: g:3:8I::U\:κ:C :J:Ѡ:Yy:\(:j::`:3:;:A::L:*:LD:s:c:(::<:*:G::ڎ:m:4:MO:_3:3:7ŀ::qP:E:':A(:<:~:o::q:L:[: :W(::F:$:n::A:e:V:܀::6:=~:}:k}:l}:-~:I(::T:S/:.:%:x:s:?:f:~:F:(:::s:P:':z:::<:~:\:~:S~:+~:t(~:8=~:::2:~:ji~:~:::Sf::~:X: W::f:ꎀ:c4:Al:n:fq::s:H:~:U:D:N~:c	:#{::::d:8::m:U:H::$׀::b:ˀ:^ۀ:x:ڰ:::r:,:y:]:Y:_:W::]:є:K߀:::C:S3:::"::c ::(:Ђ:1:Q]:|::o.:l:
 ::H::X:w:C:RZ:L:::V::ց:ۤ::T>::::A:0:Z:%:R:;:}~:~:Q}:z~:}:}:|:}:d}:2|:|:M}:m|:7|:)z:y:y:|y:y:EAy::sy:x:x:u:2'u:Cv:Zw:v:+x:-x:#w:w:?w:eAw:Zv:`v:]v:{v:Aw:]]w:v:v:w:x:[x:Yx:x:(&y:ez:z:y:x:?z:o{:q{:|:R~:]8~:F~:Q}:`z: {:$]|:|:|:{:h3|:L~:~:X~:~:}:
}:T}:o;}:S:~:}:A~:~:.~::~:X~:~:D::X:.:CZ:!:~:΀:ʀ::C::z:{:p:::s:h:ހ:l:d:[::;::LH::v:C::ɫ::\::?B:ۀ:Ɂ:U::_:Հ:j߀:>:6:6::~):6r:֖::^r:pp:,:؃:$w:
p:t:#::ⶀ:Z{::6:ǀ:O:]:	:Ɓ:\:Ɓ::=:<::ˁ::q: :i:'H::?::-:Ӈ:*:d:j::3=:9::Q:::::ׁ:*^:@:8:t:Z:؁::}::uE:+::C:4:=L::O::z:E::Q: :4:?a:y:f:R:M_:!M:1::aT:ŀ:a:]:]:UJ:%:6؀::6n:::5:D:~:\g:=Հ::]:j:T*:iH:aQ:́:w ::::(:/::[:߀::=:>:؀:D:|#:::xB::2P:V:(:`:"<::x:\:7w:E:	::~:ȼ~:::I:i::;:ZE~:TJ~:<|:xp}:;}:on}: {:{:_}:}:h}:G}:]}:	}:}:{|:W|:Ň|: |:Ȑ|:e}:(~:~:cD:1:P:!T:߶: ::[:ȗ:z:m::3:#Z:ʀ::΀:::T:v:j::6:ڀ::z3:A.:`:.:;g::w::Z:|-:T:&$::(::J:h_::Ɓ:P:::<_:e:n:,:@:C:_:Z:ƽ:?ـ:U:"P:Px:=X:t:e:%:LF:m:%6:B|:{:={:{:z{:{:|:T|:{:X{:\z:_{:,}:|:Z9}:|:>}:/P}:\}:&|:	|:S|:LV|:j|:|:s~:x}:\}:}|:}:E|:{p|:{:<{:z:$z::z:{:	z:(y:x:x:x:y:@'y:xgy:y:x:x:2y:e{:*{:L|:o}:}:*~:6f:۠~:|~:z~:=~:~:dm~:b: 2:~:': }:Mr~:~:~:i}:|=}:(|:G|:A-|:j|:h|:|:|:Z{:7o}:|:|:z|:|:%|:|:U{:5{:{:z:G{:z:+z:iy:éw:w:w:|6x:u:.w: !v:Jv: u:u:,@v:6v:u:u:7u:ct:t:2Cv:Qv:u:ot:(u:Au:u:lCv:Zw:N=w:[xw:Jv:v:+u:hu:t:([u:u:?t:t:t:s:_!t:Jr:vr:r:(q:q:p:v^p:|.p:o:,n:n:|n:85m:{m:l:zl:ok:Ak:,k:k:cXk:k:m:l:(wl:;ym:#m:&m:m:vCn:>n:m:m:n:zm: n:cn:(n:Dm:҈n:No:So:Fq:q:zn:sn:3o:n:n:n:n:&m:s?n:Fn:cn:n:im:n:n:un:"o:n:}n:3o:ko:p:Fp:p:+p:zo:!
o:~o:mn:n:No:o:}4q:q:q:\r:jt:HLs:)!t:_t:s:t:2s:s:s:	s:A<s:ms:s:r:r::s:xs:s:s:3q:nq:))q:q:	q:p:Sp:ҡp:p:p:9p:o:in:=Nn:n:Rn:$m:xm:ݘm:m:fOn:(m:An:Q3n:m:?8n:wn:On:Ӈo:o:np:||p:Jp:Wo:]o:0o:#$n:!m:Sm:l:1n:-m:<m:l:̉m:m:em:e[n:ʔm:m:m:l::m:n:l:xl:ӎk:gk:,k:`l:Wk:l:ml:l:2l:dl:m:X_k:i:-i:i:,i:i:h:h:g:Fg:sg:h:h:lh:g:`uf:)f:f:jf:g:]f:-c:Be:e:Xf: f:/'f:e:F^e:e:Fe:e:Ne:vdf:f:o h:jFg:}f:3g:
h:og:rh:6g:.g:}h:ng:Zg:f:lf:Tf:-f:f:f:źe:`d:e:{*e:D'e:}e:lf:,e:g:f:62f:f:e:Vf::jf:Ng: Zg:g:g:g:vf:f:'f:]g:Ch:ng:c:[c:c:xNd:Cc:6@c:}b:na:
b:jc:Zc:fqd:1hd:d:e:Ge:e:Id:bd:d:ʐd:e:e:e:>f:_Nf:Nxf:f:^f:g:gg:hf:f:;Kf:fg:Jg:lh:Qh:h:jh:h:h:g:Rg:sg:1h:g:Ih:Qg:dg:lg:eg:Cg:$g:bg:[f:2f:Mf:sf:
g:}g:Cg:#f:g:f:lf:J8g:g:}g:h:Ph:Qi:h:.vh:Oh:qi:i:i:x3i:i:j:j:sj:j:ui:їi:i:h:h:xg:g:6Ih:g:_g:*<g:g:,Eg:?Pf:e:Sf: f:tg:
Bg:g:vf:@g:Og:g:h:h:h:=;h:Lh:	fi:bi:vj:+j:\i:i:j:
Si:i:(i:i:5j:i:}i:i:Wi:$i:Ti:}`i:Fi:h:=g:Ӟf:
]f:Uf:,f:f:f:^g:h:g:g:Ng:cg:Myg:e:e:d:dd:e:d:,e:hRe:$e:fe:	e:fd:+d:d:%Id:d:,_c:c:#b:hb:.c:Zc:c:͚e:( e:d:ɢc:2c:c:Uc:_c:1b:b:	c:b:c:a:|`:c7b:̀b:ea:Aa:Ya:|^:|^:V]:F^:Y^:x\:\:[:r[:i[:A0[:[:dZ:^[:;Z:Z:\Y:EY:&&Y:iZ:Z:)[:j\:\:(7]:\:z[:3[:*[:s[:M\:_\:-[:mB[:.>\:,\:[:Z:_Y:Z:xEZ::Z:Z:iL[:Z:iZ:cZ:7Y:Z:Z:[Y:X:lY:4Y:Y:Y:;Z:?Z:(Z:3Z:SZ:2\:;\:\:\:4[:[[:Z:Z:Z:e=Z:,>Y:H$Z:zrZ:1\Z:bZ:Z:sZ:![:[:M[:_[:[:[:[:X\:\:,[:ڒ[:Z:[:-[:Y:oY:sbY:SY:Y:MX:IX:7V:"W:<X:]]W:*W:0W:ȏV: \V:U:U:U:U:V:W:W:O.W:W:lX:sW:X:2X:lW:ZX:eY:X:)@Y:(Y:TY:7Y:Y:&Y:LZ:Z[:=\:\:H^:J]:_:F_:V_:^:i_::_:#,`:_:a:8a:`:h`:&9`:_:_:1_:n_:^:]:ۣ]:W]:|\:s7]:^:a]:}^:4^:4_:*_:H_:-_:V_::#`:_:_:r/_:̆_:_:_:M_:i_:ɦ_:`:%`:4Va:n7a:IBa:za:a: a:da:`:|}a:ra:Mb:=a:b:ec:c:7c:Q5d:!d:{7d:n<d:sYd:d:8e:e:}Te:d:Vc:c:c:d:
e:4d:e:0e:d:{"d:Dc:Ed:Qc:7d:md:Qe:e:e:$Hf:)f: g:f:f:}g:g:bg:f:g:g:Ig:Vg:ef:f:a)h:g:g:Og:h:/g:f:1Dg:njg:f:`f:.f:{e:̼e:De:ԩd:c.e:Z(e:fe:d:e:Qe:e:	f:!f:2&f:3^f:Ne:d:d:Be:rd:g:g:Ig:g:Eg:g:g:g:g:g:g:(h::h:Bi:oh:h:h:jh:NTi:yi:N\i:h:Fh:ami:Yi:Fi:xi:!j:Wi:0h:h:j:}j:=j:`j:Xk:`k::k:	m:#l:[l:rl:Kl:m:l:Tl:m:*l:l:Jl:wl:l:.l:Sm:m:m:o:q=o:n:{n:sn:n:rn:o:{n:n: n:z5m:@m:m:
m:=m:s8m:m:tm:*m:m:qen:Xn:Njn:In:]n:*o:/o:In:OIn:n:Vzm: m:m:Un:km:.?m:m:Fm:m:m:n:65o: o:in:o:o:?o:p:Aq:s;q:q:r:xr:ʵr:s:t:5t:lt:[t:Z[t:s:_s:t:t:>u:t:	5u:3-v:Fv:lv:w:Wv:v:)Hw:C
w:v:_0x:;y:>{:W{:{:,|:|:|:Q{::z:3y:y:y:?y:z:ɏ{:|{:|:
|:{:+|:V|:l|:|:;|:|:y|:}:ҫ|:|:j}:*}:S|:&{:{:
K|:{:E{:|:{:H{:a{: 	|:|:|: {:|:<{:	z:lB{:Ҿ{:D|:}:|:{:zz:y:y:sy:y:"y:x:vx:]w:cw:zw:uw:1w:w:1w:ZWw:%ww:,w:vw:Ew:v:Ev:Kw:qw:Mw:x:x:Mw:zv:u::t:Qt:v:^v:/w:D,x:Rx:{x: y:z:y:͗y:y:x:yx:< x:x::x:Mzx:xx:֞x:&x:Qx:y:uy:y:}y:y:Sy:qy:z:;hz:1o|:]{:z:z:ؠ{:{:{:5{:|:o}:}:o}:[)}:
}:Qm|:3|:g|:{:i{:y:N+z:z:&y:y:4y:y:x:ʧx:,Rx:w~x:w:ox: y:x:3x:Գw:&x:w:w:Sw:x:[Fw:#w:Mw:Ĕv:)
v:`u:Qu:ȋu:u:7u:4t:Mt:qt:ét:,`t:%s:t:t:<t:<t:2<t:_r:4(r:&!s:r:ir:r:r:V%s:r:r:)r:ur:Mr:hr:Jr:r:s:;s:Ks:s:s:Ns:s:s:s:s:s:r:ƙr:r: s:6r:r:r:ols:֨s:s:Xs:s:)r:^s:Zs:s:Xs:F$s:r:RBs:r:r:ķr:sr:Ks:ss:Xt::!t:]u:du:Ru:Dv:[w:Zw:Xsw:]x:x:Ly:hy:y:MUy:Nx:x:Nz:	z:jCz:y:y:@y:OSx: x:1x:?w::w:	x:$@x:sw:w:v:Sv:JEv:7v:Vu:rv:v:.y:3y:Qy:x:o#y:/y:y:7x:Wox:dyx:W^y:Ay:_y:wBz:y:by:Ky:]:y:y:y:Rx:x:Ιx:|x:fx: x:x:)x:lw:܇w:Lv:Ev:v:}v:w:v: w:v:v:Ov:ebw:|w:+x:{x:w:6w:{w:ؑx:ox:-y:y:,by:Ry:tx:Tx:w:#x:w:Ow:v:w:v:;v:-w:j$w:2w:Lw:xv:v:u:v:}v:,v:u:u:u:{t:-t:s:5s:r>s:fr:sr:wr:r:@r:'r:p:p:p:p:p:=p:p:/p:no:do:o:p:p:Bp:^p:q:q:Xq:?p:dp:NLp:p:6q:(p:p:p:Nq:Kq:r:4q:Eq: q:Ivq: Vq:q:&'q:p:
r:̷r:Ls:q:;Tr:r:r:Dq:q:q:q:>r:Or:r:$r::r:r:]r:r:hr:r:r:-#s:/Yr:ir:as:q:q:)p:p:sp:p:4_p:p:]o:oo:o:Hco:o:Oo:ao:<o:5p:o:%No:#o:n:
o:%vo:o:o:n:2o:n:n:l:l:il:k:;k:j:j:i:{i:i:3j:j:`tj:βj:wk:Uk:C;k:Mj:?j:j:,j:j:sk:Hl:l:il::l:dk:k:;k:Wj:j:Áj:rj:j:j:hj:k:j:i:i:i:?8i:h:hh:h:Lh:dh:h:h:h:h:h:qi:\i:h:@i:ah:Sh:Rh:S.h:~h:g:f:f:i~f:e:SBf:ћe:e:e:d:,d:Od:c:/d:e:f:&Ng:sf:(f:f:g:g:%h:Lh:kg:rg:4g:f:f:=g:Sg:F+g:f:of:f:g:Jg:f:-e:	e:#e:*e:e:Zf:
f:&g:/h:h:h:g:{7h:
h:Qh:{i:cHi:h:Jh:h:h:i:ji:i:h:i:i:h:lh:mg:g:xg:g:sf:}f:6f:!f:=f:ie: e: d:L6e:ue:d:d:<d:e:e:1e:;$f:f:@f::f:Ɓf:Vg:g:4h:=h:g:Fh:h:g:h:h:?mh:h:]h:h:~h:eg:Qoh:h: h:I3h:@g:gg:TBg:=h:Uh:|g:#h:Sh:h:h:h:lh:g:Ig:g:rf:of:e:hf:#g:f:wf:>e:`?e:
e:>f:3f:Re:E;f:Uf:WXf:f:g:|g:#g:g:Wf:L&f:g:
Ug:g:g:<g:.g:{gg:$g:@7h:h:،h:ri:h:i:Qhi:)i:i:Dh:#h:th:&,h:h:h:Mh:kh:g:([g:]f:
f:SGf:2f:|f:!f:jf:If:Zf:o1f:{e:,f:4f:e:e:Hf:f:f:[f:Vg:Sig:ze: e:sQe:e:EVe:@e:Lg:Dg:Ug:Hg:xg:(h:i:g:Og:sMg:g:Lg:g:f:X4f:ne:_ge:d:d:ѥe:d:e:e:d:d:le:d: kd:Dd:F_c:ac:}Dc:c: c:Lc:Xc:Kc:=c:b:mc:(c:Ԃc::c:8c:Bc:}c:Nc:b:b:1b:Tb:Tb:}Hb: b:b:(c:b:b:7b:b:~c:`d:cd:c:4c:tc:;c:c:c:Hc:c:b:b:Vc:6Rd:e:!d:
|d:d:e:d:ve:%d:ge:je:e:W7e:d:d:)f:f:e:e:e:e:e:3f:iuf:De:Vd:e:e:ONf:Ef:Srf:Fe:e:
f:4g:[h:i:vj:@j:gj:j:i:Ji:΄h:h:=h:h:6j:h%j:j:k:Rk:Il:-l:m:l:l:Zm:_.n:vn:zm:.n:lm:3m:`\m:l:)l:=l:Ok:rj:Qj:j:Sk:,k:qj:Nj:J2k:j:ڄj:j:Lj:i:i:j::2k:)k:Dj:Nj:*`j:V	j:j:vj:j:
aj:]j:Hj:@ej:Wj:j:zk:j:tj:͢j:di:i:Cj:j:j:k:j:[i:Vi:i:j:7j:Tj:;j:/m:5n:Qn:An:3l:l:ܟl:k:6k:r1l:&k:k:k:ck:k:/5l:;l:nl:.fl:k:l:
k:Ak:Hk:cPl:e@l:3[l:l:I9k:k:ܷk:dl:Nl:Vl:l:lIk:ok:Oil:tn:m::m:<m:(l:Wl:m:lm:m:m:wm:ccn:l:Ll:l:k:&k:-m:m:+m:m:n:ln:sn:1n:&[n: 7n:m:8m:im:!m:m:nn::n:ڣn:qn:,}n:xn:Hm:m: m:#n:wm:jm:F:n:dn:
n:Ȩm:Xon:*o:<Xo:Wko:n:nn:n:#n:m:bn:Hm:!m:/m:($n:n:yo:{o:n:EHn:n:Can:n:&n:Rm:!m:3n:m:Q[m:~m:5m:Il:m:MZm:bm:Im:Cim:m:+m:{m:um:<6m:l:&l:k:&Bl:<l:w\k:1j:Faj:j:2j:j:Fj:i:_j:i:ci:{i:=h:Jh:g:g:g:#g:Pg:;f:me:e:e:f:$g:g:wg:wg:g::h:Dh:-g:f:=*f:g:*g: g: g:Nf:f:Af:$qf:If:)f:_f:f:4g:g: j:i:h:Ɯh:h:h:.Mh:Ưh:h::h:h:i:i:i:g:]h:eEh:Ih:Ji:́i:i:i:i::%i:h:h:Øi:Ri:Ri:2i:wi:ni:i:i:Fi:&h:	h:fh:^h:	h:dg:g:g:g:I_h:-h:lh:g:Ȇh:x.h:Gi:i:vi:i:i:!Pj:i:xh:<Ag:g:>h: g:bf:f:g:Jf:f:wf:mf:\f:ʊh::yh:߄h:ih:ݾg:g:Rh:h:[@h:!Hh:(h:g:Fh:__h:Mh:h:i$h:(h:Ph:&h:̪g:88h:4h:?h: Th:g:RFh:3Hh:|4h:Ag:`g:f:e:?1f:z6f:vf:d:OKd:`d:c:c:d:߬d:jd:@d:γd:d:d:e:֕e:e:,f:Sf:	f:ee:V.e:(e:xf:e:
e:fd:wd:e:Le:e:d:e:e:d:d:nd:d:=d:Ȗd:d:;c:;c:vc:ac:tc:\c:@c:ec:d:ʫd:Pd:d:cd:Od:td:ïe:ie:?f: e:Qe:-e:Fd:Nb:b:!c:c:b:`b:Lb:a:a:zb:b:xc:c:d:wc:Dc:xb:mTd:h|d:d:$e:d:d:d:Nc:Kc:b:aTb:ba:a:?a:`:Zb:a:_Cb:b:a:(qa:da:tka:Sa:a:{fb:c:Tc:cb:4b:nb:tla:`:+a:Ja:1a:\>a:`:0a:F`:|!a:ga:\a:`:F`:``:^:'_:n_:_:w_:_:#_:__:o?_:_:x;_:\B_:^:O^:^:c^:W^:{_:̉_:s_:X`:8_:e`:`:C`:m^:_n_:_:(m_:q_:c_:[_:_:&`:_:G`:`:N`:͝`:J`:	=a:a:a:?b:wb:Lb:Ec:'c:4b:Cc:Uc:2c:[b:{b:(b:{Cb:La:a:a:ia:a:a:_a:/a:b:b:#b:{b:qb:#c:b:c:b:zb:b:-b:vb:rc:lc:>d:cd:e:e:Ef:f:Tf:Df:f:f:zf:typescatternameOrdinary importance samplingxȜ@  ?   @  @@  @  @  @  @   A  A   A  0A  @A  PA  `A  pA  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A   B  B  B  B  B  B  B  B   B  $B  (B  ,B  0B  4B  8B  <B  @B  DB  HB  LB  PB  TB  XB  \B  `B  dB  hB  lB  pB  tB  xB  |B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B   C  C  C  C  C  C  C  C  C  	C  
C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C   C  !C  "C  #C  $C  %C  &C  'C  (C  )C  *C  +C  ,C  -C  .C  /C  0C  1C  2C  3C  4C  5C  6C  7C  8C  9C  :C  ;C  <C  =C  >C  ?C  @C  AC  BC  CC  DC  EC  FC  GC  HC  IC  JC  KC  LC  MC  NC  OC  PC  QC  RC  SC  TC  UC  VC  WC  XC  YC  ZC  [C  \C  ]C  ^C  _C  `C  aC  bC  cC  dC  eC  fC  gC  hC  iC  jC  kC  lC  mC  nC  oC  pC  qC  rC  sC  tC  uC  vC  wC  xC  yC  zC  {C  |C  }C  ~C  C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C   D @ D  D  D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  	D @	D 	D 	D  
D @
D 
D 
D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D   D @ D  D  D  !D @!D !D !D  "D @"D "D "D  #D @#D #D #D  $D @$D $D $D  %D @%D %D %D  &D @&D &D &D  'D @'D 'D 'D  (D @(D (D (D  )D @)D )D )D  *D @*D *D *D  +D @+D +D +D  ,D @,D ,D ,D  -D @-D -D -D  .D @.D .D .D  /D @/D /D /D  0D @0D 0D 0D  1D @1D 1D 1D  2D @2D 2D 2D  3D @3D 3D 3D  4D @4D 4D 4D  5D @5D 5D 5D  6D @6D 6D 6D  7D @7D 7D 7D  8D @8D 8D 8D  9D @9D 9D 9D  :D @:D :D :D  ;D @;D ;D ;D  <D @<D <D <D  =D @=D =D =D  >D @>D >D >D  ?D @?D ?D ?D  @D @@D @D @D  AD @AD AD AD  BD @BD BD BD  CD @CD CD CD  DD @DD DD DD  ED @ED ED ED  FD @FD FD FD  GD @GD GD GD  HD @HD HD HD  ID @ID ID ID  JD @JD JD JD  KD @KD KD KD  LD @LD LD LD  MD @MD MD MD  ND @ND ND ND  OD @OD OD OD  PD @PD PD PD  QD @QD QD QD  RD @RD RD RD  SD @SD SD SD  TD @TD TD TD  UD @UD UD UD  VD @VD VD VD  WD @WD WD WD  XD @XD XD XD  YD @YD YD YD  ZD @ZD ZD ZD  [D @[D [D [D  \D @\D \D \D  ]D @]D ]D ]D  ^D @^D ^D ^D  _D @_D _D _D  `D @`D `D `D  aD @aD aD aD  bD @bD bD bD  cD @cD cD cD  dD @dD dD dD  eD @eD eD eD  fD @fD fD fD  gD @gD gD gD  hD @hD hD hD  iD @iD iD iD  jD @jD jD jD  kD @kD kD kD  lD @lD lD lD  mD @mD mD mD  nD @nD nD nD  oD @oD oD oD  pD @pD pD pD  qD @qD qD qD  rD @rD rD rD  sD @sD sD sD  tD @tD tD tD  uD @uD uD uD  vD @vD vD vD  wD @wD wD wD  xD @xD xD xD  yD @yD yD yD  zD @zD zD zD  {D @{D {D {D  |D @|D |D |D  }D @}D }D }D  ~D @~D ~D ~D  D @D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D   E  E   E 0 E @ E P E ` E p E  E  E  E  E  E  E  E  E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  	E 	E  	E 0	E @	E P	E `	E p	E 	E 	E 	E 	E 	E 	E 	E 	E  
E 
E  
E 0
E @
E P
E `
E p
E 
E 
E 
E 
E 
E 
E 
E 
E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E   E  E   E 0 E @ E P E ` E p E  E  E  E  E  E  E  E  E  !E !E  !E 0!E @!E P!E `!E p!E !E !E !E !E !E !E !E !E  "E "E  "E 0"E @"E P"E `"E p"E "E "E "E "E "E "E "E "E  #E #E  #E 0#E @#E P#E `#E p#E #E #E #E #E #E #E #E #E  $E $E  $E 0$E @$E P$E `$E p$E $E $E $E $E $E $E $E $E  %E %E  %E 0%E @%E P%E `%E p%E %E %E %E %E %E %E %E %E  &E &E  &E 0&E @&E P&E `&E p&E &E &E &E &E &E &E &E &E  'E 'E  'E 0'E @'E P'E `'E p'E 'E 'E 'E 'E 'E 'E 'E 'E  (E (E  (E 0(E @(E P(E `(E p(E (E (E (E (E (E (E (E (E  )E )E  )E 0)E @)E P)E `)E p)E )E )E )E )E )E )E )E )E  *E *E  *E 0*E @*E P*E `*E p*E *E *E *E *E *E *E *E *E  +E +E  +E 0+E @+E P+E `+E p+E +E +E +E +E +E +E +E +E  ,E ,E  ,E 0,E @,E P,E `,E p,E ,E ,E ,E ,E ,E ,E ,E ,E  -E -E  -E 0-E @-E P-E `-E p-E -E -E -E -E -E -E -E -E  .E .E  .E 0.E @.E P.E `.E p.E .E .E .E .E .E .E .E .E  /E /E  /E 0/E @/E P/E `/E p/E /E /E /E /E /E /E /E /E  0E 0E  0E 00E @0E P0E `0E p0E 0E 0E 0E 0E 0E 0E 0E 0E  1E 1E  1E 01E @1E P1E `1E p1E 1E 1E 1E 1E 1E 1E 1E 1E  2E 2E  2E 02E @2E P2E `2E p2E 2E 2E 2E 2E 2E 2E 2E 2E  3E 3E  3E 03E @3E P3E `3E p3E 3E 3E 3E 3E 3E 3E 3E 3E  4E 4E  4E 04E @4E P4E `4E p4E 4E 4E 4E 4E 4E 4E 4E 4E  5E 5E  5E 05E @5E P5E `5E p5E 5E 5E 5E 5E 5E 5E 5E 5E  6E 6E  6E 06E @6E P6E `6E p6E 6E 6E 6E 6E 6E 6E 6E 6E  7E 7E  7E 07E @7E P7E `7E p7E 7E 7E 7E 7E 7E 7E 7E 7E  8E 8E  8E 08E @8E P8E `8E p8E 8E 8E 8E 8E 8E 8E 8E 8E  9E 9E  9E 09E @9E P9E `9E p9E 9E 9E 9E 9E 9E 9E 9E 9E  :E :E  :E 0:E @:E P:E `:E p:E :E :E :E :E :E :E :E :E  ;E ;E  ;E 0;E @;E P;E `;E p;E ;E ;E ;E ;E ;E ;E ;E ;E  <E <E  <E 0<E @<E P<E `<E p<E <E <E <E <E <E <E <E <E  =E =E  =E 0=E @=E P=E `=E p=E =E =E =E =E =E =E =E =E  >E >E  >E 0>E @>E P>E `>E p>E >E >E >E >E >E >E >E >E  ?E ?E  ?E 0?E @?E P?E `?E p?E ?E ?E ?E ?E ?E ?E ?E ?E  @E @E  @E 0@E @@E P@E `@E p@E @E @E @E @E @E @E @E @E  AE AE  AE 0AE @AE PAE `AE pAE AE AE AE AE AE AE AE AE  BE BE  BE 0BE @BE PBE `BE pBE BE BE BE BE BE BE BE BE  CE CE  CE 0CE @CE PCE `CE pCE CE CE CE CE CE CE CE CE  DE DE  DE 0DE @DE PDE `DE pDE DE DE DE DE DE DE DE DE  EE EE  EE 0EE @EE PEE `EE pEE EE EE EE EE EE EE EE EE  FE FE  FE 0FE @FE PFE `FE pFE FE FE FE FE FE FE FE FE  GE GE  GE 0GE @GE PGE `GE pGE GE GE GE GE GE GE GE GE  HE HE  HE 0HE @HE PHE `HE pHE HE HE HE HE HE HE HE HE  IE IE  IE 0IE @IE PIE `IE pIE IE IE IE IE IE IE IE IE  JE JE  JE 0JE @JE PJE `JE pJE JE JE JE JE JE JE JE JE  KE KE  KE 0KE @KE PKE `KE pKE KE KE KE KE KE KE KE KE  LE LE  LE 0LE @LE PLE `LE pLE LE LE LE LE LE LE LE LE  ME ME  ME 0ME @ME PME `ME pME ME ME ME ME ME ME ME ME  NE NE  NE 0NE @NE PNE `NE pNE NE NE NE NE NE NE NE NE  OE OE  OE 0OE @OE POE `OE pOE OE OE OE OE OE OE OE OE  PE PE  PE 0PE @PE PPE `PE pPE PE PE PE PE PE PE PE PE  QE QE  QE 0QE @QE PQE `QE pQE QE QE QE QE QE QE QE QE  RE RE  RE 0RE @RE PRE `RE pRE RE RE RE RE RE RE RE RE  SE SE  SE 0SE @SE PSE `SE pSE SE SE SE SE SE SE SE SE  TE TE  TE 0TE @TE PTE `TE pTE TE TE TE TE TE TE TE TE  UE UE  UE 0UE @UE PUE `UE pUE UE UE UE UE UE UE UE UE  VE VE  VE 0VE @VE PVE `VE pVE VE VE VE VE VE VE VE VE  WE WE  WE 0WE @WE PWE `WE pWE WE WE WE WE WE WE WE WE  XE XE  XE 0XE @XE PXE `XE pXE XE XE XE XE XE XE XE XE  YE YE  YE 0YE @YE PYE `YE pYE YE YE YE YE YE YE YE YE  ZE ZE  ZE 0ZE @ZE PZE `ZE pZE ZE ZE ZE ZE ZE ZE ZE ZE  [E [E  [E 0[E @[E P[E `[E p[E [E [E [E [E [E [E [E [E  \E \E  \E 0\E @\E P\E `\E p\E \E \E \E \E \E \E \E \E  ]E ]E  ]E 0]E @]E P]E `]E p]E ]E ]E ]E ]E ]E ]E ]E ]E  ^E ^E  ^E 0^E @^E P^E `^E p^E ^E ^E ^E ^E ^E ^E ^E ^E  _E _E  _E 0_E @_E P_E `_E p_E _E _E _E _E _E _E _E _E  `E `E  `E 0`E @`E P`E ``E p`E `E `E `E `E `E `E `E `E  aE aE  aE 0aE @aE PaE `aE paE aE aE aE aE aE aE aE aE  bE bE  bE 0bE @bE PbE `bE pbE bE bE bE bE bE bE bE bE  cE cE  cE 0cE @cE PcE `cE pcE cE cE cE cE cE cE cE cE  dE dE  dE 0dE @dE PdE `dE pdE dE dE dE dE dE dE dE dE  eE eE  eE 0eE @eE PeE `eE peE eE eE eE eE eE eE eE eE  fE fE  fE 0fE @fE PfE `fE pfE fE fE fE fE fE fE fE fE  gE gE  gE 0gE @gE PgE `gE pgE gE gE gE gE gE gE gE gE  hE hE  hE 0hE @hE PhE `hE phE hE hE hE hE hE hE hE hE  iE iE  iE 0iE @iE PiE `iE piE iE iE iE iE iE iE iE iE  jE jE  jE 0jE @jE PjE `jE pjE jE jE jE jE jE jE jE jE  kE kE  kE 0kE @kE PkE `kE pkE kE kE kE kE kE kE kE kE  lE lE  lE 0lE @lE PlE `lE plE lE lE lE lE lE lE lE lE  mE mE  mE 0mE @mE PmE `mE pmE mE mE mE mE mE mE mE mE  nE nE  nE 0nE @nE PnE `nE pnE nE nE nE nE nE nE nE nE  oE oE  oE 0oE @oE PoE `oE poE oE oE oE oE oE oE oE oE  pE pE  pE 0pE @pE PpE `pE ppE pE pE pE pE pE pE pE pE  qE qE  qE 0qE @qE PqE `qE pqE qE qE qE qE qE qE qE qE  rE rE  rE 0rE @rE PrE `rE prE rE rE rE rE rE rE rE rE  sE sE  sE 0sE @sE PsE `sE psE sE sE sE sE sE sE sE sE  tE tE  tE 0tE @tE PtE `tE ptE tE tE tE tE tE tE tE tE  uE uE  uE 0uE @uE PuE `uE puE uE uE uE uE uE uE uE uE  vE vE  vE 0vE @vE PvE `vE pvE vE vE vE vE vE vE vE vE  wE wE  wE 0wE @wE PwE `wE pwE wE wE wE wE wE wE wE wE  xE xE  xE 0xE @xE PxE `xE pxE xE xE xE xE xE xE xE xE  yE yE  yE 0yE @yE PyE `yE pyE yE yE yE yE yE yE yE yE  zE zE  zE 0zE @zE PzE `zE pzE zE zE zE zE zE zE zE zE  {E {E  {E 0{E @{E P{E `{E p{E {E {E {E {E {E {E {E {E  |E |E  |E 0|E @|E P|E `|E p|E |E |E |E |E |E |E |E |E  }E }E  }E 0}E @}E P}E `}E p}E }E }E }E }E }E }E }E }E  ~E ~E  ~E 0~E @~E P~E `~E p~E ~E ~E ~E ~E ~E ~E ~E ~E  E E  E 0E @E PE `E pE E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȀE ЀE ؀E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȁE ЁE ؁E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȂE ЂE ؂E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȃE ЃE ؃E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȄE ЄE ؄E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȅE ЅE ؅E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȆE ІE ؆E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȇE ЇE ؇E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȈE ЈE ؈E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȉE ЉE ؉E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȊE ЊE ؊E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȋE ЋE ؋E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȌE ЌE ،E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȍE ЍE ؍E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȎE ЎE ؎E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȏE ЏE ؏E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȐE АE ؐE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȑE БE ؑE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȒE ВE ؒE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȓE ГE ؓE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȔE ДE ؔE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȕE ЕE ؕE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȖE ЖE ؖE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȗE ЗE ؗE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȘE ИE ؘE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E șE ЙE ؙE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȚE КE ؚE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E țE ЛE ؛E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȜE МE ؜E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȝE НE ؝E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȞE ОE ؞E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȟE ПE ؟E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȠE РE ؠE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȡE СE ءE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȢE ТE آE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȣE УE أE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȤE ФE ؤE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȥE ХE إE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȦE ЦE ئE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȧE ЧE اE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȨE ШE بE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȩE ЩE ةE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȪE ЪE تE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȫE ЫE ثE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȬE ЬE جE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȭE ЭE حE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȮE ЮE خE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȯE ЯE دE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȰE аE ذE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȱE бE رE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȲE вE زE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȳE гE سE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȴE дE شE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȵE еE صE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȶE жE ضE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȷE зE طE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȸE иE ظE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȹE йE عE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȺE кE غE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȻE лE ػE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȼE мE ؼE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȽE нE ؽE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȾE оE ؾE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȿE пE ؿE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E   F  F  F  F  F  F  F  F   F $ F ( F , F 0 F 4 F 8 F < F @ F D F H F L F P F T F X F \ F ` F d F h F l F p F t F x F | F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  	F 	F 	F 	F 	F 	F 	F 	F  	F $	F (	F ,	F 0	F 4	F 8	F <	F @	F D	F H	F L	F P	F T	F X	F \	F `	F d	F h	F l	F p	F t	F x	F |	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F  
F 
F 
F 
F 
F 
F 
F 
F  
F $
F (
F ,
F 0
F 4
F 8
F <
F @
F D
F H
F L
F P
F T
F X
F \
F `
F d
F h
F l
F p
F t
F x
F |
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @FyȜ@>3[g>>f>N>r>M>j:>^?h>>|>?>>nK>>>~>qY>ٳ>?>>> J>Ƈ>>">>4>O>>J>p>܂>UƂ>x>2q>:at>}Ml> 1g>zd>v!V>FH>3F>R?>8E>&M>.O>H>A"F>E>6RA>|nF>=>j<>=>*[C>m;>Am9>5>M6>ƀ1>r+>(>&>S%>$%>>>>>>,>ʑ>Y>>`>*>x>H=a=^==@=.=x=M==y===i==$=w==_==;3=vй=[)==߁=:=#=A=;==G='=*@=ר=E<=Y==\==)==="=!U=	=۲=!=h=8==A=A==J=/=4=ƽ==ݺ====q=R===en=K=Aw=v=ɛu=s=aWr=m=r=Hm=s=D,s=s=uv=:s=)i=d3h=ce=c=1c=[yb=Ec=1c=db=:`\=tX=*_W=oN=G=HL=G=B=;C=A=t A=A={@=1jA=,?=ԙ:=J:=<=:=D35=R8=;9=(:=$5=1=1=]n-=.\/=@=?=a9=8=8=e0=D.=3l-=q,/=)0=j.=).=/=v2=1=-=ù+=)=(=C(=&=S'=y$==c= =!="=/"=!=@M!=%=<"==}==e=R=z=S=d=g===8=1==]1=R
==-====-===9=XA=l =|_=/=8* =1={ ==:N =z =$1<<\<;{<,<<V<l<(<.N<8x<x4<sc<iY<q<v<<D:<<<hA<<3<A@<`<<=f<Y<<V<K<B<l<4h<,<u<s!<h<<<<9<\<n<,
<<s<y<ON<L<j<<<o<z<AP<x4<n<<}<<<4<#<<4<@<Tz<r<ױ<<J<<<'<<<8<7<m<_< <4<N<<d<<l<l<M<<<<
c<<Ԛ<<O<</<<1<s<&<N<$<W< <<O<<E<c<l<<̫<SC<*<r<<<E<)<۶<s<<<[<1<s<<Nݨ<Þ<t<۩<D<{A<y<q=<<Q<æ<|<ҥ<T<z&<ନ<2̨<RJ<ף<<E<Ԡ<,ǡ<ƣ< <I<d_<<E<;<ԛ<<؟<G4<k<,<l)<ݓ<໔<O<<U<
<"<T<M	<ӏ<%T<{6<͍<Ռ<I<&Ҏ<d<R<<r<i<N<΀<<ی<q<< <č<z<8<<_<=<SM<$<r<m<<\<<m<2<;<m݅<M<<x<J<v<N<TF<!݇<3Έ<W<؇<S<y<4<B<W<H<<u<Z<i<<cB<Ԣ<v<X<<כ<Ԅ<t<υ<g</<A݆<ĥ<	<M<u&<	<%ŉ<< A<JǊ<2<vu</<u-< <Ǵ<]<M<O݈<.<`?<Ƈ<܍<ņ<<W<j<6<a<< M<<!<@߁<s<C<m<<~><n<x<M<<<}<<P}</<,<dȀ<C<+<<.<b|<x<y<Tv<rv<&v<-u<v<2t<w<v<Իq<ko<ro<m<k<'l<`Hg<{d<gg</@g<f<f<be<e<hf<d<ce<zd<Za<S]`< `<^<?]<\<Z<fX<U<XT<tgU<=sT<-U<=P<5Q<N<w9M<_O<R<S<SV<Y<Z<[<:Z<2fZ<fwY</Y<N9W<W<rX<:Y<HV<T<OV<6cW<`xT<V<HU<wV<U<SW<&X<W)U<R<R<SS<Q<5Q<Q<#P<EM<P<gQ<mS<D%T<T<S<QT<AS<R<CiS<T<U<3T<J=[<{Y<ɵY<Y<dY<n7W< V<V<|U<hV<U<CW<MW<U<aU<,T<{R<TR<Q<7P<Q<rlQ<(S<*T<4T<S<nQ<cP<CQ<O<?M<DN<4N<M<zN<tM<ON<M<`M<oM<)K<jK<L<M<,K<%qL<2I<@J<XI<D<1D<D<B<B<`
D<A<LD<D<B<cNC<!|C<mB<D<G<F<fE<F<MF<D<.C<w{B<LA<abB<r@<%C<A]B<xB<?A<A<@<?<?<@<EA<!?<V><{=<=<=<=<_><W><L><?<_?<Ly?<n?<><S=<-@<<@<L=<d<<|;<q=<@<<-><);<A=<(><><o><EJ><xs<<<<&;<8<}8<-8<7<S7<F7<7<-6<75</M5<4<G4<X4<42<;2<NJ2<W2<e2<C2<j0<,2<2<2<2</3<1/3<J[2<%2<f0<\0<2<1<&3<<2<o2<2<Ev1</<I0<0<2<nJ1<u.<xL.<k.<j-<f+<v*<#+<F'*<(e*</Z)<N(<\!*<*<;(<)<<+<,<E+<,,<,<8-<-<E+<Q)<=*< *<ئ*<c+<a+<+<E*<|*<(-<--<;.<A:/<#/<.<},<&@*<(<+<|+<X+<]*<V)<eY+<*<+<	+<*<=+<+<`,<*c,< -<p-<O-<.<+<$+<+<+<n-<-<B0<_/<ؾ0<,<\,<,<I2.<j.<xU0< .<1<r1<54<34<L4<%2<N^1<0</<_.<,<*<+<%*<|*<Φ*<+<]+<+< +<O+<+<++<:"+<*<(<j%*<	)<d)<|(<O'<R&<&<('<mv(<]M&<?&<&<{$<l$<#<#<$<f#<-$<N%<R&<:&<r&<C(<a>(<<'<)'<'<@E'<Q\'<9'<&<%<?$<!%<O$<f.$<N$<P$<$<#<U#<Dm#<n"<"<#<j#<*"<"<"<!<<<_{<<<U <ϖ <|!<:"<!<~x"<1"<%"<!<K <<h <Y.!<% <lM<]<;<`<N<\<<z<<<<è</<<;<7<<<s<<X8<4<<c<!<z0<C"<_D<<l<_<Q<<J<sy<ܩ<L<<< <J<h!<<n<X;<<<ë<{K<VO<N<}<=4<<mO<<I<<C<gn<J<X<X<<<<
<A~	<<6?<?<Z<t<<<sI<5	<K	<V	<'<a<V<X
<J
<;j	<2
<'
<	<g	<)
<:A
<p	<_	<v	<O	<	<<c<V<<L<<<]<Xt<<L<K<sz<><< <y<<<_0<|a<o<<;Y;;; <wv;A;;< <	<<<~<M<EP</<B<<</<߷<F<?<:<<1<<l<`<<<<< <<V<5<[<p<<< <& <7.<<<,<D<X<:P<<<m<<Mv</k<<<u<<<ׯ<<<P<v><<<Ls<8<< <t5<Y<I<=p<9T<h<"<<ۤ<<@<H<&<2<g<r<a`<S<<T!<|<y<A<,<<<+<<s<\<SM<ÿ <Y<K;;;;; h;?;Ƅ;H*;;;;;T;aU;Jp;z;w;r;@;D;;;d0;F;	;;t;=;Cb;\;;1;Ù;r?;;;;.;;Y;7w;;;;44;@;is;.;;d3;x;/>;ϧ;*;;V
;#;4;Z;m;}5;;;<3;2;;;;t3;:;R];;;;E;;x;;;I;&*;
;;k;R;s@;7E;(;;$i;h/;D;\;4Q;ں;=(;z;;;1;d;;;V4;;;&;-;q;;;ɡ;o;lF;v;O;;;;&H;3+;h?;c;;;Y;S;;6;;y; ;;5;;;;#;7;>;;6;;c*;T;;<f;y;>;Ͷ;;Z;;[;ȑ;;Y;f;;a;;;ą;-;H;30;;;m;X;;[];;; ;;G;z;|6;;;t9;9;;;u;_;4;;ۏ;7J;Z;$;1;;";;K;|;7;Z;z;n;;;P;$;;с;&;; 8;;C;8k;?M;6;;;i(;f;d;k;;Q;J;j;:h;;;;M	;;J;;Ok;;;;;o;d;;͗;V; ;?;t;;;֋;w;h;;=;[;;M5;ZV;=;n.;;V;M;;\`;H;L;:8;;; ;);1);;;;t;4;r;h;S;z;-;a<;tE;;;;R;;i; ;;T;8T;(;;f;Ϋ;M;/;4;;tL;t5;};n;;4;8;;:\;x;;iV;,S; ;a;; ;;=;w;;m;r;l;#;;;4;r;z;;!_;t;T ;X;m;D;;;v;h;m';	;;;(;;1;;;Fk;;e;;d;t;:;r;;z;);;s;J";A;;5;h;@;];;Xf;#;);|;;;; ;H;*;X;`H;q;;.;;;`;`;m;m;;;r;A;;;;W;u;P;;;I7;o;;;n;J1;;$;;J;ʢ;=i;;N^;W;!Y;;u;;;@h;\f;;;
;e;;;;۾;;㋼;;A;$;N;ߺ;㢹;H;֐;j;G;;k;';S;AN;p;p; ;Hۼ;;ad;Y;;B;;s&;x;;7;\;;;;;;#;/	;;=;;Q;?;(!;;љ;r;ڼ;<g;\;;cv;;;d;&;;6;;;ܩ;AV;;#U;;;c;;m;q;;r=;;;II;Z;;,;,;˾;F;;D;_Z;߻;c;H;;C;;Su;;;;ݺ;1;m;?;;;׏;ܾ;ö;;޶;@;/;qI;zp;/;7޳;cU;;Zy;̱; F;]3;e۰;
;l|;r; T;Ɲ;;Mѯ;;.;;7;L/;T];	;R;V;7>;n;;7;47;E;;C; ;	F;_;w;qp;x;ɢ;;;s;(E;e	;1;Ư;m;ܯ;ڰ;+;;;w;;}};N;_;;;ɭ;(;D3;g;l;RZ;R;;a;;˫;$W;;;S;; /;y;	;;1;4;;#;Ы; 1;;i;m;v˪;/;`;2٪;ի;F,;};ˬ;Ҭ;G;X;;֫;Z;;լ;_; ;ð;؛;
d;;(;1;س;v{;;dX;|;?;;;;	;1;);;1;;;©;9;;俪;;8;;W!; ;;;;<;;iZ;_>;ܯ;;I̯;^;Q;ju;;d;j߭;j5;׬;6;;ѫ;,;6;_;[;W; ;;-|;I;z,;(;%;L;;ة;;:q;P;;J;W;;f;';;;p;;X;);\n;~;xI;;ѩ;;
;姨;m;§;j;DЦ;!;w;C-;*;d;;̥;!;-/;;;$ߥ;;۴;.;&;憦;;rT;;;u;SϤ;]y;F;27;;*;@i;5;;s٢;6B;r;&;;;h;;佡;;;ޡ;v;,V;h;ѣ;U;Ȍ;;N;;/;]~;5;ʐ;i;
;3;-;k$;Q;;X;;F;;;zE;.;;;';3;;s/;2";?;p};f;U;/f;;u;/9;;ac;љ;ߙ;E=;㷙;;;;;X;;mל;;;ݞ;JR;;M;0;zv;ԝ;?՝;;[Ԟ;,t;;s|;;<a;r;);;;;hm;$b;;X;d;;!I;|;M;ޜ;-;;ߜ;#W;Ӝ;x;';;k; ;ɼ;S;Ɯ;;;;;/`;6;!;ڼ;;;;-w;^;*;4;䶝;/@;o;s;;];ܫ;m;q;l;a;;
;\;ޙ;͙;M;;7;v;Sl;2;v;q;s;;ɔ;3;;s;T;ш;С;xi;;;[T;_;;=;;";ƚ;ǃ;#;32;o';ﱘ;W;;t;@|;;;;;6; 
;;,;;ꬖ;;v;͖;Ζ;s;Ol;6N;-;;;ǖ;h;D;;|{;ⵕ;];+;Ĕ;t6;F;;;3;_;@;T;w;;;œ;5;eO;d;Fs;;-Ó;;ؔ;Ô;;a/;;Kf;&;;S;;(;U;H;;;f;W;PY;;/;̓;(ޓ;c;:;!;Δ;;][;(;<;ϗ;;~;h;&;";_;;W;;E;;Ǎ;;ь;;D;e;;S;i+;l;!z;<;;J;e';o8;A;;c;q;l;Y;q=;g;5b;0	;F;я;$s;f;;;J;o6;ޑ;(`;4;;;;*;;b;Q;q;9;;J֒;N;^;&;O;;Խ;4;S;˿;?R;_;;E;&;(;];s;wH;\E;6;g6;&͚;m;;W;; ;;;Q;;J;;F;;i;ՙ;xØ;;oɗ;cn;a;u!;;;&;ڙ;;J;rP;;;#;M+;མ;e~;{;c;a;q;z;#;Y;D2;k;;z;~;>];E;#;2;';E;W;;R;s;
;;Ln;N;F;q;;Җ;';T>;F;;;dn;u;;.4;
;ʗ;×;]ė;y;:;;:;J;v;E<;@;Ԩ;⍕;O;k;.;|Ȕ;;sɔ;;l;<;~;Y*;&;6;K;;M;
;b;;Ed;sx;Ƒ;)A;쁑;>E;4;А;;1F;y;ғ;[;;L<;9";}+;;٬;H;6R;ϓ;C;Xϒ;!;Y;X1;~;5;Y;`;~;N;F;;a;!;;;;;;"p;;V;Ւ;;Ǒ;A;jS;;H;ُ;Ng;x;;T;O;;;;v;;Zˍ;;&;v;FĎ;կ;;
;?;;k;[;;"I;f/;Ҍ;;m;};;Vi;;ċ;6;ve;U;L;O;};;$;;Ή;o;J;;Ê;d;;C;;q;\;ΰ;⎊;*;;;;ob;7;R;窋;;m;;tߌ; ;y;t;;;c;R;;^;;z;o;ԋ;9;7v;Y;ʌ;U;6;5S;;;\&;m;;0;S;;mݍ;_ٍ;:;C;;};Ό;B;,;U;܋;=;g;?;ϋ;=;׋;D;F;#;;f;ڔ;;Q،;a;l@;W;*u;ǌ;;;р;ڕ;e;w;E;C;ڍ;D;!;;,C;;q;;;$;~;`;;;;1;\;#Ǌ;mƊ;;;;;';;t!;{;Q;H;;M;x;;;̳;0;w;;d;Z;;@;x;f;FA;)8;DJ;ߊ; L;;;;U;y;f;&;U;.P;QB;;};;vy;~;l;T1;;d8;:!;;b߉;_;};;@;z;B;;;;;׶;6; y;;-;;L;";;H;,!;;	;y;}ʊ;;-[;]ƈ;S;G?;bC;;3;q;Έ;8Ĉ;;;;&;ڈ;?;;e;e;~;(';6;);
;H;t;;/;,;Ј;C;;Ѭ;!;%A;;Ն;&;x;;;9;h;PՃ;8;x;;D;;˄;;;΄;;̈́;|;8;(;t;e;;b;Cb;=;[;9;F;?>;OH;$Ɂ;dE;_ ;m;f;p;l;;;&;k;+;M~;h;ւ;N9;; ق;P;;v:;@;3;7;ZՀ;Jp;N;?;a;ʁ;;;¦;~;;߮;
@;EɁ;s;΂;K;;;;Ă;\0;;<;|);#;;t;_;;W;;X;1;};U{;_{;|;|;Gz;=z;d[{;={;2n|;|;
|;|;{;|;};|;
};ft};};};|;1+};M|;y;<y;x;Xw;Zw;mv;w;w;.x;R`v; u;Dt;Qt;u;u;{u;vet;u;vt;-*t;s;Zt;%t; u;{u;u;@u;Eu;_u;؆v;tv;v;|v;u;ju;7u;mv;Ӫu;nt;{t;Ds;D?s;Es;r;q;nq;;r;r;:q;4|q;,r;;q;q;Dp;o@o;ISo;o;{o;p;cp;Zo;o;[n;Lo;0o;o;C/p;tqo;o;o;
o;ϑo;;o;_o;n;Om;m;{l;l;rrk;j;wj;Iak;hj;$h;g;vg;dWg;&\g;~f;}je;d;@c;c;b;vb;Db;a;a;a;.a;Qa;za;)`;;`;t`;`;t7b;9b;Rb;^b;b;Sb;
b;b;|(a;@b;b;b;wb;b;{[b;fa`;n:_;_;V^;^;];B];];-^;]; \;
\;U_;-^;n^;c6^;_^;$^;1];:];u];h\;}\;#];^;x];	];v];j];v\;\;|\;r\;3[;\;l\;/\;e\;x\;xn\;&g\;T}[;Z;Z;MZ;pZ;CY;Y;_Z;MZ;Z;7Z; \;n\;;\;j\;|g\;?\;M];>\;\;[;\ \;ZZ;Y;2Z;4[;`Z;2[;1[;J[;M\;:];\<\;];#Q^;^;C^;o^;];-];J^;ex];$v_;eM_;=Z^;];^;TM^;:^;^;m_;)_;];y];[;(8\;19\;#\;M\;\;|g\;\;=]\;];b];mJ^;?L^;@^;@	_;{'_;J_;o`;p_;`;	V`;o^;,^;c^;];Z\;];3];\];O];v\;\;QF\;i\;q\;\;f];v[;K[;aq[;E\;[;\\;\;U];\;&J\;\;\;1\;\;X\;\;_\;a\;)[;![;Z;Z;X;X;lX;X;|0Y;`9X;W;\W;{X;XX;W;)X;MX;
X;!-Y;ƿY;pZ;VX;ziX;4W;SW;&X;IY;ZX;W;4X;8
X;V;?0V;LT;.eT;e3T;tS;XT;W*T;-S;S;T;T;{T;1T;_S;ƄQ;C R;.Q;xP;EfP;XO;$P;qO;NO;P;N^O;7O;P;Q;/Q;aQ;Q;)P;\WQ;vhP;O;9O;!O;}O;NN;O;,N;zO;tO;O;1N;i'N;
N;zN;O;#O;O;<O;%N;`N;:DN;RO;N;7M;L;AwL;1L;;N;0N;N;wN;xN;N;~N;O;O;KO;O;
UP;\P;_Q;,Q;,R;WO;O;P;Q;زP;7Q;P;Q;P;O;O;mO;sP;Q;Q;Q;P;(P;OO;>P;O;JO;] O;vO;O;O;yO;N;N;D"N;"N;'N;rM;2M;MfM;1M;L;qAL;L;7L;%L;K;LK;K;
L;K;XNK;K;J;J;EJ;$J;J;2J;qK;K;K;uK;{K;L;M;M;WN;N;M;M;tN;N;N; O;xO;IO;mO;[O;Z*N;M;3N;M;2M;M;YN;zM;QN;c7M;L;L;L;?L;L;L;L;L;xM;N;M;7M; N;N;tN;#QM;L;3L;QML;íK;#K;K;^L;IK;TL;K;J;$J;J;I;#I;igI;J;-I;J;NJ;ʿJ;EJ;$wH;TH;UH;J;z9I;%I;I;I;IMJ;TeK;)L;L;WL;]L;K;K;_K;`qK;RL;OL;a L;L;
 L;tK;EL;\L;L;L;^L;K;K;	}K;&K;K;hM;L;M;L;-wL;dL;mL;0K;xK;#J;.J;7I;>I;=J;eRJ;J;wK;e#L;$6K;J;:K;TK;tK;]OM;M;mJ;3J;jJ;{sJ;tJ;]K;VPK;	L;M;qL;(L;K;/L;fL;M;x5M;#M;0M;M;JM;M;M;|M;YN;zN;QO;øO; O;iFL;LL;DL;K;K;7L;L;۸M;)M;N;P;*P;O;"O;;O;P;ιO;sP;O;sO;CN;xN;N;O P;!Q;؏P;{P;LaO;DO;fN;N;M;s\M;~L;$L;L;)K;}L;7<L;mK;Z*J;2J;eI;@J;I;lJ;DJ;|J;ߥL;L;͢K;;L;lK;K;L;JL;K;L;L;WK;V'L;yJ;UJ;DJ; WJ;I;J;MI;H;H;4I;H~H;G;H;gH;8gH;F;]RF;G;F;sF;F;G;NF;;E;.@F;@E;:xD;C;1C;7C;`\D;27E;D;2D;D;C;rC;@C;SC;)C;EC; B;B;E;6vF;	F;G;CF;G;PH;$I;H;<wH;vH;qqH;oH;HH;H;{EI;I;XdH;OG;)G;%H;$H;JH;0H;jH;H;qH;G;G;JH;H;[H;.H;E;3D;E;_D;E;.E;\C;C;B;wyA;zB;B;MB;|B;C;2WC;TC;hoD;h,E;s~E;E;E;F;F;!F;oF;ZF;HF;$F;E; F;}sF;F;IE;.E;E;D;HE;E;D;XE;ME; E;!E;YE;3D;,D; C;6B;B;}B;@;@?;|?;>;>;S>;}>;"?;H2?;=;(=;=;h=;>;E>;\?;[>;.>;*(>;t>;i>;s}?;>;>;=;(=;S=;=;K=;u=;<;<;{=;g=;z=;=;dm>;R@>;>;w=;\/=;=;v>;	4?;/|?;>>;f>;&?;@;?;h?;e?;@;-@;?;*@;q@;2L@; y@;a?;A;xA;@;@;ƌ@;@;g?;x?;@?;-w>;!>;q	>;>;>;ɼ=;,=;z$=;*<; =;N<;(=;!/=;<;=;<;.;;h;;v:; :;:;:;#;;;;mP;;<;M;;`;;F<;%=;v!>;|p>;>;s>;=;%:?;]d?;?;73>;<; <;%P<;;;Ҙ;;r:;S:;:;N:;9;y9;8;S8;^8;W8;N9;
8;}8;8;	8;A8;8;08;_8;/S8;;9;D-9;c9;HF:;9;;Su;;t;;;;6<;(,<;Z;;fC;;};;;;:;:;9;w9;{9;q9;8;
8;8;O8;{8;9;]8;7;M7;\6;66;96;B6;È6;6;6;6;6;7;`5;6;f5;L35;Z4;I4;3;)4;l4;n4;2;3;s3;3;sY2;J2;81;N:2;-2;p2;2;R2;1;1;i1;\1;'2;Fe1;2;12;i2;*h2;-{2;|g2;2;w2;2;}2;2;:2;3;!2;W2;$g2;6p2;2;x1;1;1;
1;v1;`1;0;u0;0;=b1;=A1;'1; 1;0;50; 0;?^1;F1;f}1;1;1;0;/0;0;61;x1;n_1;H]2; 2;1;-2; 2;1;%1;P0;0;'1;v0;J/;/;D.;/;.;}.;š.;ca.;&/;t-;#6-;i,;,;M,;e-;-;
.;-;,;Q,;,;4,;+;[,;+;+;+;]+;H+;`Z+;C+;z+;?+;l*;);O););&);e);v);3);`(;(;O(;(;(;xs(;Sy(;l(;&';';V';E';̞&;ֵ&;C';';O%;3&;AH&;]%;&;#;';-J&;&;&;&;?&;';&;&;&;3Q&;';	%;$;&;r';(;OZ(;';';Ϸ';'; ';s';i';?(;(;#^(;';';4';';t5';&;\&;G&;x&;&;`"&;Z&;&;(';2';}';,(;f';h);(;);	(;(;);)+);*);2);.); );F(;)(;\';&3(;&&;v&;.p&;m&;%&;';n&;&;E';/';t';b';z&;&;y&;I*&;[&;N&;&; &;^&;tJ&;}&;;[&;&;W&;8&;(;j[(;u(;G(; $););h';@(;n(;(;܍(;d0(;';\D(;x(;f8(;P(;M(;
(;C(;(;(;R(;R9(;';V';h9(;k(;8);&);z);t);v);o); );S(;2';@';N';==';';@';:';';X(;W';';I&;F2';';&;';:(;g(;0(;ad';O';;(;q(;c(;HQ(;y(;P(;7(;(;/); (;f(;,(;y);2m););););@);7*;F*;*;\*;{*;@2*;6*;*;+;i+;@+;$+;Ϭ*;*;+;+;*;#+;*;);ڽ);&*;%););y*;N*;*;
);); (;D;(;';';(;tq(;(;|(;i(;(;););););M););Ӷ););`*;*;L*;*;?!);(;(;!);m);܎););););-q););W);L);iD);(;););(;0);-);\););`();M);););y);M); |);E(;M);(;);3(;rZ);-9);1);l~(;(;1(;(;0);%););xR););S););.*;(;(;(;(;R);1);T@););
);(;(;(;(;m7););Ts*;*;ܐ*;);G);(;4(;@{(;P(;5(;T&(;B(;';';z';q';)';%';Ͳ';T;(;)(;';a';&;~&;V%;$;L%;Ȯ$;T%;.%;*%;%;l%;1k&;I&;%;6&;X&;&;';c&;]';E&;&;!&;t"';&;m%;${%;u$;B$;&#;Fx#;<#;#;"#;#;Vu#; #;/$;/#;$;r$;3r$;L$;$;";";;#;tk#;L";y";Pv";}t";J";I";[";";C";#;##;#;m#;d#;#;\S$;#;
*$;O#;#;\#;71$;$;7($;	$;$;%;j$;$;$;%;Y%;L%;0%;$;$;C|$;$;r$;|$;$;K$;\$;l]$;B$;Fs$;#;#;Z#;";";8";";_";R";T";!;ܡ!;:!;!;bz!;{!;J";e#;W#;ɳ#;6o#;m#;#;#;C#;%;.%;/%;M%;%;$;n$;%;j$;hM%;Hw%;@&;X&;2&;&;&;&;&;&;ܱ&;`M&;H%;%;)&;F&;&%;,&;w';f&;#&;&;&; U';';=';U';';	l(;';#';^);(;ʡ(;ݝ(;';R';2(;'(;4(;FX(;';(;!(;&(;);(;(;$);(;(;(;#););(; (;';';(; ';t';';v&;&;VL&;%;%;6%;.%;';';N';S_';[(;ו(;(;(;(;IE(;);*;w*;);p);%);qh););D(;΀(;(;(;)(;m(;';>(;';';!';\';';1(;=(;[(;(;&);ɳ);
);ɝ);T);8*;);]);7*;);8););Y);(;(;(;)(;';';L(;(;C(;,e(;i(;s);););t);h);$2);J(;r(;h6(;(;(;J(;';';&';4';i3';&;%;%;1?&;I%;%;$;"%;X%;QU$;#;ep$;e$;[$;7u$;m$;-C$;؞#;#;#;Sj#;#;$;%$;a#$;#;#;O$$;#;k#;>T#;#;#;#; #;";#;";z#;}$;s$;$;#;Dl#;k#;#;r?$; $;{$;29$;%#;#;#;$;$;L$;x$;$;F$;)$;#;ݿ";#;";#;F!#;#;";";";";`#;ܸ#;e#;$#;M";";q[#;t5#;)#;}";C";C";!;!;(m!;U!;>!;=l!;4!;fY!; ;b ;0 ;8 ;^ ;h ;N ;D ;;s;&^;;K;;;];;;4;D;!;KU;C8;X";i;u;J;B;A;8;L;v;;
;];xG;;;1;_;;}b;I/;q;]*;;;;;>;Lt;w;f;]l;&;I0;?q;-;/;;;;;&;#7;x;;n;z;;;u;;s;\;;3;XS;+;'7;Y;;\;p;4;&l;_;m;q/;4V;";>$;P;;;;0;w;;3;G;!;;;_;6;T;L*;z;<7;;s*;7;;w; ;N;A;;;;C;;*;C;;>;;i;2;X;;O	;	o;;F;# ;Qa;\;q;G; ;j;&;+;o;R;;Y;M;;;;d;
Q;=;g;;I;9;M;;D;;;;_;;$>;je;6;#;H;;Z;v;$t;;;߫;y;z;1;F;8;~t;v;;0; \;;D;s;y;zj;	m;d;H<;;@;C;;4;7;Q
;-=;;,;;;3H;];;
;e;q;y;3;;MK;b;
 ;;Ҕ;p;;6;);>;;G;@/;d;l,;;E;Г;;;S;';';; ;L;v^;w};%;z;T;A;1;;@o;C;V;R;";;3;Y;;`;);B;W;;);C;";;K;;4;;0;Df;SL;j;^>;R;|;;~;Ъ;;Ͳ;;;;;
;^;Ya;=;;3;;;M;fE;>k;V;_B;;;ۍ;4;f$;	;Ju;y;2;,;Ox;~;;;[;,A;h;;3U;;G;; ;;!;p;';M;";@;;;;;5;Lm;a&;;z};X;;R;;H;[;
;-;$; 7;;*-;;;;;<q;;˦;-;C;uN;;;i;;Y ;#h;;:3;;|;xQ;dI;;b;Q;M>;:j;;9;w;6@;;;;S;;D;;;|T;u;n;-;#l;;@;o;;];;;);];p;;R;Y;;;;<;;r.;=;c;;;;;D.;w;;	i;6u;S;D!;6;t;;π;;;;k;x;;;M;;;;ȯ;; r;; ;;2;";];Y;;w;ݨ;.;Ȅ;b>;j;"];
0;@7;!;;;
;3;>;պ;;;@;I;0;;;t; ;;$;7; ;h;;/;/";<;;+;L;T;;;;4;;;p;gK;;;f;s;:;t;a;Iw;ދ;k;;;=;*;;+;;};LN;S;\;O;;_;s;ݒ;t;E;!;9;h;;;;;@;;;8;Ӣ;];#;;;;N;t;m;`;e;;;;;;4;;>;;qk;;;y;;C;;+;~;YW;^J;\;P;\;;P;c;E;8X;DT;K;Z;;';VM;vs;8
;x;	';?;Y;;;;2;A;;h;;O<;D;Q;;;u;U;;;4;;;;#;p;r;;S;;*;;"";S;O;;{L;u;;;;;m;
s;m;4;V;;W;6;;[;3;L;0;R;*v;B;;H;g;j;#j;Kh;;m;r;;Y;t;ԝ;/-;;;{;;;M;Q;;~;<;0;;;;;";\W;S;w;e;M;2;;;j
;;LN;z;9;;P;;;";-;7;3;V;o;;;;3\;}8;;;;;Q;J;>;<;*;M;;.; ;;,;+;;;h;L;!;(=; ,;;0;X0;T;*K;A;X^;
;	;9n	;a,	;K;5;l;h;j^;.;B;;s;*m;X;ܾ;w;L;c;W;:;F;;x;9h;;;^;;S;;J;T;;0;4;D;;;1;;;o;ߐ;+;!;;y;va;;x;;;h;";";V;;A;;;A;h;V;-;7;5;J;;;p;;g;_];-L;;Y;ܛ;8;	;;pf;;@;;6;;:E;pK;.;;u;03;#;;Y;;6;;3;1;;;;T;.;m#;;;u;;(;;)d;u;m;-;;]1;8{;m;M;4g;P!;,;W;V;F;*;;-;";S;L;;;x;܅;ef;;O;D;;À;;v;#;;(:;Si;;;;؟;y;;&2;O;Z;L7;Z;;;;D;0;c;;\;r;~;po;[=;$(;;Q;;-;;;;V;;;|;;,;;;J;<;;r;;d;;;;h;Q;8;X;(;x;;;/;;&;;f;;;;7;L;z;ٝ;j;;;v;;G;m;!;
+; ;W ;ߵ ;o ; ;{ ;8;;;~o;Ҋ;q;Bo;=M;خ;Q;;_;=;l;;;;!;_+;;;;;;F; ; ;';S;/;9;;t;;J;;7;ƅ;<;;j;;K; ;% ;\ ;_ ; ;9 ;l9 ;' ;%:N:::::s:,m ; ;C ;b ;2 ;; ; ;b;=	;( ;ͯ ; ;6D:G:;:Z::r:&u:x::w:\::?u:Sp:R:ZF:I:::L::Qp:-:W=::Ҥ:::w:=:L:_:J:Aw::1:::$:2:':::::K:o:h:::T%:oa:\":ť:-::"::!:@:cx::@::w::?:::F:̴:V::1:D:Q:):2:2^:3:A::/:d:":>:͉:::"::::7:.8:c: ::<P::::A:w:Q[:
::ZQ::u:::: B::E::9:::=:&:
::::&f:β::Ͼ::r::}:D0::Ɇ:::::H: :W:L$:::w:v:{:{::9:g::::c:r\:#}:8:0::::4:<::i:_:::o:,: ::s:W::ܖ::: :::::Si:`:V:g:/u:I:I::Dh:-:N4:(::|S:z:x::,:::	\::5::_:oR::n:{M:::G:.;:(j::2::jW:y:I:4:ej:&:}H::RL:B:m2:#=::#:f:ج:|:::|q:)::M:!:::mT::3:e:s::m:cQ:vJ::,:L:&:j:e:::::2;:m:a:g::#:O::::	:T:::):H-:::v:;:T:G:TN::9:oT:::`::E::ά:::|{:s:6:+:::!:M:q::::R:F:a:::-:qm:d:v:F':w_::e::S:f0:F::::39:Z:R:}:7::}:# :c::(:Fo:ő:?g:::ɍ:4:&:.7:Q::::f:nH::o:o:(:::m:7:S:A>::::::,:}:/:#q:O^::(=:M::m::m:::::<:Q2:e:%	:k:Ӂ:j:::#:a:V::`:%::J::<:F:%::h::o:A:}: ::q:y:W:h:R::ϑ::Ӯ:E{:: :::I~:(:*:1::Z:x:!U::=a:	::m$:vL:V:4:::h::nU:m::X:d]:Vw:T:1:):`:u::;:
:::a:my:":a:w:v::/:::h::[:Ȫ:4:]::::*:;:є::x::	H:'::h :*:::)::C:c:X:	:;:r:V:H::X:':2::::.:e,:b:C:JA:Z::X:	:::g:U::):&:F:x:?:<:s:V::}:{:@:i:sm:ۈ:7`:q::nK: ::$:c::V:a::E::::ݭ: :e:F:!W:J:%::~:M:|::::n:m*:):q: j:.:!E:E4:ײ:H:4::::n1::8:HV:ZR::#:r:f:q: :x:O:,:a::q:f:::NH:[:m:!:P:w3::2y:{:P:(: ::ty:,:d:80:D::}:dT::i:z3:Z}:ئ:`1:\:N:!:::Ҏ:z:z::#:<::::k::$:t<::::ύ:m:O:J&:j::@\::::O:K:::r:\:Q::]:::ȳ:m::m:m:u::,:&:(:>:iP:{:d:v:CI::a:CF:r:::
V::x::C::w::^:J:ۧ:/::4:1:
::t:n:H::;:<:wY:::H5::}<:q:::t:}R:c^:s ::<r::A:;:1:6M:Z:خ:::p:::%:u::::ܜ::*~:T:j:V:$::I:!::C:-:Z::Z:0:e:2:d[:::X:_u::wn:V:e:7H:v::=:j:d:A:P:#:X:O:::V::2/:::q	:X!::.:o?:#Y:hJ:*:':::z:m::[::E: :4V:&::*:J:_!:: =:(Y:K:aZ::[:!:| ::::
j:!:U:\:i=:%:x:<:t-:h:Q:8::t:/e:`:L::Z:K:::N:o:X::::G:u::/:H;:@:::::::r:,:-::S::W:l:[:::S::x#:O:[A:o:;:::Q:ܵ::J:cz:& :N:~:6P: :V9:`:a::4:::::1:R:]:}::}k:<:3:::F:2l:T:v,:z:/::VP::d:i:::E:-D:.::dz:+:;:Fv::X::C:: w::\H:_:	::A:%:s:L:::?9::,:h:s:J::w:Y:N::C::h:::+:e:n:I:ݶ:::N:V:,:ڷ:w::L:I:?:2::N4:::S:":$:A]:":::I::{:w:::C&:::u:G:":=:8:$:ɷ:Z:	:*:: ]:.l::::i:?:::]:0:4:;:u:.:R:j:	:HL:ݵ:lg:]::/::w:i4:i3::":\::;E:p:h:&::S::4:M::J:A::dW::-+:Җ::):D::M:}9::O:+:-:7=::@j:A::N:Xp:@:M:J::n:A:$:D:c:[}:	::#:Ȍ:H:S:4:\::::::::_:-:2D:h::T::@: :&:#::Z::::X:NN::x :r::@:j:V:&T:n:::::}::A:4=::5:?:::z:`::j:vr:)::(:Q:::::*::z:::aN:):\:D::Ly::=:N^:&:V:_W::+::*::::ݷ::8:l6::\:H::N::::*:P:!t:S:::M:i::G::4::#:E:@:I::A:A :g:{Q:\:_:::|:&:!:\::~::::.:L:U:P:b:/:{:;:I6::Z::?:u:Ӊ:(J::h:;:::O:Ή:m::"::	::V:::?:):@E::w:S::O`:+:7::s:W:^::F:3i::Xv::$:f:[:::,8::::6::U:nl:!p::::::%{:L::. :o:F:Z:D:[::::H&::ӻ::b:o-: ::::ڰ:?::O:]:::::i:j:t:f':*:Y::S::S::<:щ:@C:ç::I:~:dF:˽::Խ::
:w::W:*O:n::s: ǽ:O:֞:M::::H:::ο::::
#::j:U:::	:I::::c:::m`:;C::: :::۾::!¾:ʿ:x:::_g:@6:::(:ț::AW:rD:^:=::\:;:::_:{:::OP:ǿ:<}:|j::[::V:p:c:[::*:F:s:H:x	:WD:l:S:x3:9::n:q:%::x:I<:M:$::{!:Q:|=::f:}U:x:I:::+:*::s:`e::T
:$::W:sM:-:: (:o1:R:#::::(:/:Y:::a:%::}J:n:͡:k:)L:]t:j$:Q:::*:	::(h:X:\::$#:eU:?:m: :-~:m::,::ҷ:):RY:`:h:`:4:::::m:ߐ:T::EW:)=:y:_d:_:@:::;:l:Rg::::#::N:iS:;c:c:H::Ql:;8:&:c::.::::::K:~::8:H:H: :q:y: :::)U::<:,::7::l:,X:::y::=`::JG::Ê::W:fs:4S:f::1:R:
:V::/:3::::k:<:: :S:*: +:	:a :	:::I:2:	:v::>:Z::~::s:]::f-:D::=::}:J::[%::1$:Q: :ȳ:h:(:P::@::w:D:ʏ:V:::C::L:L:6:D:LO:u:lL::::D:,-:j ::::?::*:=7:f:::::X:nf:::|E:q:f:F:7B::(:M߿:l:::m:<:p::::Q:So:=:&:L:HT:v:\:H::G:ɾ:a:	:4Ӿ::nv:O:::x:!:::qY:7:ᴼ:::::::3ӻ:I߻:ܻ::<:V:o:::`͹::::q:$:M::Ek:: :Q!:O
:Ư:,:T::Ǹ:N:	:ٷ:::8::i::O:z:H:j:-
:?,:{:W:z:Ĭ:|:::&::: ':
O:2::mȵ::s:ص:Aյ:R_:):,<:X:t:X:ɲ:۵:mߵ:.е::j::[:?C:ͷ:Ʒ:::ׁ::Mĸ:j~:W}:cm::\:7ݸ:1:5:l:#͸:":R:25:8:5:|Y:::::߸:::Vd:B:SL:::Q:E:A:߆:A:Z@:T:з:ѷ:[*:::Ÿ:D:::2d:Z::|ĸ:v2:{:%::ø::3:?͸:jĸ:A::^::B:::e::j:僸:]_:&:eg:C:::: ::ڹ:::3:3ʶ:闶:eζ:f9:Xx:e4:H:ܰ:
:t:m:<m:.:nߵ:ڵ:m:FB::*::h: :6:´:h:::V4:ϵ::o:(:#:@ɴ:,<:캴:Z::8:迳:޳:
0:-:::::::t::U:ݳ: ::::C\:Z.:N::::":::?:	۲:R :j!:;:!:ԩ::7:v:D::3:s:\:r::Ű::	::4::@::Z:D:˰::԰::O::\:O::n^::Zo:
:q:::wh::qѰ:b:::,:[:
n::6:i$:@U:_%:\::ɝ:3::o:AO:
:%l:<:Ӂ:ذ::z:;:կ::
:/:X֯::IB::):::Ư:X:g:@&:jƮ:\: c:': :n$:W::::::|:A::ב::#:::I:.#::::Ů:m:/Q::::'::8:լ: ::qe:o::O֬:D:ʒ:vO:::ʭ:(::4:oȮ:3:46:&::\:::N:o:~:a::<:):\:W:s:ǰ:困:::1:-::p::-:::m:E:.\:)a:H::9:::f=:ѯ::::`::J:{=:=::-:8:㰯:'::::`M:Ѱ:::A:::9::::9:jҮ:::P:::]:ɮ:e:<:Fh:y:: :Mۮ:D:7:a::$:;Ƭ:X:sI:V:6:j:T:":S:he:;:R:Y:.e:v۬::	ˬ:|W:_:`:X:):ţ:"::|:::::k:
::E:Z:Hj:7::<:]:	f::@:x:$|:O:H:r:i:?8:v:QѪ:©::ͩ::©:n*:V6:+:\W:7:5:fe:N::z:E:`:df:o\:!:̪:؋:	:z:(:Ƭ:\:<:x:::t:::ܨ:_:`::{:a¨:1:]:ʇ:O:::ب:$::MK:7 :WϨ::l:}I::1:b:::ڿ::C:::::A:*:Ƨ:ŧ::&:d:䬧:x :l:B:3::T:::̦:(:]ۦ:\:IҦ:cX:ե:Ⱥ:t::ե::
::p:t::\::<:S:Ԥ::49:r:|:̥::::id:wJ:I4:f:¤:D:m:k:&::Z:Τ:ѭ:R`:,:7פ:::(:$::`:Ő:S|:H:Ǥ:`:O::	:$U:3O:\:::u:!::㝣:e::::Ӣ:.:|:;::|:6::R:G::*o:!%::Eӥ:%:6W:#:::Ņ:%8::	ݤ::Xޤ:::פ::-:%J::-:C:,:G::җ:A٥::J3::,:S,:z:3A: :o:ֺ:ʺ::/:s::F֥:ץ:٥:C:G: ?:O-:F:6:xH:^:G:¤:W:t:L::.f:E::L:z}:i:Z:%:nz:У:s::::}:: :a:::::[	:::Ԣ:آ:ݢ:뻢:j:/:ڡ::0:/:w_:-':6:::::ꂡ:h:_C:1:Vf:Y5:@:ˡ::::w:sj:c:F:Y:ˡ:3::׈:x:f$:2:/:cN:>/:::	::Ο:c:Ž::::
:F:a:V:Lؠ:X::^:h:g:o:}:ȍ::`D:@T:::㎡:_:6{:#h:[y:]r:ϴ::Z:E:Ң:::vK::f:Rǡ:$ݡ:]:H:מ::::r:s::Gh::d::?9:T@:K:B:CҠ:{D::?::ꆠ:W:*:u:ɟ::':ן:p::d:f::`::::5:ޟ::X0:m՟:Ӂ:X:aB:K(::v::3:؞:ޞ::O:::DŞ:::eԞ:қ:B::Q:&::M:@:ܔ:):Ai:T:j:뜞:UX:Lx::D:y:U:K:S:ԝ:b::e:::*:#:ʝ::ܞ:::-:Ν:O:n::]ם:6:):M::::Z::Q:::N:˝:c::a:::쉞:ӱ::::f::R8::[:L:֟:἟:'ʟ:@:G:^:s::h::˟:ؠ:à::::K:d:Р::?E:9:٠:`:q:(:":Pa:f:m:-F:::E:n:ny:s:ܟ:::|Ɵ:П:M_:ԍ:ؠ:ɠ:F:jg:y:9:1_::):Ţ:il::3:Y:D(:7:B::Ф:8q:=:}::闤:?<:?:G::;:Ҥ:ߤ::w:?:::Aդ:::Ȥ:դ:c@:
:M:̤:ߤ::{:s:賓:::Aa:#2:L~:N::|:}]::ۚ::OM:1:W:	:Q:A:nt:):(::*::::-A:=:*&: :ԏ:4q:(:lC:~:J:A:i:):1::&}:6V::j::]ޤ:Τ:p:Ԥ:: ::˥::I::w:W: A:q:N:]:Ʃ:RӤ:M::@:w=:l":@:8.:t::3:P:3:C:c::L:yƣ:ޢ:J:::Cݡ::::ɡ:ZS:X:R:̡::g:Z:젢:/:::L:#:~::A:::cʠ:z/::X:'::_:+ :z:-:D:fݡ:M:ϡ:(:::C:.:o:::Ɖ::2:?:#C::D::?:Dz:3:!%:E:ס::g:Vѡ:o:Ӝ:>:T:.[:::e!:M:Ԡ:ن:;:IG:::+9:\p:6:::7؟:::⡟:J::X::D:u:sA:d:6Q:::rN:&::ޝ:!:fq:@::::S:%	:7:::pݜ:Ȝ: :Ԝ:/}:k::K:%:cj:ٛ::N:)ޛ::?::<:N:%:!:G:S:g:::O::J::|>::+::":>:TϜ:1 :::Ԝ:_:<֜:5:::ak::1͞:
:ɬ:j:턞:\:::':ߝ:۝:J:nu:j:Ȟ::}:|:v::j::|:'4::%ٜ:Ĝ:P:"::̑:C:ߜ::{:P՜::ڜ:
: :\::,U:: ::n:՜:s:|ޛ:=::}:tɛ:[:):˛:<::y:":؛::A:lF:r:hɛ::xӛ:ě:|:}::ś:w::s:噛:ў:ᶛ:\:ܛ:қ:Q{:8 :Oՙ:(͙:~:2:ہ:::ڡ::ݘ:M:ژ:ͣ:Q:i:d::He:=:[:i:y:::Rq:9:`:G:<:	:Q7:4:A:d:H:q:k::2::CV::-:|4::`: :g::㜖:~::ƣ:ܖ:1:C:":Ȼ::&:ח:M:$ٗ::O:::滗:|::k:ō:K::::Iԕ:::ٕ:R:;:ޔ:^::ו:v:O:6:Q:::>::x:z:D:ld::d:0:gb:h:f:2,:A:.:7::Jڗ:ꂗ:ŗ::ȗ:::b:G::C::sK:q1:
:dA:ۖ:͖:::	:[:Z6:n:r:QK::~ϗ:D::@:.:=:zL:Շ:P:b:*:D:I::6T:]:A:!:&::=:6̗::hQ:u:Y::+:E:z::ח:Q::: :җ:::|q::$:::0:Tn:L`:̀:4:S:x*:*4: ::u:|:sΗ:1]::5r::ۖ:ږ::;8:+:ڂ:J:}:k::ߗ:W:]:	:3::x:@Ɩ:::z:\:z:Ͳ:٨:l:ܬ:ڋ:L:J:yX::C:::/:o:ၖ::JH::j:O::z:h:k::>Ֆ::C::ޖ:6:|::~2:R::?N:͖: :j:J:[:wM::+:Վ:s[:d8:x::~:tK::[:gN:c::::+:K:?:~Q:S:i:Q:{:&::!:Z:P4::ֹ:ӕ:n:p:Y:İ:T:3:|$:4:w:v:G:>:*Ȗ::4v::?:*::8:`::?:۳:':Җ:\::::/::c:J:$/::Q:u;:sJ:L:?(:(:(r:h:
:@:h:$:__:j:`:F:Ř:^:p'::T:F.:b :pi:j:C::0:2?:$!:?8:P:M:V*:\::Z::z:Ι:	::}:ԙ:::9:::}:\:^F:u:M:Ǟ:ԙ:~:r:0:XE:ψ:ښ:(:s:f:I'::r:4::X::::r:&0:-:R5:%':y):R::×::-L:S:K՗:Xɗ:Eҗ:i::¸:ڡ:×:a:`+::Cݖ:H::#v:J˗:Y::m:=͗:: +:CK::LN:4P:H:!:_::/(::7:B:9q:z:AƘ::(G:v:Y5:#:|:::v:K:L:6O:yn:qؘ:Oݘ:õ:::c:hn:l:|X::>k:y:)::*:{ǖ:::ڧ::a:k:t:F:5:s#:)::}:;::뺖:I4:Zg::ݕ:(:ū:CŔ:L:z::ߔ:Q:::n,:E:ߔ::錔:V:ؔ:\::`:Q:C::X:C:::C:K:@ޓ:|::Г:^:@:gT:ٚ:m:r::Γ:ē:$:$r:*g:m:|x:-:):Zp:I:Ó::œ:&:+: %::nX:~:d:?t:_::F:5 :H::l:/ܒ::-:8E:<:~/:G
:::d:{:k*:):::ؑ:::aܒ:l:ؒ::"Ē::~Α:n:&:J:Hr::^::Dؐ:*::̐:А:ِ:O:::::::|:g:::0:n:^::ԑ:x:#:ΐ:Ӝ:=::
:oq:Vg:0K:0:Ŏ::1e:B::T:s::=:%:#:Ϋ:}:o:}l:X:&\:BC:h:8:_ƌ:l:݌::$::,":]l:y:S::H:9:S:6΍:U:̣::(b:q:+::1:p:
?:Q:x:gL:7::/:C:V:̒:{:A:ی:j:}:?:1:4:ٌ:8ߌ:n:^: :K:::ی:\0::Ì:X::v::΍:駍:|:GN:Ό:5A:$':N
:6:,:%:;؋:~::::vJ::ʋ:՜:h:z::I:M:H:ߊ:::Ď:Ō:ǌ::;:~	:>g::dҍ:聍::X:v:~P:X^:z:.:9:&:=:@:t*::aE::G:s:::m6:::::Z&:O!:#:::b:̌:w:t::ޝ::U:n::ٌ:J:e:::ǋ::͋:w:ˌ::騌::m:w:::
: :::`e:cY:]:|D::2':1:7:L:C:&:
::x:1:Q::h:S::bW:h:6:^b::t{:N:I:t:f{:*:Da:y:M?: =::: u:m::HC::T::1:":Eڈ:ʈ::q:	T:sP:F:]:Ї:: :4::::8ņ:w::m;:3::}':Q:G::K:#:8P:q:R:F::O:::Ȇ:ӆ:$:::T|:2:V:U%: ::m`:j::(:ֶ::̇:::Ԯ:@:|:Շ:x:r:N:h:|::Ӈ::)::c:+::v:9&:h:G҇:E:%:g :L:j:亇:Ç:Ň:::1:lC::O:]:׈:롈:ja:E:+d:(W:X:::r:@:}:8:c*:Q:M:sv:$O:S:[:D:y:3:D):
:ш:zو:1:dȈ:؈:::0:߈::So:;:O:љ::u :f:q;:#:ȡ::::Ƈ:mf:S:2$:t(:!?:::ԣ:C::h:-:].:r!:;:}:w:nׇ::$:,:::>:#3:_':Dk::s::::n2:V#:*:ˈ:+i:w:o:c:]::~:7:H:u:::J::F::9:4::z:`:i:!:0k:K:F7:Q:f:5:!:6:3X:l::{::qφ:::#:T:ڝ:X:]P::ֱ:85:::Ow:~:n::|u:n4:@:{:u:xq:::d:ƅ:-Ʌ::Y:Xc:::ք:::K:::ƃ:::F :+:F:W:=::/:׃:Ʊ:8:Z::~:::K:|1:8v:::؃::2ۄ::啄:Ը:w:]:q/::/:p:߄:}:s:]\:jW:j:QA:X::5:Ń:ἃ:ƃ: :у:\҃:5:σ::i:!m:Z:r:*:::::::F:f:#N:t^:D5:a::y:::
:V::+:҂::::\ł::S:6:Z:d::":!:typescatternameWeighted importance samplingxȜ@  ?   @  @@  @  @  @  @   A  A   A  0A  @A  PA  `A  pA  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A   B  B  B  B  B  B  B  B   B  $B  (B  ,B  0B  4B  8B  <B  @B  DB  HB  LB  PB  TB  XB  \B  `B  dB  hB  lB  pB  tB  xB  |B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B   C  C  C  C  C  C  C  C  C  	C  
C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C   C  !C  "C  #C  $C  %C  &C  'C  (C  )C  *C  +C  ,C  -C  .C  /C  0C  1C  2C  3C  4C  5C  6C  7C  8C  9C  :C  ;C  <C  =C  >C  ?C  @C  AC  BC  CC  DC  EC  FC  GC  HC  IC  JC  KC  LC  MC  NC  OC  PC  QC  RC  SC  TC  UC  VC  WC  XC  YC  ZC  [C  \C  ]C  ^C  _C  `C  aC  bC  cC  dC  eC  fC  gC  hC  iC  jC  kC  lC  mC  nC  oC  pC  qC  rC  sC  tC  uC  vC  wC  xC  yC  zC  {C  |C  }C  ~C  C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C  C C   D @ D  D  D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  	D @	D 	D 	D  
D @
D 
D 
D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D  D @D D D   D @ D  D  D  !D @!D !D !D  "D @"D "D "D  #D @#D #D #D  $D @$D $D $D  %D @%D %D %D  &D @&D &D &D  'D @'D 'D 'D  (D @(D (D (D  )D @)D )D )D  *D @*D *D *D  +D @+D +D +D  ,D @,D ,D ,D  -D @-D -D -D  .D @.D .D .D  /D @/D /D /D  0D @0D 0D 0D  1D @1D 1D 1D  2D @2D 2D 2D  3D @3D 3D 3D  4D @4D 4D 4D  5D @5D 5D 5D  6D @6D 6D 6D  7D @7D 7D 7D  8D @8D 8D 8D  9D @9D 9D 9D  :D @:D :D :D  ;D @;D ;D ;D  <D @<D <D <D  =D @=D =D =D  >D @>D >D >D  ?D @?D ?D ?D  @D @@D @D @D  AD @AD AD AD  BD @BD BD BD  CD @CD CD CD  DD @DD DD DD  ED @ED ED ED  FD @FD FD FD  GD @GD GD GD  HD @HD HD HD  ID @ID ID ID  JD @JD JD JD  KD @KD KD KD  LD @LD LD LD  MD @MD MD MD  ND @ND ND ND  OD @OD OD OD  PD @PD PD PD  QD @QD QD QD  RD @RD RD RD  SD @SD SD SD  TD @TD TD TD  UD @UD UD UD  VD @VD VD VD  WD @WD WD WD  XD @XD XD XD  YD @YD YD YD  ZD @ZD ZD ZD  [D @[D [D [D  \D @\D \D \D  ]D @]D ]D ]D  ^D @^D ^D ^D  _D @_D _D _D  `D @`D `D `D  aD @aD aD aD  bD @bD bD bD  cD @cD cD cD  dD @dD dD dD  eD @eD eD eD  fD @fD fD fD  gD @gD gD gD  hD @hD hD hD  iD @iD iD iD  jD @jD jD jD  kD @kD kD kD  lD @lD lD lD  mD @mD mD mD  nD @nD nD nD  oD @oD oD oD  pD @pD pD pD  qD @qD qD qD  rD @rD rD rD  sD @sD sD sD  tD @tD tD tD  uD @uD uD uD  vD @vD vD vD  wD @wD wD wD  xD @xD xD xD  yD @yD yD yD  zD @zD zD zD  {D @{D {D {D  |D @|D |D |D  }D @}D }D }D  ~D @~D ~D ~D  D @D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D  D  D @D `D D D D D   E  E   E 0 E @ E P E ` E p E  E  E  E  E  E  E  E  E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  	E 	E  	E 0	E @	E P	E `	E p	E 	E 	E 	E 	E 	E 	E 	E 	E  
E 
E  
E 0
E @
E P
E `
E p
E 
E 
E 
E 
E 
E 
E 
E 
E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E  E E  E 0E @E PE `E pE E E E E E E E E   E  E   E 0 E @ E P E ` E p E  E  E  E  E  E  E  E  E  !E !E  !E 0!E @!E P!E `!E p!E !E !E !E !E !E !E !E !E  "E "E  "E 0"E @"E P"E `"E p"E "E "E "E "E "E "E "E "E  #E #E  #E 0#E @#E P#E `#E p#E #E #E #E #E #E #E #E #E  $E $E  $E 0$E @$E P$E `$E p$E $E $E $E $E $E $E $E $E  %E %E  %E 0%E @%E P%E `%E p%E %E %E %E %E %E %E %E %E  &E &E  &E 0&E @&E P&E `&E p&E &E &E &E &E &E &E &E &E  'E 'E  'E 0'E @'E P'E `'E p'E 'E 'E 'E 'E 'E 'E 'E 'E  (E (E  (E 0(E @(E P(E `(E p(E (E (E (E (E (E (E (E (E  )E )E  )E 0)E @)E P)E `)E p)E )E )E )E )E )E )E )E )E  *E *E  *E 0*E @*E P*E `*E p*E *E *E *E *E *E *E *E *E  +E +E  +E 0+E @+E P+E `+E p+E +E +E +E +E +E +E +E +E  ,E ,E  ,E 0,E @,E P,E `,E p,E ,E ,E ,E ,E ,E ,E ,E ,E  -E -E  -E 0-E @-E P-E `-E p-E -E -E -E -E -E -E -E -E  .E .E  .E 0.E @.E P.E `.E p.E .E .E .E .E .E .E .E .E  /E /E  /E 0/E @/E P/E `/E p/E /E /E /E /E /E /E /E /E  0E 0E  0E 00E @0E P0E `0E p0E 0E 0E 0E 0E 0E 0E 0E 0E  1E 1E  1E 01E @1E P1E `1E p1E 1E 1E 1E 1E 1E 1E 1E 1E  2E 2E  2E 02E @2E P2E `2E p2E 2E 2E 2E 2E 2E 2E 2E 2E  3E 3E  3E 03E @3E P3E `3E p3E 3E 3E 3E 3E 3E 3E 3E 3E  4E 4E  4E 04E @4E P4E `4E p4E 4E 4E 4E 4E 4E 4E 4E 4E  5E 5E  5E 05E @5E P5E `5E p5E 5E 5E 5E 5E 5E 5E 5E 5E  6E 6E  6E 06E @6E P6E `6E p6E 6E 6E 6E 6E 6E 6E 6E 6E  7E 7E  7E 07E @7E P7E `7E p7E 7E 7E 7E 7E 7E 7E 7E 7E  8E 8E  8E 08E @8E P8E `8E p8E 8E 8E 8E 8E 8E 8E 8E 8E  9E 9E  9E 09E @9E P9E `9E p9E 9E 9E 9E 9E 9E 9E 9E 9E  :E :E  :E 0:E @:E P:E `:E p:E :E :E :E :E :E :E :E :E  ;E ;E  ;E 0;E @;E P;E `;E p;E ;E ;E ;E ;E ;E ;E ;E ;E  <E <E  <E 0<E @<E P<E `<E p<E <E <E <E <E <E <E <E <E  =E =E  =E 0=E @=E P=E `=E p=E =E =E =E =E =E =E =E =E  >E >E  >E 0>E @>E P>E `>E p>E >E >E >E >E >E >E >E >E  ?E ?E  ?E 0?E @?E P?E `?E p?E ?E ?E ?E ?E ?E ?E ?E ?E  @E @E  @E 0@E @@E P@E `@E p@E @E @E @E @E @E @E @E @E  AE AE  AE 0AE @AE PAE `AE pAE AE AE AE AE AE AE AE AE  BE BE  BE 0BE @BE PBE `BE pBE BE BE BE BE BE BE BE BE  CE CE  CE 0CE @CE PCE `CE pCE CE CE CE CE CE CE CE CE  DE DE  DE 0DE @DE PDE `DE pDE DE DE DE DE DE DE DE DE  EE EE  EE 0EE @EE PEE `EE pEE EE EE EE EE EE EE EE EE  FE FE  FE 0FE @FE PFE `FE pFE FE FE FE FE FE FE FE FE  GE GE  GE 0GE @GE PGE `GE pGE GE GE GE GE GE GE GE GE  HE HE  HE 0HE @HE PHE `HE pHE HE HE HE HE HE HE HE HE  IE IE  IE 0IE @IE PIE `IE pIE IE IE IE IE IE IE IE IE  JE JE  JE 0JE @JE PJE `JE pJE JE JE JE JE JE JE JE JE  KE KE  KE 0KE @KE PKE `KE pKE KE KE KE KE KE KE KE KE  LE LE  LE 0LE @LE PLE `LE pLE LE LE LE LE LE LE LE LE  ME ME  ME 0ME @ME PME `ME pME ME ME ME ME ME ME ME ME  NE NE  NE 0NE @NE PNE `NE pNE NE NE NE NE NE NE NE NE  OE OE  OE 0OE @OE POE `OE pOE OE OE OE OE OE OE OE OE  PE PE  PE 0PE @PE PPE `PE pPE PE PE PE PE PE PE PE PE  QE QE  QE 0QE @QE PQE `QE pQE QE QE QE QE QE QE QE QE  RE RE  RE 0RE @RE PRE `RE pRE RE RE RE RE RE RE RE RE  SE SE  SE 0SE @SE PSE `SE pSE SE SE SE SE SE SE SE SE  TE TE  TE 0TE @TE PTE `TE pTE TE TE TE TE TE TE TE TE  UE UE  UE 0UE @UE PUE `UE pUE UE UE UE UE UE UE UE UE  VE VE  VE 0VE @VE PVE `VE pVE VE VE VE VE VE VE VE VE  WE WE  WE 0WE @WE PWE `WE pWE WE WE WE WE WE WE WE WE  XE XE  XE 0XE @XE PXE `XE pXE XE XE XE XE XE XE XE XE  YE YE  YE 0YE @YE PYE `YE pYE YE YE YE YE YE YE YE YE  ZE ZE  ZE 0ZE @ZE PZE `ZE pZE ZE ZE ZE ZE ZE ZE ZE ZE  [E [E  [E 0[E @[E P[E `[E p[E [E [E [E [E [E [E [E [E  \E \E  \E 0\E @\E P\E `\E p\E \E \E \E \E \E \E \E \E  ]E ]E  ]E 0]E @]E P]E `]E p]E ]E ]E ]E ]E ]E ]E ]E ]E  ^E ^E  ^E 0^E @^E P^E `^E p^E ^E ^E ^E ^E ^E ^E ^E ^E  _E _E  _E 0_E @_E P_E `_E p_E _E _E _E _E _E _E _E _E  `E `E  `E 0`E @`E P`E ``E p`E `E `E `E `E `E `E `E `E  aE aE  aE 0aE @aE PaE `aE paE aE aE aE aE aE aE aE aE  bE bE  bE 0bE @bE PbE `bE pbE bE bE bE bE bE bE bE bE  cE cE  cE 0cE @cE PcE `cE pcE cE cE cE cE cE cE cE cE  dE dE  dE 0dE @dE PdE `dE pdE dE dE dE dE dE dE dE dE  eE eE  eE 0eE @eE PeE `eE peE eE eE eE eE eE eE eE eE  fE fE  fE 0fE @fE PfE `fE pfE fE fE fE fE fE fE fE fE  gE gE  gE 0gE @gE PgE `gE pgE gE gE gE gE gE gE gE gE  hE hE  hE 0hE @hE PhE `hE phE hE hE hE hE hE hE hE hE  iE iE  iE 0iE @iE PiE `iE piE iE iE iE iE iE iE iE iE  jE jE  jE 0jE @jE PjE `jE pjE jE jE jE jE jE jE jE jE  kE kE  kE 0kE @kE PkE `kE pkE kE kE kE kE kE kE kE kE  lE lE  lE 0lE @lE PlE `lE plE lE lE lE lE lE lE lE lE  mE mE  mE 0mE @mE PmE `mE pmE mE mE mE mE mE mE mE mE  nE nE  nE 0nE @nE PnE `nE pnE nE nE nE nE nE nE nE nE  oE oE  oE 0oE @oE PoE `oE poE oE oE oE oE oE oE oE oE  pE pE  pE 0pE @pE PpE `pE ppE pE pE pE pE pE pE pE pE  qE qE  qE 0qE @qE PqE `qE pqE qE qE qE qE qE qE qE qE  rE rE  rE 0rE @rE PrE `rE prE rE rE rE rE rE rE rE rE  sE sE  sE 0sE @sE PsE `sE psE sE sE sE sE sE sE sE sE  tE tE  tE 0tE @tE PtE `tE ptE tE tE tE tE tE tE tE tE  uE uE  uE 0uE @uE PuE `uE puE uE uE uE uE uE uE uE uE  vE vE  vE 0vE @vE PvE `vE pvE vE vE vE vE vE vE vE vE  wE wE  wE 0wE @wE PwE `wE pwE wE wE wE wE wE wE wE wE  xE xE  xE 0xE @xE PxE `xE pxE xE xE xE xE xE xE xE xE  yE yE  yE 0yE @yE PyE `yE pyE yE yE yE yE yE yE yE yE  zE zE  zE 0zE @zE PzE `zE pzE zE zE zE zE zE zE zE zE  {E {E  {E 0{E @{E P{E `{E p{E {E {E {E {E {E {E {E {E  |E |E  |E 0|E @|E P|E `|E p|E |E |E |E |E |E |E |E |E  }E }E  }E 0}E @}E P}E `}E p}E }E }E }E }E }E }E }E }E  ~E ~E  ~E 0~E @~E P~E `~E p~E ~E ~E ~E ~E ~E ~E ~E ~E  E E  E 0E @E PE `E pE E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȀE ЀE ؀E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȁE ЁE ؁E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȂE ЂE ؂E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȃE ЃE ؃E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȄE ЄE ؄E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȅE ЅE ؅E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȆE ІE ؆E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȇE ЇE ؇E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȈE ЈE ؈E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȉE ЉE ؉E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȊE ЊE ؊E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȋE ЋE ؋E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȌE ЌE ،E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȍE ЍE ؍E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȎE ЎE ؎E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȏE ЏE ؏E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȐE АE ؐE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȑE БE ؑE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȒE ВE ؒE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȓE ГE ؓE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȔE ДE ؔE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȕE ЕE ؕE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȖE ЖE ؖE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȗE ЗE ؗE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȘE ИE ؘE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E șE ЙE ؙE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȚE КE ؚE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E țE ЛE ؛E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȜE МE ؜E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȝE НE ؝E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȞE ОE ؞E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȟE ПE ؟E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȠE РE ؠE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȡE СE ءE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȢE ТE آE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȣE УE أE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȤE ФE ؤE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȥE ХE إE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȦE ЦE ئE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȧE ЧE اE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȨE ШE بE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȩE ЩE ةE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȪE ЪE تE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȫE ЫE ثE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȬE ЬE جE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȭE ЭE حE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȮE ЮE خE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȯE ЯE دE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȰE аE ذE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȱE бE رE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȲE вE زE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȳE гE سE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȴE дE شE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȵE еE صE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȶE жE ضE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȷE зE طE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȸE иE ظE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȹE йE عE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȺE кE غE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȻE лE ػE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȼE мE ؼE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȽE нE ؽE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȾE оE ؾE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E ȿE пE ؿE E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E  E E E E  E (E 0E 8E @E HE PE XE `E hE pE xE E E E E E E E E E E E E E E E E   F  F  F  F  F  F  F  F   F $ F ( F , F 0 F 4 F 8 F < F @ F D F H F L F P F T F X F \ F ` F d F h F l F p F t F x F | F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  	F 	F 	F 	F 	F 	F 	F 	F  	F $	F (	F ,	F 0	F 4	F 8	F <	F @	F D	F H	F L	F P	F T	F X	F \	F `	F d	F h	F l	F p	F t	F x	F |	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F  
F 
F 
F 
F 
F 
F 
F 
F  
F $
F (
F ,
F 0
F 4
F 8
F <
F @
F D
F H
F L
F P
F T
F X
F \
F `
F d
F h
F l
F p
F t
F x
F |
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F 
F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F DF HF LF PF TF XF \F `F dF hF lF pF tF xF |F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F  F F F F F F F F  F $F (F ,F 0F 4F 8F <F @F5c6e0de0c-3901-11f0-234e-bd09c571f662/cfb9dac3af175b34layoutautosize¥xaxistickvals  ?   AtitletextDealer showingticktextA10templatelayout coloraxiscolorbarticksoutlinewidth    xaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhitehovermodeclosestpaper_bgcolorwhitegeoshowlakesèshowlandélandcolor#E5ECF6bgcolorwhitesubunitcolorwhitelakecolorwhitecolorscalesequential    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921diverging    #8e0152=ͧ#c51b7d>Lͧ#de77ae>#f1b6da>ͧ#fde0ef?   #f7f7f7?#e6f5d0?333#b8e186?Lͧ#7fbc41?fff#4d9221?  #276419sequentialminus    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921yaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhiteshapedefaultslinecolor#2a3f5fhoverlabelalignleftmapboxstylelightpolarangularaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6radialaxisgridcolorwhitetickslinecolorwhiteautotypenumbersstrictfontcolor#2a3f5fternaryaaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6caxisgridcolorwhitetickslinecolorwhitebaxisgridcolorwhitetickslinecolorwhiteannotationdefaultsarrowhead    arrowwidth?  arrowcolor#2a3f5fplot_bgcolor#E5ECF6titlex=Lͥscenexaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitezaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhiteyaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitecolorway#636efa#EF553B#00cc96#ab63fa#FFA15A#19d3f3#FF6692#B6E880#FF97FF#FECB52data scatterpolargltypescatterpolarglmarkercolorbarticksoutlinewidth    carpetbaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitetypecarpetaaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitescatterpolartypescatterpolarmarkercolorbarticksoutlinewidth    parcoordslinecolorbarticksoutlinewidth    typeparcoordsscattertypescattermarkercolorbarticksoutlinewidth    histogram2dcontourcolorbarticksoutlinewidth    typehistogram2dcontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcolorbarticksoutlinewidth    typecontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattercarpettypescattercarpetmarkercolorbarticksoutlinewidth    mesh3dcolorbarticksoutlinewidth    typemesh3dsurfacecolorbarticksoutlinewidth    typesurfacecolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattermapboxtypescattermapboxmarkercolorbarticksoutlinewidth    scattergeotypescattergeomarkercolorbarticksoutlinewidth    histogramtypehistogrammarkercolorbarticksoutlinewidth    pietypepieautomarginêchoroplethcolorbarticksoutlinewidth    typechoroplethheatmapglcolorbarticksoutlinewidth    typeheatmapglcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921bartypebarerror_ycolor#2a3f5ferror_xcolor#2a3f5fmarkerlinecolor#E5ECF6width?   heatmapcolorbarticksoutlinewidth    typeheatmapcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcarpetcolorbarticksoutlinewidth    typecontourcarpettabletypetableheaderlinecolorwhitefillcolor#C8D4E3cellslinecolorwhitefillcolor#EBF0F8scatter3dlinecolorbarticksoutlinewidth    typescatter3dmarkercolorbarticksoutlinewidth    barpolartypebarpolarmarkerlinecolor#E5ECF6width?   scattergltypescatterglmarkercolorbarticksoutlinewidth    histogram2dcolorbarticksoutlinewidth    typehistogram2dcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scatterternarytypescatterternarymarkercolorbarticksoutlinewidth    heightC  marginl    b    r    tBp  titleyaxistickvals  @A  AtitletextPlayer sumticktext  @A  AwidthC  configshowLink¨editableªresponsiveêstaticPlotªscrollZoomæframesdatazmax?  y(  @A  PA  `A  pA  A  A  A  A  A  AtypeheatmapcolorscaleBlueredzminʿ  z(뻾]8̾ʾ
ݾXhTǾV3>?(<wG2N+ۼV/=x>o?S9p?(2r=ʏC<zt<\l^oļV@D<>>A!?p?(=~=,O= I=I^<n <*>>D%?q?(=P={=Ȕ#=<=$H>C>$?p?(	>==W=죃=0>=U>>;G,?Kr?('=`=#Z<p(:Kgm<m>S???VUq?(Zm<IXO*(g=L?r??flq?(*½4&@-7TIJ`B>C8?s?(qCTg遾5̐=ul|^$#,>X?transposeéshowscaleáx(  ?   @  @@  @  @  @  @   A  A   A5c6e0de0c-3901-11f0-234e-bd09c571f662/1c437dfc407d8916layoutxaxistickvals(  ?   @  @@  @  @  @  @   A  A   AtitletextDealer showingticktextA@   @@  @  @  @  @  A   A  A   templatelayout coloraxiscolorbarticksoutlinewidth    xaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhitehovermodeclosestpaper_bgcolorwhitegeoshowlakesèshowlandélandcolor#E5ECF6bgcolorwhitesubunitcolorwhitelakecolorwhitecolorscalesequential    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921diverging    #8e0152=ͧ#c51b7d>Lͧ#de77ae>#f1b6da>ͧ#fde0ef?   #f7f7f7?#e6f5d0?333#b8e186?Lͧ#7fbc41?fff#4d9221?  #276419sequentialminus    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921yaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhiteshapedefaultslinecolor#2a3f5fhoverlabelalignleftmapboxstylelightpolarangularaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6radialaxisgridcolorwhitetickslinecolorwhiteautotypenumbersstrictfontcolor#2a3f5fternaryaaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6caxisgridcolorwhitetickslinecolorwhitebaxisgridcolorwhitetickslinecolorwhiteannotationdefaultsarrowhead    arrowwidth?  arrowcolor#2a3f5fplot_bgcolor#E5ECF6titlex=Lͥscenexaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitezaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhiteyaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitecolorway#636efa#EF553B#00cc96#ab63fa#FFA15A#19d3f3#FF6692#B6E880#FF97FF#FECB52data scatterpolargltypescatterpolarglmarkercolorbarticksoutlinewidth    carpetbaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitetypecarpetaaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitescatterpolartypescatterpolarmarkercolorbarticksoutlinewidth    parcoordslinecolorbarticksoutlinewidth    typeparcoordsscattertypescattermarkercolorbarticksoutlinewidth    histogram2dcontourcolorbarticksoutlinewidth    typehistogram2dcontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcolorbarticksoutlinewidth    typecontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattercarpettypescattercarpetmarkercolorbarticksoutlinewidth    mesh3dcolorbarticksoutlinewidth    typemesh3dsurfacecolorbarticksoutlinewidth    typesurfacecolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattermapboxtypescattermapboxmarkercolorbarticksoutlinewidth    scattergeotypescattergeomarkercolorbarticksoutlinewidth    histogramtypehistogrammarkercolorbarticksoutlinewidth    pietypepieautomarginêchoroplethcolorbarticksoutlinewidth    typechoroplethheatmapglcolorbarticksoutlinewidth    typeheatmapglcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921bartypebarerror_ycolor#2a3f5ferror_xcolor#2a3f5fmarkerlinecolor#E5ECF6width?   heatmapcolorbarticksoutlinewidth    typeheatmapcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcarpetcolorbarticksoutlinewidth    typecontourcarpettabletypetableheaderlinecolorwhitefillcolor#C8D4E3cellslinecolorwhitefillcolor#EBF0F8scatter3dlinecolorbarticksoutlinewidth    typescatter3dmarkercolorbarticksoutlinewidth    barpolartypebarpolarmarkerlinecolor#E5ECF6width?   scattergltypescatterglmarkercolorbarticksoutlinewidth    histogram2dcolorbarticksoutlinewidth    typehistogram2dcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scatterternarytypescatterternarymarkercolorbarticksoutlinewidth    heightC  marginl    b    rA   tA  yaxistickvals(  @A  PA  `A  pA  A  A  A  A  A  AtitletextPlayer sumticktext(  @A  PA  `A  pA  A  A  A  A  A  AwidthC  configshowLink¨editableªresponsiveêstaticPlotªscrollZoomæframesdatazmax?  y(  @A  PA  `A  pA  A  A  A  A  A  AtypeheatmapcolorscaleGreyszminʿ  z(  ?  ?  ?  ?  ?          (  ?                  (  ?                  (                    (                    (                    (  ?  ?  ?  ?  ?          (  ?  ?  ?  ?  ?          (  ?  ?  ?  ?  ?          (  ?  ?  ?              transposeéshowscale¡x(  ?   @  @@  @  @  @  @   A  A   A4c6e0de0c-3901-11f0-234e-bd09c571f662/aebe9ff9bf4a3c7layoutxaxistypelogtitletextEpisodes (log scale)templatelayout coloraxiscolorbarticksoutlinewidth    xaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhitehovermodeclosestpaper_bgcolorwhitegeoshowlakesèshowlandélandcolor#E5ECF6bgcolorwhitesubunitcolorwhitelakecolorwhitecolorscalesequential    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921diverging    #8e0152=ͧ#c51b7d>Lͧ#de77ae>#f1b6da>ͧ#fde0ef?   #f7f7f7?#e6f5d0?333#b8e186?Lͧ#7fbc41?fff#4d9221?  #276419sequentialminus    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921yaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhiteshapedefaultslinecolor#2a3f5fhoverlabelalignleftmapboxstylelightpolarangularaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6radialaxisgridcolorwhitetickslinecolorwhiteautotypenumbersstrictfontcolor#2a3f5fternaryaaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6caxisgridcolorwhitetickslinecolorwhitebaxisgridcolorwhitetickslinecolorwhiteannotationdefaultsarrowhead    arrowwidth?  arrowcolor#2a3f5fplot_bgcolor#E5ECF6titlex=Lͥscenexaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitezaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhiteyaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitecolorway#636efa#EF553B#00cc96#ab63fa#FFA15A#19d3f3#FF6692#B6E880#FF97FF#FECB52data scatterpolargltypescatterpolarglmarkercolorbarticksoutlinewidth    carpetbaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitetypecarpetaaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitescatterpolartypescatterpolarmarkercolorbarticksoutlinewidth    parcoordslinecolorbarticksoutlinewidth    typeparcoordsscattertypescattermarkercolorbarticksoutlinewidth    histogram2dcontourcolorbarticksoutlinewidth    typehistogram2dcontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcolorbarticksoutlinewidth    typecontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattercarpettypescattercarpetmarkercolorbarticksoutlinewidth    mesh3dcolorbarticksoutlinewidth    typemesh3dsurfacecolorbarticksoutlinewidth    typesurfacecolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattermapboxtypescattermapboxmarkercolorbarticksoutlinewidth    scattergeotypescattergeomarkercolorbarticksoutlinewidth    histogramtypehistogrammarkercolorbarticksoutlinewidth    pietypepieautomarginêchoroplethcolorbarticksoutlinewidth    typechoroplethheatmapglcolorbarticksoutlinewidth    typeheatmapglcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921bartypebarerror_ycolor#2a3f5ferror_xcolor#2a3f5fmarkerlinecolor#E5ECF6width?   heatmapcolorbarticksoutlinewidth    typeheatmapcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcarpetcolorbarticksoutlinewidth    typecontourcarpettabletypetableheaderlinecolorwhitefillcolor#C8D4E3cellslinecolorwhitefillcolor#EBF0F8scatter3dlinecolorbarticksoutlinewidth    typescatter3dmarkercolorbarticksoutlinewidth    barpolartypebarpolarmarkerlinecolor#E5ECF6width?   scattergltypescatterglmarkercolorbarticksoutlinewidth    histogram2dcolorbarticksoutlinewidth    typehistogram2dcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scatterternarytypescatterternarymarkercolorbarticksoutlinewidth    legendorientationhmarginlBH  bBH  rBH  tBp  yaxisrange      @@titlerotationB  textYMonte-Carlo estimate of <br> state value with <br> ordinary importance sampling (10 runs)configshowLink¨editableªresponsiveêstaticPlotªscrollZoomæframesdatashowlegend¡y\   @  ?   @?%I?  ?.:?%I?*?   ??>>ף>=>j>  P>K~1>/>m>KW?y.?\0/?z@5?ԙ$?M,%?t??):>Z>h??l	?8?6???=f?e;??I???W?Ɖ???P?a??݁??,|??y??2f~??}?\y?t0?.?+C?GA?ط?`?(e?[??*D?A?π?{?"?r???&???՜?O?|?{?y?x?w?v?*t?r?$q?xo?6~?}?z?Dy?@w?k	u?s?]q?Lt?_s?r?Ȫq?u?8u?s?Yr?DMs?tr?	r?p?o?vn?ּl?rl?p-k?a?f?xje?pd?&c?:cb?}a?c_?d^?`?*_?^?y^?S]?]?]?]?_?B^?]?\?!g\??{[?`Z?Y?WZ?/Y?lX?W?V?PMV?[nU?[T?ԈS?R?*R?]Q?P?jPQ?JQ?MgP?P?K+O?N?bWN?M?xUM?L?C,M?#fL?L?bL?K?K?	K?|J?U=J?9J?J?1)J?:I?I?EI?H?aI?xJ?hJ?(I??I?mH?zNH?G?JH?#H?6G?yF?[F?jE?{E?D?)D?ajD?4D?C?C?1uB?N/B?VA?PA?A?B?"A?B?A?MA?0@?@?@?/@?{w@?^@?2@?n??DR??>?c>?V>?d=?X=?_=?z>=?J<?K<?<?/;?2;?z'<?3<?;?;?j;?KH;?:?t:?Q):?9?9?&9?ϼ8?8?:?:?:?a:?c2:? :?9?$3:?9?9?O9?9?9?9?9?X9?9?19?9?J9?b;?OL;?@;?R;?:?ϵ:?:?F:?|:?:?:?:?w9?:? 9?v_9?L9?|8?.4:?9?M:?,.:?:?F9?:? ;?:?:?[:?R	:?9?U9?e9??9?Q2;?:?[{:?t:?}:?y:?E:?9?{9?)9?8?q8?8?8?8?8?38?8?*8?<8?7?A7?w7?7?}n7?7?^8?58?և8?8?8?De8?;8?P,8?j8?18?8,8?$8?j7?8?;E8?-8?o8?58?8?d8?7?
7?S7?7?6?ݜ6?a6?Q6?o6?;5?5?5?5?|5?t5? +5?V9B?cA?A?pA?A?ƽA?D{A?gA?BA?A? @?}@?ɟ@?,r@?5@?E@?j@?Т@?@?{@?b@?Y<@?!@?????zk?? /??Y$??7>?>?x>?Y;>?>?=?G=?ҝ=?>?=?=?U~=?0=?D =?n<?<?J<?ٽ<?<?g<?h<?O<?[*<?O;?d)<?W!<?q<?q<?Bo<?|S<?+<?*;?;?;?]G;?:;?:?;:?|:?:?:?x:?/:?:?V:?>T:?!:?gP:?#:?E9?59?]w9?K_9?̓9?l9?RK9?f9?@9?9?)8?8?F8?D8?8?8?8?>`8?GJ8?E8?\8?7?7?h7?t7?E7?X7?6<7?4r7?17?7?6?6?26?6?o6?W6?_l6?Բ6?в6?=6?6?6?ض6?ϕ6?m7?g7?^7?K7?#7?x7?V8?c#8?7?.7?ε7?7?Ye7?=7?7?~6?6?Q6?n6?he6?B6?u46?16?H6?,7?6?u7?"9?W8?8?>8?Ɲ8?x8?k8?VV8?+8?f8?+8?i8?	j8?,\8?78?tN8?;8?8?O58?t88?P8?"8?U!8?8?7?e7?7?d7?lv7?7?g7?.7?0p7??7?9?a9?;9?.9?Lm9?\V9?H9?{F9?29?!9?8?"8?-9?9?9?f9?0\9?C9?:?g;?:?:?B:?:?:?ف:?x_:?H:?%a<?Q>?!>?>?=?=?=?=?Zn=?J=?t.=?	=?=?d=?=?"=?%<?<?<?`<?<?<?k<?<?<?m<?l<?B<?>?>?2=?=?=?=?a=?=?H~>?a>?o>??>?C>?_>?@>?u>?>?>?7>?X=?*=?=?8=?=?>?4>?w>?>?N>??a>?L>?c4>?@>?;>?'>?>?>?=?r=?'=?=?B=?_=?e=?=A=?6=?"=?<?=?<?<?<?<?<?<?<?<?w<?k<?p<?/><?#<?;?Y;?;?د;?;?<?*;?;?r;?X;?~7<?n6<?H<?;?A;?;?;?;?\;?;?!;?$=?<?;<?><?<?#<?a<?<?a]<?7<? <?<?f;?;?#;?Ε;?vq;?Z;?zg;?ly;?{;?#;?q;?{;?W;?.D;?f;?;?/;? ;?t:?9;?;?;?y;?;?;?p;?mE;?q;?AH;?1;?;?:?;:?6:?';?:?:?m;?;?):?8;?:?i:?:?d:?h:?u:?\:?$G:?*:?*:?`:?T:?y:?:?j:?9\:?}S:?<:?.:?:?S9?%9?9?T9?w9?9?b9?Y9?9?9?z9?l9?V9?@9?*K9?79?(9?f9?d9?
8?8?8?
8?8?l8?8?Z8?8?&8?8?8?8?-8?H8?8?8?|8?r8?i8?w8?
b8?t[8?w?8?$=8?$8?#8?68?@8?8?8?8?8?8?8?Ym8?8?P8?֚8?~8?	Y8?<8?28?A8?78?o-8?T8?j8?Q8?U8?8?8?K8?>8?8?!8?8?y8?n8?m8?V8?M8?:8?N8?
18?8?w7?7?;7?38?'*8?p8?Y8?98?E"8?38?8?8P8?A8?58?7#8?8?8?8?7?7?7?:7? 7?7?P7?j8?k8?R8?@8?'8?'8?|7?z7?S7?7?7?7?7?z7?BV7?T7?;7?-7?k7?6?K6?6?6?f6?6?6?:6?l6?]6?=n6?g6?\6?A6?Z6?E6?Q'6?R6?6?5?5?N5?h5?`5?e5?Yz5?^5?$W5?5?5?l5?3\5?2G?typescatterx\  ?   @  @@  @  @  @  @   A  A   A  A  A   B  HB  pB  B  B  B  B  HC  C  C  C  D  /D  HD  aD  zD  D ;E  zE @E E E  E F @F +F ;F  KF ZF `jF  zF ЄF F pF @F F F F F PF  F F F F `F 0F  F  G G G G G pG XG @G ( G $G 'G +G /G 3G 7G ;G h?G PCG 8GG  KG OG RG VG ZG ^G bG xfG `jG HnG 0rG vG  zG }G G ܂G ЄG ĆG G G G G G |G pG dG XG LG @G 4G (G G G G G G G ԭG ȯG PG DG 8G ,G  G G G G G G G G G G G G G G xG lG `G TG HG <G 0G $G G G  G G G G  H H H H H H H H H 	H 
H H H H H H H H |H vH pH jH dH ^H XH RH LH FH @H :H 4H .H ( H "!H "H #H $H 
%H &H &H 'H (H )H *H +H ,H -H .H /H 0H 1H 2H 3H 4H 5H 6H 7H 8H 9H :H ;H z<H t=H n>H h?H b@H \AH VBH PCH JDH DEH >FH 8GH 2HH ,IH &JH  KH LH MH NH OH PH PH QH RH SH TH UH VH WH XH YH ZH [H \H ]H ^H _H `H aH bH cH dH ~eH xfH rgH lhH fiH `jH ZkH TlH NmH HnH BoH <pH 6qH 0rH *sH $tH uH vH wH xH yH  zH zH {H |H }H ~H H kH H eH H _H ܂H YH փH SH ЄH MH ʅH GH ĆH AH H ;H H 5H H /H H )H H #H H H H H H H H H H H H H |H H vH H pH H jH H dH H ^H ۗH XH ՘H RH ϙH LH ɚH FH ÛH @H H :H H 4H H .H H (H H "H H H H H H H H 
H H H H H {H H uH H oH H iH H cH H ]H ڬH WH ԭH QH ήH KH ȯH EH °H ?H H 9H H 3H H -H H 'H H !H H H H H H H H 	H H H H H zH H tH H nH H hH H bH H \H H VH H PH H JH H DH H >H H 8H H 2H H ,H H &H H  H H H H H H H H H H H H H yH H sH H mH H gH H aH H [H H UH H OH H IH H CH H =H H 7H H 1H H +H H %H H H H H H H H H H H H H ~H H xH H rH H lH H fH H `H H ZH H TH H NH H HH H BH H <H H 6H H 0H H *H H $H H H H H H H H H H H H  H }H H wH H qH H kH H eH H _H H, I k I I  I&I eII I I _II II YII II SII II MII II GII II AII II ;IyI II 5	Is	I 	I	I /
Im
I 
I
I )IgI II #IaI II I[I II IUI II IOI II III II ICI II I=I |II I7I vII I1I pII I+I jII I%I dII II ^II II XII II RII II LII II FII II @I~I II :IxI II 4IrI II .IlI II ( If I  I I "!I`!I !I!I "IZ"I "I"I #IT#I #I#I $IN$I $I$I 
%IH%I %I%I &IB&I &I&I &I<'I {'I'I 'I6(I u(I(I (I0)I o)I)I )I**I i*I*I *I$+I c+I+I +I,I ],I,I ,I-I W-I-I -I.I Q.I.I .I/I K/I/I /I0I E0I0I 0I 1I ?1I}1I 1I1I 92Iw2I 2I2I 33Iq3I 3I3I -4Ik4I 4I4I '5Ie5I 5I5I !6I_6I 6I6I 7IY7I 7I7I 8IS8I 8I8I 9IM9I 9I9I 	:IG:I :I:I ;IA;I ;I;I ;I;<I z<I<I <I5=I t=I=I =I/>I n>I>I >I)?I h?I?I ?I#@I b@I@I @IAI \AIAI AIBI VBIBI BICI PCICI CIDI JDIDI DIEI DEIEI EIEI >FI|FI FIFI 8GIvGI GIGI 2HIpHI HIHI ,IIjII IIII &JIdJI JIJI  KI^KI KIKI LIXLI LILI MIRMI MIMI NILNI NINI OIFOI OIOI PI@PI PIPI PI:QI yQIQI QI4RI sRIRI RI.SI mSISI SI(TI gTITI TI"UI aUIUI UIVI [VIVI VIWI UWIWI WIXI OXIXI XI
YI IYIYI YIZI CZIZI ZIZI =[I{[I [I $tIshowlegend¡y\      ?>>>8c>.:>؉>$I>>=>H>.:>"I>=3x>Nl>g]>A>=KD>Q>{q>qES>7Q>rT>d>R>Bs>D\><>">>f>}>>~>>1> ?^y?f?o?X?I??zw?.r?j?=e?a?^?Y?z%X?;T?S?O?GVN?CJ?K?*I?G?GsE?QD?E?'C?WA?	??o=?];?n~<?]=?,@?>?uCC?@?:]A?t??>?5/=?D;?ւ9?=?>?R=?;?:?ٸ9?H=?<?p;?:?<?=<?m	<?;?\9?9?I9?آ<?=?jY<?M;?[;?':?;m:?b9?$9?Ae8?S7?
6?X5?a5?Q4?H3?2?13?d?;,c?Pb?V,a?`?h_?l^?]?:\?4]?#\?'[?Y?X?*X?$Z?Y?X?UtX?[W?ÐW?[?#Z?.Z?r^^?O]?e\?%Q[?;~Z?kZ?Y?وY?2^X?fW?MV?X?AX?פW?,W?W?,,W?MfX?W?aV?YV?lV?W?'V?FW?V?cV?]GW?V?U?T?-T?`S?R?iR?-R?HQ?Q?P?CP?dO?~:P?!gO?N?y[N?'M?߯M?]$O?{N?PN?`N?FN?{M?<M?L?M?_^L?K?s^K?(K??K?J?ۡJ??bJ?I?_GI?H?wH?0H?zG?oG?G?TG?:F?G?.QG?F?G?G?!G?G?}G?^G?G?G?WG?;G?!F?5F?AE?&WE?FE?*E?D?{D? D?C?C?5C?pB?B?7B?`B?A?U?ezV?V?Z?Z?YZ?Z?zY?BBY?iY?BUY?X?X?W8X?)W?W?=W?f8X?iX?hW?YTX?%.X?HX?6wX?sX?EX?}SX?HW?X?'W?W?$W?V?V?*V?U?cU?	U?'T?TT?XT?iS?pS?,S?IS?S?S?͟R? R?R?OQ?pQ?Q?P?P?^R?R?8R?[JR?'R?	Q?`Q?>Q?P?ʶP?eP?nP?O?GO?[6P?O?,O?O?9cO?kO??O?O?N?vN?iN?E+N?6M?M?XM?RM?AL?L?L?'SL?K?@K?K?%K?rK?#K?'K?J?UK?GK?CUK?VK?J?J?yJ?+J?I?I?=I?#>I?H?>I?NH?vI?H?}H?WH?2YH?#H?FJH?CH?4H?FG?G?yG?YG?BG?F?ФF?YF?F?;E?
F?,E?CL?K?.fK?[K?K?DJ?&J?[J?J?N
J?I?5vI?YI?u;I?_I?EI?bI?H?.H?cH?OH?H? H?yG?G?G?G?rG?*:G?ƆG?YG?~G?|G?CG?G?F?F?4F? E?F?E?E?E?QE?a)E?%D?]D?iD?D?D?RD?KD?aD?yC?E?mE?DF?$JF?F?F?F?'F?F?ʞF?tF?RF?rF?F?̋F? AF?kF?3F?5:[?J#[?Z?;Z?'iZ?47Z?'Z?Y? Y?@Y?[?K[?gN[?+[?\Z??Z?Z?TZ?l_Z?Z?sY?[Y?ԕY?f]Y?CY?7Y?4X?;hZ?IZ?Z*Z?Y??Y?Y?[Y?5Y?
Y?/%Y?
X?ޟX? dX?!X?W?@W?W?,W?XdW?R.W?W?BV?ޞV?VV?-V?5V?"V?`V?EAV?UV?UV?V?UU? U?µU?>U?oU?CU?T?T?>U?!U?4T?ѪT?T?rT?2IT?oLT?2T?uT?WS?S?|S?zS?oSS?S?LR?R?R?LT?NT?T?T?T?T??T?
T? S?jS?uS?#S?S?/S?S?NS?kS?<S?}S?4S?R?R?CR?R?R?gR?BR?R?Q?Q?zQ?MQ?#Q?Q?'#Q?P?VP?RP?VP?'{P?_OP?P?O?\9P?H/P?xJP?2P?-+P?P?O?RO?zO?@[O?iHO?&O?KN?IN?jN?N?N?XN?FN?BN?N?xN?kN?VN?(N?M?dM?M?NvM?\\M?]zM?kZM?<M?^
M?L?бL?L?gL?KL?L?K?L?fK?gK?CK?ȊK?aK?CK?[K?FK?"IK?(8K?K?K?J?uJ?JJ?J?UUJ?_ZJ?&%J?,I?I?jI?TI?CMI?eI?(I?+H?H?ޫH?H?]H?\H?^H?!8H?H?H?cG?G?H?H?G?zGH?eH?H?SL??8L?UL?K?K?K?K?K?E|K?IK?0K?eK?J?J?*K?_;K?E,K?K?sK?mK?WK?FK?0K?K?J?J?4J?yJ?z^J?QJ?*CJ?(J?[J?[I?rI?I?ąI?P?^3Q?g6Q?Q??Q?&Q? Q?`P?P?P?P?~P?P?gP?	?P?x)P?O?O?O?=O?SO?,O?LO?iCO?+O?O?PN?N?$O?c2O?0jO?bO?8QO?d?O?8O?O=O?6O?O?N?FN?XN?N?'N?sN?WO?[3O?\O?XO?N?mN?N?N?\N?~N?N?N?3N?N?wN?RN?:N?SN?0 N?M?M?qM?L_M?7M?M?&M?)M?M?sL?SL?L?L?L?L?0L?HL?L?xL?VsL?KL?*L?L?QL?u=L?"L?#L?WL?K?K?K?K?fK?AK?K?kK?eK?֨K?ՈK?gK?|QK?(K?K?J?eJ?HJ?J?J?zJ?J?J?uJ?<`J?RJ?@?J?0,J?
J?^I?I?J?NI?8I?I?rJ?ZJ?>aJ?yJ?^J?qiJ?Q?J?,J?J?I?I?nI?pI?I?tI? I?I?kI?oI?|J?J?J?J?J?vJ?J?J?J?J?J?DJ?cqJ?%NJ?%)J?J?vJ?J?I?I?iI?EI?I?_I?I?ζI?I?iI?}IL?#L?8L?K?_K?K?yK?OK?9]N?EN?h+N?N?M?8M?M?XM?0M?#M?M?yM?kM?_VM?VPM?L<M? M?OO?դO?jO?yO?O?$vO?UO?	cO?CO?zAO?-O?G)O?&O?O?-N?uN?_N?N?L?typescatterx\  ?   @  @@  @  @  @  @   A  A   A  A  A   B  HB  pB  B  B  B  B  HC  C  C  C  D  /D  HD  aD  zD  D ;E  zE @E E E  E F @F +F ;F  KF ZF `jF  zF ЄF F pF @F F F F F PF  F F F F `F 0F  F  G G G G G pG XG @G ( G $G 'G +G /G 3G 7G ;G h?G PCG 8GG  KG OG RG VG ZG ^G bG xfG `jG HnG 0rG vG  zG }G G ܂G ЄG ĆG G G G G G |G pG dG XG LG @G 4G (G G G G G G G ԭG ȯG PG DG 8G ,G  G G G G G G G G G G G G G G xG lG `G TG HG <G 0G $G G G  G G G G  H H H H H H H H H 	H 
H H H H H H H H |H vH pH jH dH ^H XH RH LH FH @H :H 4H .H ( H "!H "H #H $H 
%H &H &H 'H (H )H *H +H ,H -H .H /H 0H 1H 2H 3H 4H 5H 6H 7H 8H 9H :H ;H z<H t=H n>H h?H b@H \AH VBH PCH JDH DEH >FH 8GH 2HH ,IH &JH  KH LH MH NH OH PH PH QH RH SH TH UH VH WH XH YH ZH [H \H ]H ^H _H `H aH bH cH dH ~eH xfH rgH lhH fiH `jH ZkH TlH NmH HnH BoH <pH 6qH 0rH *sH $tH uH vH wH xH yH  zH zH {H |H }H ~H H kH H eH H _H ܂H YH փH SH ЄH MH ʅH GH ĆH AH H ;H H 5H H /H H )H H #H H H H H H H H H H H H H |H H vH H pH H jH H dH H ^H ۗH XH ՘H RH ϙH LH ɚH FH ÛH @H H :H H 4H H .H H (H H "H H H H H H H H 
H H H H H {H H uH H oH H iH H cH H ]H ڬH WH ԭH QH ήH KH ȯH EH °H ?H H 9H H 3H H -H H 'H H !H H H H H H H H 	H H H H H zH H tH H nH H hH H bH H \H H VH H PH H JH H DH H >H H 8H H 2H H ,H H &H H  H H H H H H H H H H H H H yH H sH H mH H gH H aH H [H H UH H OH H IH H CH H =H H 7H H 1H H +H H %H H H H H H H H H H H H H ~H H xH H rH H lH H fH H `H H ZH H TH H NH H HH H BH H <H H 6H H 0H H *H H $H H H H H H H H H H H H  H }H H wH H qH H kH H eH H _H H, I k I I  I&I eII I I _II II YII II SII II MII II GII II AII II ;IyI II 5	Is	I 	I	I /
Im
I 
I
I )IgI II #IaI II I[I II IUI II IOI II III II ICI II I=I |II I7I vII I1I pII I+I jII I%I dII II ^II II XII II RII II LII II FII II @I~I II :IxI II 4IrI II .IlI II ( If I  I I "!I`!I !I!I "IZ"I "I"I #IT#I #I#I $IN$I $I$I 
%IH%I %I%I &IB&I &I&I &I<'I {'I'I 'I6(I u(I(I (I0)I o)I)I )I**I i*I*I *I$+I c+I+I +I,I ],I,I ,I-I W-I-I -I.I Q.I.I .I/I K/I/I /I0I E0I0I 0I 1I ?1I}1I 1I1I 92Iw2I 2I2I 33Iq3I 3I3I -4Ik4I 4I4I '5Ie5I 5I5I !6I_6I 6I6I 7IY7I 7I7I 8IS8I 8I8I 9IM9I 9I9I 	:IG:I :I:I ;IA;I ;I;I ;I;<I z<I<I <I5=I t=I=I =I/>I n>I>I >I)?I h?I?I ?I#@I b@I@I @IAI \AIAI AIBI VBIBI BICI PCICI CIDI JDIDI DIEI DEIEI EIEI >FI|FI FIFI 8GIvGI GIGI 2HIpHI HIHI ,IIjII IIII &JIdJI JIJI  KI^KI KIKI LIXLI LILI MIRMI MIMI NILNI NINI OIFOI OIOI PI@PI PIPI PI:QI yQIQI QI4RI sRIRI RI.SI mSISI SI(TI gTITI TI"UI aUIUI UIVI [VIVI VIWI UWIWI WIXI OXIXI XI
YI IYIYI YIZI CZIZI ZIZI =[I{[I [I $tIshowlegend¡y\        >>  >L>.:>>؉>$I>S>u>1F>(!>K>}>>>!>b\>qE>UT>3B>@>nV>>>|>B>.F?p*??5?]?B?ߢ?dB?`l?ใ? |?u~?5?y?u?Rn?<n?xl?i?t?߁n?Kj?g[h?d?n^?q?,q?l?%j?5f?bc?*^?M^?^?\?zY?+V?S?X?wW?U?(b?]6a?m_?]?<^?d\?Z?-O\?Z?W?'U?!cT?R?Q?<RP?O?M?uL?qJ?yJ?H?ϖG?B)F?D?D?C?A?kA?@?E(??nY??[@?ߗ???@?w(??Aj@???k??d>??k=?<<?#E<?e
;?P~:?Cd=?<?;? ;?4?3?Y3?Q2?18?8?C?HC?|B?oD?D?p\D?D?C?fBC?(B?*B?	B?TA?;A?IU@???????mC?#C?RB?VB?=QM?L?ɳK?K?SJ?L??K?*K?oK?PK?J?xDK?`7K?J?I?I0I?vH?OJ?J? I?]J?8-J?I?TmI?cH?I?I?I?H?`7J?^Q?kP?P?qP?#RP?zO?N? N?J]M?]&M?L?[PL?BK?CK?K?5K?J?LmJ?oJ?i&K?MJ?J?~:J?{I?plI?H?H?}I?J?lJ?`J?cJ?VJ?I?yzI?.I?/I?H?H?΋H?S?JS?^#S?*R?DPR?
Q?Q?jQ?P?oP?!P?OQ?pQ?%Q?(P?P?O?N?N?4N?_N?N?VN?JM?
M?QM?M?M?hM?M?;M?uN?VN?M?dM?L?qL?h%L?K?˅K?MK?J?]J?DJ?܊I?	I?]H?'DH?G?G?tG?3G?JxG?1G?F? F?7pF?8H?7G?G?xG?G?xpG?/G?F?F?{F?F?E?&E?%E?E?[E?|E?E?`WE?D?D?@D?C?C?[JC?/C?B?HB?B?B?CB?A?WA?A?A?wA?A?R@?A?@?{@?a@?Ǧ@?w@?i@?
F@?????z??X??h??=/??7??Y????>?W>?A?A?~A?A?.UA?B@?B?]B?;B?LA?tA?A?lA?(A?3@?l@?1@?}@?s@?@?A?EjA?uA?A?ǍA?fYA?A?ݼ@?xt@?Vm@?+t@?d\@?&@?@???l??}??[??I??>?#??>?>?>?!"??>?*>?`>?E>?`>?lY>?c>?1>?9>?!W>?>?P=?>?D >?9=?>?p=?VK>?>?=?=?7=?=?w=?x=?=?=>?E>?>?=?=?=?(j=?=?d=?@
>?=?=?@=?=?s]=?$>?+??$&??>?"??f??9>?>?o>?>?)>?Ff>?f4>?)>?=?=? =?z=?Y=?`=?A=?>?λ>?j>?y]>?%>?>?=?=?=?=?DB?ZC?B?C)C?I!C?dC?3C?"C?C?1C?B?B?B?pB?xmB?\B?[B?@B?A?+A?A?+A?}A?A?ݝA?TA?1A?nA?B@?@?8@?٠@?c@?#M@?o@???I??G??R??z????|??{R??/????>?>?j>?>?+t>?j>?>?-v>?GE>?
>?5=?b=?'>?>?=?=?=?Dv=?^=?,=?L=?=?=?/<?%<?	<?`z<?1\<?B<?Y@<?d"<?;?<?;?	<?W;?;?<?8;?7;?H;?à;?:;?;?;?y;?>;?;?P;?7;?7/;?$;?:?9:?::?½:?:?W:?]:?\:?,:?5A:?:?9?29?έ9?|9?:b9?99?qC9?z.9?"9?9?8?8?ز8?8?t8?`8?jE8?*-8?B8?8$8?S8?f78?B8?-8?8?7?G7?8?7?87?D7?97?7?xc7?@7?+7?W7?47?D7?X7?6?6?!6?6?Ӧ6?6?36?o6?r6?`i6?@6?6?\6?>5?%5?5?5?%5?5?5?n5?p5?~5?e5?85?5?5?4?4?m4?4?4?f4?D4?4??3?x3?+3?t3?x3? p3?q3?R{3?Q3?=h3?3?]i3?>A3?.3?^3?T5?:5?5?	5?4?4?4?}4?v4?4?e4?B4?,4?4?3?4?4?"{4?Ns4?n4?Z4?w@4? #4?$4?y4?
4?Wa4?=4?f4?.t4?'r4?-u4?U4?&]4?AS4?E4?@4?]4??4?*4?#4?3?B3?e3?3?3?43?WY4?4?C4?u4?DZ4?P4?f.4?3?3?;3?3?3?3?3?t3?n3?N3?5?ާ5?\6?6?6?ù6?6?7?017?*7?7?s7?46?h6?6?ӯ6?6?6?"}6?a6?^6?ry6?tf6?OR6?T6?6?[6?K6?86?C?yB?.C?@	C?B?B?*B?B??zB?gB?OB??B?B?LB?lA?	A?6A?A?{A?nA?kA?8wA?uA?<XA?MA?2A?MA?eA?fFA?)1A?A?wA?A?A??A?<A?)A?GA?qB?ZB?C?B?B?B?;B?B?C?GB?jB?B?B?cB?B?B?tB?OaB?pB?ZB?LB?6B?%B?/B?3"B?1B?f(B?B?B?iA?A?A?WA?A?^A?iA?uNA?=A?(A?6A?@?@?@?@?Rs@?]@?A@?D@???I@?????????g??????????u??3????s??0p??CZ??n??O??@??'??[@??-??L??a[??fU??7??KU??@??J??????@?w@?@?;i@?w@?~@?!@?@?R@?@?@?r@?@?}@?"@?B@?v@?Z@?I@?1@?@?b@?????????r@?@???Z??-??????I??????|??vx??A\??]??;??$??E"??z????????>?	>? D?)D?gN?ON?DN?*N?dN?IDN?@N?8,N?;"N?"N?*M?N?R?typescatterx\  ?   @  @@  @  @  @  @   A  A   A  A  A   B  HB  pB  B  B  B  B  HC  C  C  C  D  /D  HD  aD  zD  D ;E  zE @E E E  E F @F +F ;F  KF ZF `jF  zF ЄF F pF @F F F F F PF  F F F F `F 0F  F  G G G G G pG XG @G ( G $G 'G +G /G 3G 7G ;G h?G PCG 8GG  KG OG RG VG ZG ^G bG xfG `jG HnG 0rG vG  zG }G G ܂G ЄG ĆG G G G G G |G pG dG XG LG @G 4G (G G G G G G G ԭG ȯG PG DG 8G ,G  G G G G G G G G G G G G G G xG lG `G TG HG <G 0G $G G G  G G G G  H H H H H H H H H 	H 
H H H H H H H H |H vH pH jH dH ^H XH RH LH FH @H :H 4H .H ( H "!H "H #H $H 
%H &H &H 'H (H )H *H +H ,H -H .H /H 0H 1H 2H 3H 4H 5H 6H 7H 8H 9H :H ;H z<H t=H n>H h?H b@H \AH VBH PCH JDH DEH >FH 8GH 2HH ,IH &JH  KH LH MH NH OH PH PH QH RH SH TH UH VH WH XH YH ZH [H \H ]H ^H _H `H aH bH cH dH ~eH xfH rgH lhH fiH `jH ZkH TlH NmH HnH BoH <pH 6qH 0rH *sH $tH uH vH wH xH yH  zH zH {H |H }H ~H H kH H eH H _H ܂H YH փH SH ЄH MH ʅH GH ĆH AH H ;H H 5H H /H H )H H #H H H H H H H H H H H H H |H H vH H pH H jH H dH H ^H ۗH XH ՘H RH ϙH LH ɚH FH ÛH @H H :H H 4H H .H H (H H "H H H H H H H H 
H H H H H {H H uH H oH H iH H cH H ]H ڬH WH ԭH QH ήH KH ȯH EH °H ?H H 9H H 3H H -H H 'H H !H H H H H H H H 	H H H H H zH H tH H nH H hH H bH H \H H VH H PH H JH H DH H >H H 8H H 2H H ,H H &H H  H H H H H H H H H H H H H yH H sH H mH H gH H aH H [H H UH H OH H IH H CH H =H H 7H H 1H H +H H %H H H H H H H H H H H H H ~H H xH H rH H lH H fH H `H H ZH H TH H NH H HH H BH H <H H 6H H 0H H *H H $H H H H H H H H H H H H  H }H H wH H qH H kH H eH H _H H, I k I I  I&I eII I I _II II YII II SII II MII II GII II AII II ;IyI II 5	Is	I 	I	I /
Im
I 
I
I )IgI II #IaI II I[I II IUI II IOI II III II ICI II I=I |II I7I vII I1I pII I+I jII I%I dII II ^II II XII II RII II LII II FII II @I~I II :IxI II 4IrI II .IlI II ( If I  I I "!I`!I !I!I "IZ"I "I"I #IT#I #I#I $IN$I $I$I 
%IH%I %I%I &IB&I &I&I &I<'I {'I'I 'I6(I u(I(I (I0)I o)I)I )I**I i*I*I *I$+I c+I+I +I,I ],I,I ,I-I W-I-I -I.I Q.I.I .I/I K/I/I /I0I E0I0I 0I 1I ?1I}1I 1I1I 92Iw2I 2I2I 33Iq3I 3I3I -4Ik4I 4I4I '5Ie5I 5I5I !6I_6I 6I6I 7IY7I 7I7I 8IS8I 8I8I 9IM9I 9I9I 	:IG:I :I:I ;IA;I ;I;I ;I;<I z<I<I <I5=I t=I=I =I/>I n>I>I >I)?I h?I?I ?I#@I b@I@I @IAI \AIAI AIBI VBIBI BICI PCICI CIDI JDIDI DIEI DEIEI EIEI >FI|FI FIFI 8GIvGI GIGI 2HIpHI HIHI ,IIjII IIII &JIdJI JIJI  KI^KI KIKI LIXLI LILI MIRMI MIMI NILNI NINI OIFOI OIOI PI@PI PIPI PI:QI yQIQI QI4RI sRIRI RI.SI mSISI SI(TI gTITI TI"UI aUIUI UIVI [VIVI VIWI UWIWI WIXI OXIXI XI
YI IYIYI YIZI CZIZI ZIZI =[I{[I [I $tIshowlegend¡y\                                        ף=>?m?|>.>.>>M>>Յ>~>>t>e!>>7Y>O>*o>>H>?k2?W*?$?'?f?r??*?;?;?NF?ͷ??M\7?4?0?5N?mf?Hc?`?.a?z`?$\?;d?:c??d?_?-W[?V?(T?)P?tM?PK?K?P?R?R?S?c]Q?haO?Q?CN?L?J?k_I?NH?RG?E?,C?nFC?(A?U?T?{tT?LgU?ES?#S?h*Q?T?R?yQ?lgQ?NP?$O?^oQ?f@O?"P?sN?L?L?Y[?{3Z?-Y?
'X?>W?zhU?+T?<-S?^zS?rR?|gQ?P?O?2Q?P?#O?N?~N?@U?qT?S?R?&IR?*Q?VR?Q?P?P?P?'Q?Q?8	P?@8O?KN?ZM?L?'K?=K?84J?|R?wR?9iQ?P?O?O?O?ѸN?lM?z|M?5M?L?MCL?`K??K?J?nJ?"I?{$I?ťJ?OI?M?SN?M?GN?WN?O?|O?]O?N?N?tgM?AL?
EL?L?K?M?!MM?L?#L?lK?\M?uM?L?hM?bL?{M?M?$L?xL?L?XL?*L?MK?:K?8K?K?CJ?7lJ?2I?OI?H?zLH?NG?ʂG?KF?F?>E?{E?E?ȤE?F,E?ZF?F?5UF?ڱE?
E?D?RD?,D?_C?eC?^DC?C?B?B?B?LB?~A?FA?@?@?R@?D@?S@?g??	A?A?@?{d@?{A?@?@?C@?g????<??@??%U??>???Y%??>?>?_>?e>?=?ik=?<?<?=<?
<?	<?y>?[=?M=?=?)=?b=?6=?2>?=?L{=?q->?M>?Z*>?y=?=?=?F>?(>?=zB?B?jA?A?bA?A? A?B?(B?iA?UA?OA?%A?)A?@?A?KrA?xTB?uB?P\B?PB?iB?AB?C?C?C?eC?|C?vC?C?pC??C?B?B?}TB?B?SB?`B?uB?_B?VB?B?A?xA?96A?tA?#@?B?VB?G/B?%A?A?A?GwA?<A?A?@?y@?gB?fB?B?B?B?fB?WdB?SB?&B?A?A?}A?EA?:A?
A?@?#@?q@?R@??@?@???Du??!Y??=??>?`????ݴ??/A?p$B?
B?B?LsB?CB?^B?8B?CA?A?}A?OA?A?LB?TB?B?B?B?7{B?1B?pA?YA?nA?A?"@?@?e@?5@?3@?,????L??_??F??s??????l??A????>?>?dR>?3J>?>?Q>?>?%>?>?]>?AT>?>?>=?=?v>?c	>?T#>?=?z=? >?>?>?D>?z>?=?U=?Ҙ=?џ=?p=?>?Ư>?f>?>?dF>?=?>?>?\R>?X>?'>?j>?~>?&j>?S>?DL>?>?I=?W=?=?X=?6)=?=?3<?t=?!=?=?=?=?=?w=?z=?o=?@??>?>?*>?V>??3>?!>?*=?=?=?=?=?ߴ=?=?v=?G=?*=?=?<?R<?<?y<?IX??"????3??[>?>?>?]>?;.>??7>?>?y=?C=?=?=?=?=?=? >?=?ߦ=?g=?d=?~=?_=?p=?F=?+=?4=?=?l<?5<?o<?ޕ<?'v<?<?<?Ӱ<?@<?}<?y<?u:<?u
<?";?;?m;?r;?5<;?c;?N:?G:?:?:?{:?Xl:?[:?.C:?!:?(:?:?:?kV:?i:?:?]
:?9?@9?<?h;?;?;?;?;?;?ό;?s;?-p;?U;?JW;?0;?;?:??:?O:?:?x|?lg?}d?UG?,??i?ƞ??-??o?`?9?7?7٠?p??u?|W?*?!??͟?ᬟ??U?b?4??͠?8??j?=??<?Yҟ?Ġ?n?=????5??˞??iÞ??S?a?0?%?v?Н???`]?=5?	??ޜ?ɜ??Cv?I?????0?K?g?D9??_?;????Ր?}?h?\?QC?w??ٙ?4?ݜ?}?O?)? ??)Ø???Yd?J?L1?Y4?{??j?җ????]?iA?&??ؖ?c?p?'?e??Y?4???+??z?#???k?=?N7???ٔ??:?觔?Ȕ?Ѫ?ݩ?R?og?"_?%K?U??!??=??N͔???w|?Q??ߔ?U?۔????y?i?K?-??W?Փ??"?n?us?zW?9? ?	?R?3??}?*
??̒???B?n^?h??1?$???P֑??௑??u?j?N?z7?z?5?5ݐ???0?+`?I@?K$?
?:??W??l?A?5?p?\?Q?`0?o??ێ?(?Ď?Y??y?jY?M?.??H?{>?F2????΍?幍?ڡ?W?_m?M?<F?0?&?!????!ی??l?F?~r?`?L?3?I%?
?P?׋??i?T?4?h?t\?mO?6?+?U? ?X?Њ?m?.?S?r?id?cJ?<???/?̉?d??ᇉ?o?f?P?s6?f@?.?;q?T?I?(?? ??&ډ?뿉??͌?n?Ne?9H?:?0??5?q?Ј?V?Ү???e?wH?1?>?/?2?~?F?և?*Ƈ???!??Z?h}?h?V?4J?q?+?typescatterx\  ?   @  @@  @  @  @  @   A  A   A  A  A   B  HB  pB  B  B  B  B  HC  C  C  C  D  /D  HD  aD  zD  D ;E  zE @E E E  E F @F +F ;F  KF ZF `jF  zF ЄF F pF @F F F F F PF  F F F F `F 0F  F  G G G G G pG XG @G ( G $G 'G +G /G 3G 7G ;G h?G PCG 8GG  KG OG RG VG ZG ^G bG xfG `jG HnG 0rG vG  zG }G G ܂G ЄG ĆG G G G G G |G pG dG XG LG @G 4G (G G G G G G G ԭG ȯG PG DG 8G ,G  G G G G G G G G G G G G G G xG lG `G TG HG <G 0G $G G G  G G G G  H H H H H H H H H 	H 
H H H H H H H H |H vH pH jH dH ^H XH RH LH FH @H :H 4H .H ( H "!H "H #H $H 
%H &H &H 'H (H )H *H +H ,H -H .H /H 0H 1H 2H 3H 4H 5H 6H 7H 8H 9H :H ;H z<H t=H n>H h?H b@H \AH VBH PCH JDH DEH >FH 8GH 2HH ,IH &JH  KH LH MH NH OH PH PH QH RH SH TH UH VH WH XH YH ZH [H \H ]H ^H _H `H aH bH cH dH ~eH xfH rgH lhH fiH `jH ZkH TlH NmH HnH BoH <pH 6qH 0rH *sH $tH uH vH wH xH yH  zH zH {H |H }H ~H H kH H eH H _H ܂H YH փH SH ЄH MH ʅH GH ĆH AH H ;H H 5H H /H H )H H #H H H H H H H H H H H H H |H H vH H pH H jH H dH H ^H ۗH XH ՘H RH ϙH LH ɚH FH ÛH @H H :H H 4H H .H H (H H "H H H H H H H H 
H H H H H {H H uH H oH H iH H cH H ]H ڬH WH ԭH QH ήH KH ȯH EH °H ?H H 9H H 3H H -H H 'H H !H H H H H H H H 	H H H H H zH H tH H nH H hH H bH H \H H VH H PH H JH H DH H >H H 8H H 2H H ,H H &H H  H H H H H H H H H H H H H yH H sH H mH H gH H aH H [H H UH H OH H IH H CH H =H H 7H H 1H H +H H %H H H H H H H H H H H H H ~H H xH H rH H lH H fH H `H H ZH H TH H NH H HH H BH H <H H 6H H 0H H *H H $H H H H H H H H H H H H  H }H H wH H qH H kH H eH H _H H, I k I I  I&I eII I I _II II YII II SII II MII II GII II AII II ;IyI II 5	Is	I 	I	I /
Im
I 
I
I )IgI II #IaI II I[I II IUI II IOI II III II ICI II I=I |II I7I vII I1I pII I+I jII I%I dII II ^II II XII II RII II LII II FII II @I~I II :IxI II 4IrI II .IlI II ( If I  I I "!I`!I !I!I "IZ"I "I"I #IT#I #I#I $IN$I $I$I 
%IH%I %I%I &IB&I &I&I &I<'I {'I'I 'I6(I u(I(I (I0)I o)I)I )I**I i*I*I *I$+I c+I+I +I,I ],I,I ,I-I W-I-I -I.I Q.I.I .I/I K/I/I /I0I E0I0I 0I 1I ?1I}1I 1I1I 92Iw2I 2I2I 33Iq3I 3I3I -4Ik4I 4I4I '5Ie5I 5I5I !6I_6I 6I6I 7IY7I 7I7I 8IS8I 8I8I 9IM9I 9I9I 	:IG:I :I:I ;IA;I ;I;I ;I;<I z<I<I <I5=I t=I=I =I/>I n>I>I >I)?I h?I?I ?I#@I b@I@I @IAI \AIAI AIBI VBIBI BICI PCICI CIDI JDIDI DIEI DEIEI EIEI >FI|FI FIFI 8GIvGI GIGI 2HIpHI HIHI ,IIjII IIII &JIdJI JIJI  KI^KI KIKI LIXLI LILI MIRMI MIMI NILNI NINI OIFOI OIOI PI@PI PIPI PI:QI yQIQI QI4RI sRIRI RI.SI mSISI SI(TI gTITI TI"UI aUIUI UIVI [VIVI VIWI UWIWI WIXI OXIXI XI
YI IYIYI YIZI CZIZI ZIZI =[I{[I [I $tIshowlegend¡y\                    ؉?  ?0LABANo:A@@S^c@/@]k-@M@@?Q?d@2&@@?]?f?E?ؕ?2ۈ?DyM?,R?0?!?5?N??? x9?0?2?*?K0?ϒ*?5$?>c!?G$?+?(?2$?&)?|3?2?28?Ȁ4?͹8?5?Q2?1?.?Hq,?o+?p*?ȯ'?&?%$?%?#?L"?$?#?2"?`"?P"?@!?4 ?\*"?A&?$?1$?$#?Y"?K6!?!? ?K4?ߍ3?2?41?20?/?.?,/?0?m0?/?i.???ӭ>?K>?Q@?)B?}PB?A?@?vA?A?NB?'B?rA?C?B?	)D?C?q
F?ιD?WD?C?B?B?ePA?@?d@?A?LA?r@?D?{C?C?|B?C?0B?YA?e@?3@?@?X???e??>???W>?O=?<?e<?a;?ڽ:?S:?:?A9?c#B?B?A?TeA?B?%AB?^A?A?DW@?CH@?gA?A?J@?@?4C?9B?SA?tA?AA?B?(A?ˮA?tA?B?1AB?-B?xA?XC?B?tB?
B?kA?@?@?N@?V@?	1@?R??*??d??$@???^n??q??&??J??4??%7??7??<>?;>?=?=?l=?7=?mA?F@?X@???WC??Gq??>?q>?-u>?=?/=?T==?i=?d	=?ǣ<?=?IH?fH?G?G?jG?,RG?F?rG?%J?I?UI?
H?}H?T H?z	H?G?@G?IF?|WF?oE?E?DE?HD?ɊD?)D?HE?D?yD?&D?H?(H?G?iG?oG?hG?F?iF?7F?E?E?9E?JD?oD?OD?@MD?C?C?FC?9B?B?$[B?B?A?B?B?{B?2B?	A?A?A?A?*A?@?x@?@?Y??l@?^@?@?;3@???_??o??G5??{>?ɧ>?@?w@?A@?@?d@?$8@?U@?>0@?y??mA?لA?lA?c<A?J#A?@?A?3@?e@? u@?@?+n@?@?@?@?B?fD?`D? D?0C?SC?D?dD?,JD? D?C?C?]C?mFC?5JC?8B?B?1B?B?H=B?A?y
B?A?A?9vA?A?RA?@?@?A?aYA?&A?A??A?ðA?NA?nA?A?oA?!A?}A?TA?XA?8A?g@?:@?KA?A?nA?dkA?HA?n@?@?A?@?1@?)A?D?C?`C?C?C?C?
PC?guC? $C?D?|D? D?`D?cD?qD?$+D?\<D?D?&C?C?E?bD?P?P?CP?T;P?,P?AP?0UP?2P?@O?O?<O?CO?0OO?uO?c>O?O?EN?yN?HN?9N?<kN?EN?-sN?N?M?IM?0fM?+M?ΊM?{M?XM?cM?F!M?L?~L?YL?L?K?K?K?HK?VeK?nK?4K?J?uK?
K?J?J?iJ?J?3<J?J?GI?$J?I?I?dI?GI?I?tH?H?H?H?nH?q<H?G?G??~G?wG?JG?RIG?^BG? G?F?F?8F?BE?YF?eF?F?oF?~F?OF?4F?E?
F?E?E?E?dE?$E?g}E?OE?\0E?WE?&E?D?'D?D?oD?=D?
D?lD??D?0D?%C?C?tC?WC?!C?C?lpC?c?C?C?B?B?8B?B?qB?:B?hB?IB?.B?9B?B?$B?1OB?&B?B?oA?A?A?A?3A?A?|A?xgA?5A?	A?@?G@?_@?${@?]@?p@?@?Ӛ@?@?K@?@?tq@?S@?>+@?[??????????c????ф??hV??1(????>?y>?3??>?O6??d>? ??$>?>?8>?^>?v>?T]>?8>?>?=?=?y=?u=?>?;>?]->?$>?>?"K??	$??o??R	??>?>?>?j>?y>?>?X>?<X>?8>?F>?1>?`>?I>?>?y=? =?>?f=?>?=?9=?p=?=?=?=?U=?=?b=?=?=?T=?O=?0=?8=? =?8=?=?Q<?<?E<?9<?<?<?<?Ӭ<?v<?d<?Du<?<?z<?<?=?<?=?ڕ=?m=?O=?l2=?2=?=?=?ځ=?=?=?=?e=?=?=?=?>?>?K>?>?>?>?'W??F??!????H??9>?>?`????h??>J??S??????¥????????ѕ??u??{??Z??7??8??9?? ??d??m9????o????F??η??[??;w??[????N??n??k??j??W??B??t????d??C??d??V??M??%??b????>? ??t"?? ??j>?>?i>?7>?>?
>?p>?bX>?+>?>?O>?>?2>?G>?>?}>?a>?O>?93>?)>?J>?=?=?=?=?=?=?@?@?k@?u@?K_@?O@?^@?jS@?f0@?@?????Z??S??r??iU??F??T???%????V>?8????{>?V>?>?כ>?>?֒>?>?Ń>?v>?=S>?M`>?;B>?{>?{>?a>?S>?,>?n>?a>?ec>?O>?@>?P>?R>?=?=?e=?=?R=?=?{=?V=?I=?(=?(=?/=?"=?r==?D=?+=?=?s=?%=?<?<?#<?j<?<?}<?To<?CT<?><?/<?J<?YR<?T:<?m5<?(<?0<?F*<?<?<?};?3L<?UE<?:<?]F<?<?<?<?W<?'=?=?"<?<?<?9<?C<?<?<?<?<?<?<?K<?<?|<?}<?m<?YN<?S<?D<?<<?<?<?;?;?;?a;?;?;?;?;?;?u;?;?̴;?d;?;?;?*};?l;?O;?iE;?6;?!;?>:?:?:?E:?ے;?m;?H;?.H;?3;?~&;?4;?:?2:?:?:??:?Z_:?O:?O:?:?b:?c:?Y:?Y:?S:?G:?
+:?J:?0:?):?! :?+];?typescatterx\  ?   @  @@  @  @  @  @   A  A   A  A  A   B  HB  pB  B  B  B  B  HC  C  C  C  D  /D  HD  aD  zD  D ;E  zE @E E E  E F @F +F ;F  KF ZF `jF  zF ЄF F pF @F F F F F PF  F F F F `F 0F  F  G G G G G pG XG @G ( G $G 'G +G /G 3G 7G ;G h?G PCG 8GG  KG OG RG VG ZG ^G bG xfG `jG HnG 0rG vG  zG }G G ܂G ЄG ĆG G G G G G |G pG dG XG LG @G 4G (G G G G G G G ԭG ȯG PG DG 8G ,G  G G G G G G G G G G G G G G xG lG `G TG HG <G 0G $G G G  G G G G  H H H H H H H H H 	H 
H H H H H H H H |H vH pH jH dH ^H XH RH LH FH @H :H 4H .H ( H "!H "H #H $H 
%H &H &H 'H (H )H *H +H ,H -H .H /H 0H 1H 2H 3H 4H 5H 6H 7H 8H 9H :H ;H z<H t=H n>H h?H b@H \AH VBH PCH JDH DEH >FH 8GH 2HH ,IH &JH  KH LH MH NH OH PH PH QH RH SH TH UH VH WH XH YH ZH [H \H ]H ^H _H `H aH bH cH dH ~eH xfH rgH lhH fiH `jH ZkH TlH NmH HnH BoH <pH 6qH 0rH *sH $tH uH vH wH xH yH  zH zH {H |H }H ~H H kH H eH H _H ܂H YH փH SH ЄH MH ʅH GH ĆH AH H ;H H 5H H /H H )H H #H H H H H H H H H H H H H |H H vH H pH H jH H dH H ^H ۗH XH ՘H RH ϙH LH ɚH FH ÛH @H H :H H 4H H .H H (H H "H H H H H H H H 
H H H H H {H H uH H oH H iH H cH H ]H ڬH WH ԭH QH ήH KH ȯH EH °H ?H H 9H H 3H H -H H 'H H !H H H H H H H H 	H H H H H zH H tH H nH H hH H bH H \H H VH H PH H JH H DH H >H H 8H H 2H H ,H H &H H  H H H H H H H H H H H H H yH H sH H mH H gH H aH H [H H UH H OH H IH H CH H =H H 7H H 1H H +H H %H H H H H H H H H H H H H ~H H xH H rH H lH H fH H `H H ZH H TH H NH H HH H BH H <H H 6H H 0H H *H H $H H H H H H H H H H H H  H }H H wH H qH H kH H eH H _H H, I k I I  I&I eII I I _II II YII II SII II MII II GII II AII II ;IyI II 5	Is	I 	I	I /
Im
I 
I
I )IgI II #IaI II I[I II IUI II IOI II III II ICI II I=I |II I7I vII I1I pII I+I jII I%I dII II ^II II XII II RII II LII II FII II @I~I II :IxI II 4IrI II .IlI II ( If I  I I "!I`!I !I!I "IZ"I "I"I #IT#I #I#I $IN$I $I$I 
%IH%I %I%I &IB&I &I&I &I<'I {'I'I 'I6(I u(I(I (I0)I o)I)I )I**I i*I*I *I$+I c+I+I +I,I ],I,I ,I-I W-I-I -I.I Q.I.I .I/I K/I/I /I0I E0I0I 0I 1I ?1I}1I 1I1I 92Iw2I 2I2I 33Iq3I 3I3I -4Ik4I 4I4I '5Ie5I 5I5I !6I_6I 6I6I 7IY7I 7I7I 8IS8I 8I8I 9IM9I 9I9I 	:IG:I :I:I ;IA;I ;I;I ;I;<I z<I<I <I5=I t=I=I =I/>I n>I>I >I)?I h?I?I ?I#@I b@I@I @IAI \AIAI AIBI VBIBI BICI PCICI CIDI JDIDI DIEI DEIEI EIEI >FI|FI FIFI 8GIvGI GIGI 2HIpHI HIHI ,IIjII IIII &JIdJI JIJI  KI^KI KIKI LIXLI LILI MIRMI MIMI NILNI NINI OIFOI OIOI PI@PI PIPI PI:QI yQIQI QI4RI sRIRI RI.SI mSISI SI(TI gTITI TI"UI aUIUI UIVI [VIVI VIWI UWIWI WIXI OXIXI XI
YI IYIYI YIZI CZIZI ZIZI =[I{[I [I $tIshowlegend¡y\                                        9c=">dff>U?h>ʭN>&??33?o?q
>q>>#>|>e>Q>m>L>aP>m>}>= ?X?g?N?Y?EL?ǜb?U?`N?ȁF?U?hN?20J?mC? tE?j@?:?7?z9?N>?Wj?Is?em?h?vc?k?(k?g?qx?~Ys?ro?]k?mg?cd?fc?`?mp]?	Z?nV?(T?fQ??O?M?L?4,J?BI?YH?2SF?D?jC?C?B?
?A?9A???`A?0A?a??g??^B?4B?/A?FQ@?>?{=?<?<?;?*:?49?!89?L_8?7?8?6T:?BX;?9?9?V8?Տ9?8?2;?C<?:?:?:?:?7?7?H6?65?4?^4?r4?j4?3x6?'5?4?4?iD5?j5?5?6?97?QK7?DU7?{7?']7?as6?5?95?(5?D6?27?6?86?25?5?^i4?4?j4?c3?3?3?j|3?,T7?6?z6?6? h5?;4??4?_3?;?[<?JK<?e<?#K?L?W[L??M?U/M?[?7[?FZ?8Z?Z?:Y?	Y?(Y?wX?HX?4X?!X?mPW?UW?rV?1V?U?/U?T?S?S?QsS?
5S?S?S?R?dQ?Q?<Q?P?P?P?P?ɜP?	P?xO?!O?P?O?nO?O?5N?N?)N?!VN?bN?_M?7-M?BsM?L?L?eM?m3M?N?M?nM?\%M?ìL?HL?HM?OM?IM?L?9[L?K?ϖK?/K?<J?sGJ?I?\I?`I?? I?H?2 I?$H?<[H?;hH?H?#H?G?7G?+G?Z?PZ?=Y?}vY?7X?X?vX?X?A-X?aW?wW?W?nV?{V?4V?U?@IU?r6U?T?QU?T?QbT?S?S?*S?R?R?IS?R?sR?R?uR?~R?MR?jR?HR?Q?Q??Q?Q?*Q?NQ?$VQ?Q?P?	P?P?0P?k<Q?4P?ېP?P?mP?<P?]5P?O?RO?O?~Q?OQ?!Q?	Q?P?O~P?P?.nQ?hQ?P?]Q?VHQ?Q?P?;rP?:P?tP?-Q?`P?	Q?oP?OT?/S?S?߀S?S?YS?4R?nR?R?gtR?G4R?R?Q?zQ?Q?4TQ?Q?gP?P?pP?P?\P?P?P?O?,O?O?^O?[2O?(N?
O?N?BqN?n)N?sN?N?M?0M?M?6M?M?*M?/M?M?L?L?L?	L?ϞL?zL?BL?i&L?AK?K?K?K?;aK?QK?yJ?dJ?RK?TK?.J?J?OCJ?J?YI?I?gI?.I?$eI? I?XH?I?^6I?4I?=I?f9I?I?GH?{K?K?6nK? K?J?J?mJ?~TJ?pHJ?J?UJ?7J?*I?J?!J?I?RI?	I?˜I? [I?FI?,I?I?sH?H?yH?oH?DH?:MH?H?G?_wH?`XH?`&H?G?$H?G?G?G?zG?ĊG?_PG?7G?8G?eG?%{G?4H?DH?ZG?G?G?qG?XG?G?F?F?F?pF?$xF?g?F?/<F?%F?F?JF?9TF??F?!F?E?OE?,E?FE?hTE?S<E?E?FD?D?D?ɣD?xD?NE?HE?Z E?D?D?BD?JD?D?{D?GD?]D?jD?D?|D?D?[D?5D?C?C?D?C?'D?D?xC?C?C?pC?~C?*JC?R C?ZB?6B?B?~B?zB?B?:B?B?}B?rSB?T+B?B?5"B?B?@F?*F?E?&E?E?F?F?mF?	F?F?˘F?F?F?G?,F?}H?I?H?wH? H?MjH?3H?lH?G?G?iG?pG?@G?G?0G?G?%F?F?ZF?KN?ԐN?=N?N?-N?pN?^SN?)!N?M?M?wM?zM?@M?4M?ZM?M?HXM?(M?aM?9L?(L?5L?L?L?zM?5mM?vM?GM?rM?1OM?M?	M?M?QM?KQ?gQ?|TQ?AMQ?YQ?OQ?UP?@P?P?P?P?mP?JP?P?P?P?_O?yO?SO?*O?O?^O??4O?'|O?;O?O?oO?4O?:&O?U+O?&O?)O?VO?]O?N?N?O?N?O?N?N?ûN?N?N?rN?MN?2N?aM?hM?M?M?z~M?iM?EM?,M?M?zM?\IM?N?ZN?"AN?N?M?N?M?M?<M?ӬM?=M?fM? O?N?N? N?N?VN?\N?1N?N??M?M?M?[M?!rM?ZM?iM?4N?LN?hM?M?M?M?ӿM?M?bM?M?/bM?FM?T!M??M?N?N?qN?P?8O?O?O?ƇO?|O?TXO?:IO?O?yN?@N?O?pN?öN?5N?tN?QmN??<N?iN?iHN?7N?N? M?M?pO?IO?4O?w O?O?N?N?6O?;N?O?{O?O?O?{eO?JO?<.P?wP?l P?mP?4P?k)P?
P?CP?P?cP?CO?`O?2O?O?O?%pO?vGO?VO?O?YO?CO?8O?O?$O?O?O?O?uO?O?O?,YO?\O?CO?O?N?N?N?1O?N?O?jN?N?N?vO?VO?1O?nO?RO?)O?DO?*O?VN?N?N?N?}yN?:N?MN?N?wN?qXN?26N?iP?+P?P?yP?P?٣P?xP?|eP?GP?c=P?|'P?!P?P?P?fNP?#PP?CP?F P?P?#O?O?"O?O?BP?P?P?O?KO?tP?bYP?DMP?GP?;.P?cP?O?CO?O?O?O?O?OO?yO?QmO?MO?2O?mO?AO?O?O?O?ҍO?iO?wO?EO?sO?fO?EO?1%O?O?:O?#Q?Q?Q?Q?Q?,Q?YbQ?<Q?q"Q?Q?PP?P?οP?P?6qP?<JP?.P?P?P?P?MuP?I`P?=P?rP?O?P?O??O?>O?O?WO?֙O?J}O?`O?2MO??O?AO?\O?LO?:O?~O?N?(N?N?1N?RN?N?N?5pN?2o?typescatterx\  ?   @  @@  @  @  @  @   A  A   A  A  A   B  HB  pB  B  B  B  B  HC  C  C  C  D  /D  HD  aD  zD  D ;E  zE @E E E  E F @F +F ;F  KF ZF `jF  zF ЄF F pF @F F F F F PF  F F F F `F 0F  F  G G G G G pG XG @G ( G $G 'G +G /G 3G 7G ;G h?G PCG 8GG  KG OG RG VG ZG ^G bG xfG `jG HnG 0rG vG  zG }G G ܂G ЄG ĆG G G G G G |G pG dG XG LG @G 4G (G G G G G G G ԭG ȯG PG DG 8G ,G  G G G G G G G G G G G G G G xG lG `G TG HG <G 0G $G G G  G G G G  H H H H H H H H H 	H 
H H H H H H H H |H vH pH jH dH ^H XH RH LH FH @H :H 4H .H ( H "!H "H #H $H 
%H &H &H 'H (H )H *H +H ,H -H .H /H 0H 1H 2H 3H 4H 5H 6H 7H 8H 9H :H ;H z<H t=H n>H h?H b@H \AH VBH PCH JDH DEH >FH 8GH 2HH ,IH &JH  KH LH MH NH OH PH PH QH RH SH TH UH VH WH XH YH ZH [H \H ]H ^H _H `H aH bH cH dH ~eH xfH rgH lhH fiH `jH ZkH TlH NmH HnH BoH <pH 6qH 0rH *sH $tH uH vH wH xH yH  zH zH {H |H }H ~H H kH H eH H _H ܂H YH փH SH ЄH MH ʅH GH ĆH AH H ;H H 5H H /H H )H H #H H H H H H H H H H H H H |H H vH H pH H jH H dH H ^H ۗH XH ՘H RH ϙH LH ɚH FH ÛH @H H :H H 4H H .H H (H H "H H H H H H H H 
H H H H H {H H uH H oH H iH H cH H ]H ڬH WH ԭH QH ήH KH ȯH EH °H ?H H 9H H 3H H -H H 'H H !H H H H H H H H 	H H H H H zH H tH H nH H hH H bH H \H H VH H PH H JH H DH H >H H 8H H 2H H ,H H &H H  H H H H H H H H H H H H H yH H sH H mH H gH H aH H [H H UH H OH H IH H CH H =H H 7H H 1H H +H H %H H H H H H H H H H H H H ~H H xH H rH H lH H fH H `H H ZH H TH H NH H HH H BH H <H H 6H H 0H H *H H $H H H H H H H H H H H H  H }H H wH H qH H kH H eH H _H H, I k I I  I&I eII I I _II II YII II SII II MII II GII II AII II ;IyI II 5	Is	I 	I	I /
Im
I 
I
I )IgI II #IaI II I[I II IUI II IOI II III II ICI II I=I |II I7I vII I1I pII I+I jII I%I dII II ^II II XII II RII II LII II FII II @I~I II :IxI II 4IrI II .IlI II ( If I  I I "!I`!I !I!I "IZ"I "I"I #IT#I #I#I $IN$I $I$I 
%IH%I %I%I &IB&I &I&I &I<'I {'I'I 'I6(I u(I(I (I0)I o)I)I )I**I i*I*I *I$+I c+I+I +I,I ],I,I ,I-I W-I-I -I.I Q.I.I .I/I K/I/I /I0I E0I0I 0I 1I ?1I}1I 1I1I 92Iw2I 2I2I 33Iq3I 3I3I -4Ik4I 4I4I '5Ie5I 5I5I !6I_6I 6I6I 7IY7I 7I7I 8IS8I 8I8I 9IM9I 9I9I 	:IG:I :I:I ;IA;I ;I;I ;I;<I z<I<I <I5=I t=I=I =I/>I n>I>I >I)?I h?I?I ?I#@I b@I@I @IAI \AIAI AIBI VBIBI BICI PCICI CIDI JDIDI DIEI DEIEI EIEI >FI|FI FIFI 8GIvGI GIGI 2HIpHI HIHI ,IIjII IIII &JIdJI JIJI  KI^KI KIKI LIXLI LILI MIRMI MIMI NILNI NINI OIFOI OIOI PI@PI PIPI PI:QI yQIQI QI4RI sRIRI RI.SI mSISI SI(TI gTITI TI"UI aUIUI UIVI [VIVI VIWI UWIWI WIXI OXIXI XI
YI IYIYI YIZI CZIZI ZIZI =[I{[I [I $tIshowlegend¡y\                                        +?L?H?3*#??>
S>b>`L>>o>dζ>۪>g??>,?;i>tv?nX?v?-Ջ??fn?f?&vh?h?[?أW?U\Q?N?U??a?VX?d???Y??? ?;??I?京?VM?:?V0??Bѝ?"?m?Y?4?q?ӈ?Ȳ?C?ו?]ʕ?P?B??5??0?ϋ?`?A?v?H?G?o?N?$?j?V??B?>}?Ǆ|?5z?PQ}?{?ky?^w?\iu?Vs?֭s?آq?`xq?ao?No?Xn?m?]k?:k?j?h?z?7Hy?qx?v?e??0?ݮ?M?l?	???~?D}?{?/{?i{?Ty?x??w? w?y?)x?Q??ލ?H?H ??15?֊?F?^?,?Ή???#^??m0??U?؅?=??@?R?=?;?5?͖?A?%2?DԂ?8???K\?l?5??u??~?.?~?~?e}?!?Q?1Z? ~?Z~?l}?|?{?
){?Zj{?J\z?ay?x?8x?^w?w?v?v?Xu?Јt?s?5	s?_r?iq?ur?q?q?8q?s}p?o?o?n?n?}n?VRn?Im? m?wl?k?(k?j?j?`j? j?+i?j?j?i?Pi?h?Wh?Ah?Kh?ng?g?yf?7uf?ݿe?]-e?\d?,Ed?+c?	c?Yc?b?jec?4b?3b?Ab?a?Ba?`?`?`?`?`?_?^?`?`?V_?b_?^?ծ^?^?@^?]? ^?'b?KSb?a?fa?Qb?a?ya?Aqa?
a?a?e`?Q`?_?D_?O`?_:`?֖`?;
`?_?:_?^?^?$S^?_Q^?5^?d]?]?]? ]?]?]?pJ^?x^?^?]?]?i]?%O]?Ҧ]?*]?,]?|\?\?՘\?3\?8[?$\[?Z?Z?LZ?g2Z?1Y?rY?!HY?Z?Y?gZ?Z?Y?]Y?/Y? Y?5sY?vY?X?-oZ?fBZ?[?[?_[?q[?d*[?Bb?a?Oa?S-a?;`?`?ٿc?e?d?d?Pd?%sd?X&d?c?[c?0Hc?@(c?d?,d?uc?c?;c?0b?b?Nb?b?a?za?la?`?ޯ`?}`?a?`?H4`?_?_?]_? _?B_?^?^?+^?w^?j;^??^?z^?~]?l]?q]?]?]?B2]?2]?˲]?Z]?@]?)]?]?]?]?}]?3]?c\?\?J\?\?\?;\?̡\?\?r\?\?hm\?@\?S\?\?yS\?q\?k[?t[?B[?b
[?[?Z?MZ?;Z?s4Z?VZ?LY?Y?Y? fY?1CY?=Y?Y?rX?X?X?ΏX?X?X?X?9X?X?LX?!X?W?QW?W?W?W?7W?VW?@W?ݺV?sV?wLV?<V?V?U?|U?~U?0PU?U?T?LaU?,U?T?<T?T?T?3T?m<U?RT?sT?GU?TT?wT?LoT?j]U?,U?d U?8T?T?_T?7(T?S?0S?S?CS?tS?[S?E)S?/S?<R? R?ТR?kR?(3R?Q?Q?UR?:R?R?Q?R?lQ?}Q?fQ?Q?&Q?tQ?NQ?<Q?D4Q?Q?R?VQ?9Q?FQ?lQ?nQ?9zQ?5Q?%UQ?VQ?PQ?Q?OQ?vQ?taQ?gxQ?Q?CTQ?TQ?=FQ?Q?Q?P?
P?P?^P?g2P?KP?v1P?P?O?aO?)P?BsP?JP?|P?O?O?O?O?9RP?P?xO?
O?O?xO?3VO?O?dN?N?N?rN?>N?N?O?N?KN?N?cIN?N? |N?ON?VN?&KN?7N?M?M?4M?ّM?aM?>M?M? M?L?JL?]vL?DL?L?K?K?K?N?]N?mQN?c=N?N?N?sN?N?VN?bN?9N?+N?,N? N?M?M?M?!M?M?M?^M?5;M?sM?FVM?vOM?.M?eM?L?-L?ӜL?L?rL?zUL??L?L?qK?PL?K?J	L?K?cK?|K?
OK?%K?aJ?3K?J?J?J?yJ?sJ?!J?%J?J?YJ?ZK? K?J?"J?vJ?J?J?OVJ?MJ??J?J?uI?*I?I?OI?vI??I?.I?I?I?9H?H?xH?H?A!I?I?3H?5H?ȢH?oyH?H?hH?{H?lH?^H?^H?Y<H?H?eH?G?8G?G?IG?'G?fG?>G?UG?CG?x+G?eG?XF?F?F?F?F?F?F?`uF?eYF?.DF?F?+E?qE?E?E?E?E?E?E?oE?{E?`E?]E?9AE?xE?HE?&E? D?D?D?D?D?D?D?.fD?gpD?FUD?<D?qqD?D?HD?nD?/D?D?yD?dD?(hD?jD?{D?SD?lLD?PD?`/D?(D?	D?4C?C?3D?D?jC?D?C?C?C?NC?lC?C?C?x_C?>cC?<lC?9YC?;5C?#C?C?B?B?B?RB?DB?B?B?B?ܔB?P~B?}B?9\B?_B?EB?4B?B?A?iA?vA?éA?A?A?'A?mA?hA?A?	A?OsA?XdA?1SA?3:A?RDA?FA?=A?A?sA?A?A?<pA?tA?eA?A?|A?A?<A?7B?	A?8A?A?A?A?oA?}bA?>A?7A?gA?A?i@?@?@?%@?@?@?@?@?EA?@A?a#A?sB?uB?`iB?EB?7+B?B?A?A?A?"C?VsC?hC?wC?lC?ZC?4C?)C?gC?B?B?0B?FB?*B?VsB?%WB?8B?(B?8B?B?B?B?B?B?<pB?CbB?AB?9B?(B?B?A?A?A?uA?A?A?A?QA?A?A?A?p|A?݊A?yzA?}A?A?A?A?oA?WA?lA?aRA?!TA?JA?1A?z$A?IA?.QA?IA?
?A?(%A?6A?@?@?cD?typescatterx\  ?   @  @@  @  @  @  @   A  A   A  A  A   B  HB  pB  B  B  B  B  HC  C  C  C  D  /D  HD  aD  zD  D ;E  zE @E E E  E F @F +F ;F  KF ZF `jF  zF ЄF F pF @F F F F F PF  F F F F `F 0F  F  G G G G G pG XG @G ( G $G 'G +G /G 3G 7G ;G h?G PCG 8GG  KG OG RG VG ZG ^G bG xfG `jG HnG 0rG vG  zG }G G ܂G ЄG ĆG G G G G G |G pG dG XG LG @G 4G (G G G G G G G ԭG ȯG PG DG 8G ,G  G G G G G G G G G G G G G G xG lG `G TG HG <G 0G $G G G  G G G G  H H H H H H H H H 	H 
H H H H H H H H |H vH pH jH dH ^H XH RH LH FH @H :H 4H .H ( H "!H "H #H $H 
%H &H &H 'H (H )H *H +H ,H -H .H /H 0H 1H 2H 3H 4H 5H 6H 7H 8H 9H :H ;H z<H t=H n>H h?H b@H \AH VBH PCH JDH DEH >FH 8GH 2HH ,IH &JH  KH LH MH NH OH PH PH QH RH SH TH UH VH WH XH YH ZH [H \H ]H ^H _H `H aH bH cH dH ~eH xfH rgH lhH fiH `jH ZkH TlH NmH HnH BoH <pH 6qH 0rH *sH $tH uH vH wH xH yH  zH zH {H |H }H ~H H kH H eH H _H ܂H YH փH SH ЄH MH ʅH GH ĆH AH H ;H H 5H H /H H )H H #H H H H H H H H H H H H H |H H vH H pH H jH H dH H ^H ۗH XH ՘H RH ϙH LH ɚH FH ÛH @H H :H H 4H H .H H (H H "H H H H H H H H 
H H H H H {H H uH H oH H iH H cH H ]H ڬH WH ԭH QH ήH KH ȯH EH °H ?H H 9H H 3H H -H H 'H H !H H H H H H H H 	H H H H H zH H tH H nH H hH H bH H \H H VH H PH H JH H DH H >H H 8H H 2H H ,H H &H H  H H H H H H H H H H H H H yH H sH H mH H gH H aH H [H H UH H OH H IH H CH H =H H 7H H 1H H +H H %H H H H H H H H H H H H H ~H H xH H rH H lH H fH H `H H ZH H TH H NH H HH H BH H <H H 6H H 0H H *H H $H H H H H H H H H H H H  H }H H wH H qH H kH H eH H _H H, I k I I  I&I eII I I _II II YII II SII II MII II GII II AII II ;IyI II 5	Is	I 	I	I /
Im
I 
I
I )IgI II #IaI II I[I II IUI II IOI II III II ICI II I=I |II I7I vII I1I pII I+I jII I%I dII II ^II II XII II RII II LII II FII II @I~I II :IxI II 4IrI II .IlI II ( If I  I I "!I`!I !I!I "IZ"I "I"I #IT#I #I#I $IN$I $I$I 
%IH%I %I%I &IB&I &I&I &I<'I {'I'I 'I6(I u(I(I (I0)I o)I)I )I**I i*I*I *I$+I c+I+I +I,I ],I,I ,I-I W-I-I -I.I Q.I.I .I/I K/I/I /I0I E0I0I 0I 1I ?1I}1I 1I1I 92Iw2I 2I2I 33Iq3I 3I3I -4Ik4I 4I4I '5Ie5I 5I5I !6I_6I 6I6I 7IY7I 7I7I 8IS8I 8I8I 9IM9I 9I9I 	:IG:I :I:I ;IA;I ;I;I ;I;<I z<I<I <I5=I t=I=I =I/>I n>I>I >I)?I h?I?I ?I#@I b@I@I @IAI \AIAI AIBI VBIBI BICI PCICI CIDI JDIDI DIEI DEIEI EIEI >FI|FI FIFI 8GIvGI GIGI 2HIpHI HIHI ,IIjII IIII &JIdJI JIJI  KI^KI KIKI LIXLI LILI MIRMI MIMI NILNI NINI OIFOI OIOI PI@PI PIPI PI:QI yQIQI QI4RI sRIRI RI.SI mSISI SI(TI gTITI TI"UI aUIUI UIVI [VIVI VIWI UWIWI WIXI OXIXI XI
YI IYIYI YIZI CZIZI ZIZI =[I{[I [I $tIshowlegend¡y\                                        >$I?tZ?V?rf?w]W?κA?H+?H)???Oϗ?	m?M? h?ӳe?P?	H?]^?Ǘ?ɥ?ٳ?஡??*J?r5??u?Ho?e?C_?Y?U?rT?`?q]?,a??.?ǝ?Y???}Җ?^?͐??`_?n?6??|i???a|?px?u?r?4o?q?r?Op?m?k?+i?4h?f?|pf?d?b?l`?
^?\?^?]?v%`?`?a?Pa?na?A_?Q]?q[?Y?GTX?tV?cT?j.S?Q?5P?IO?N?eM?K?+J?FI?ZrH?hG?PF?F?F?F?gE?nD?D?Y$D?C?m??F1?a??j?O?q??O?n??m?)?i??*?և?I?TՆ??s??µ?%?X̓??e??Á?<?Ȁ?$?y?~?a~?}?|?|?z9{?6z?z?y?:x?Zw?fTy?z?˱y?Ox?Dx??w?=w?Wv?"u?t?Ev?ry?Jx?w?1w?[v?u?Gu?=t?s?et?>iu?t?+#t?Yis?-r?q?+q?p?hKp?Fo?@o?Bpn?5m?:l?@l? l?]Qk?uj?-j?8i?Gi?~h?Gg?(g?TLh?Eg?rg?f?Nf?e?3e?Ge?+d?.d?.d?tc?Gc?Эb?b?Xb?^a?a?ja?.a?=`?dD`?_?*_?^?^>^?]?_?z_?g_?^?]^?<]?2]?F\?\?I[??F[?D[?|Z?Z?Z? IZ?Z?!Z?DY?X[Y?-Y?X?s?X?X?X?W?V?jV?)V?dU?EZU?U?#U?U?U?U?]U?/T?ٔU?U?U?dU?qU?T?ڞT?(T?>9V?aU?jV?UZ?4Z?A+Z?
Z??Z?~Z?Z?-$[?סZ??Z?8Y?Y?zY?Y?mY?FZ?йY?Y3Y?=X?%gX?
X?̪W?<W?V?pV?GV?V?U?dU?U?.T?/YU?U?|U?hU?AU?	U?7T?.T?8T?T?T?eT?gT?V?]V?7V?U?RU?͔U?+U?_T?xU?#U?:U?,	U?/T?T?T?T?#S?S?dS?S?S?jS? S?dR?LR?R?:Q?R?Q?Q?Q?Q?ZQ?JQ?$Q?Q?Q?Q?בQ?pQ?rQ?\Q?\Q?NRQ?DQ?P?pQ?:Q?Q?pQ?<:Q?Q?0P?3P?P?DQP?O?O?O?KO?LO?YO?fO?uN?N?uN?CN?N?SM?JN?N?{M?M?{M?{M?6M?oM?M?L?}L?vL?+5L?K?K?5L?cK?K?IK?eK?L4K?0K?K?|VK?K?J?pK?9K?J?WK?JK?K?YcK?K?CJ?J?ҽK?qK?
'K?,EL?]L?L?iL?*L?9L?K?QK?_K?K?J?!J?mJ?YM?/'M?L?L?F}L?=L?FL?@L? L?M?M?`M?"JM?P?`O?O?!P?3O?O?P?MO?ԔO?O?{O?TO?wO? O?GN?qN?N?PN?0N?%N?M?M?ҌM?PM?M?cM?.PM?#M?L?L?OjL?g8L?lL?	L?*L?I
L?K?BK?K?ZK?rK?AK?*K?J?J?J?z^J?3J?;J?I?J?pI?I?^I?GI?oI?*TI?k,I?%I?I?MI?H?H?tH?DH?H?H?H?H?H?usH?7H?H?G?*H?G?G?G?G?G?H?yG? G?G?6zG?sG?k?G?nG?eF?F?mF?F?RF?'F?;F?E?E?hE?E?E?'sE?TE?#E?E?D?D?D?BD?ئD?ٸD?D?D?[D?D?nD?FD?.D?C?C?{C?v}C?(KC?kC?C?HC? D?eD?CHD?nUD?4D?D?D?#D?D?{!D?<C?D?]C?C?C?]C?ՅC?AC?YC?C?]zC?VC?C?<D?GxD??eD?nD?gXD?D?vD?%LE?k-E?E#E?E?E?D?iD?
D?D?TD?o+D?bC?nC?jD?C?~C?C?!C?D?J"D?rD?D?C?LC?C?C?wD?hD?AUD?-D?,D?D?C?C?|C?C?C?bC?GKC?s)C?
C?B?~B?B?B?B?C?*C?MC?MC?ޢC?C?uC?NC?RC?k9C?2C?C?tC?S>G?G? G?F?|F?7F?<F?lvF?eF?AF?I/F?[F?E?E?E?}E?vE?NjE?@E?'E?)E?E?E?:E? E?DE?D?D?D?D?D?mD?D?AyD?}D?OoD?MD?[D?D?D?D?ȥD?D?vD?cD?E?CD?D?D?rD??QD?1D?D?vD?D?qD?D??D?aD?HD?=D?j8D?%D?&C?C?C?ȪC?C?gC?C?4\C?4C?@C?! C? C?kB?B?^I??8I?'I?L?L?JK?K?K?K?*K? L?K?K?K?K?K?K?`K?}K?K?K?}K?qK?WK?PK?<K?IK?dAK?(K?GK?J?J?dJ?~J?vJ?qJ?`J?GJ?XJ?GFJ?=J?	*J?J?I?I?GI?$I?I?KI?tI?NI?J2I?|I?TH?H?H?H?H?H?H?yH?uH?i|H?iH?vH?JjH?`H?H?~H?kH?HH?
2H?H?G?G?TG?KG?uG?G?fG?G?G?`G?lG?|PG?G?G?fG?K|G?xG?	rG?MG?Q5G?f*G?G?G?2G?r}G?4G?^G?G?kG?nG?]G?_G?JG?,G?.G?G?vG?HF?F?F?F?DF?yF?UF?DF?0F?F?F?bF?E?E?yF?XF?/F?:F?-F?LF?zF?1uF?gF?)NF?>F?w:F?3@F?(,F?98F?nF?SF?;JF?^.F?F?F?E?E?E?QF?I?F?OrG?ZG?AG?	G?dG?F?пF?£F?H?d*H?2%H?-H?H? H?H?8G?E?typescatterx\  ?   @  @@  @  @  @  @   A  A   A  A  A   B  HB  pB  B  B  B  B  HC  C  C  C  D  /D  HD  aD  zD  D ;E  zE @E E E  E F @F +F ;F  KF ZF `jF  zF ЄF F pF @F F F F F PF  F F F F `F 0F  F  G G G G G pG XG @G ( G $G 'G +G /G 3G 7G ;G h?G PCG 8GG  KG OG RG VG ZG ^G bG xfG `jG HnG 0rG vG  zG }G G ܂G ЄG ĆG G G G G G |G pG dG XG LG @G 4G (G G G G G G G ԭG ȯG PG DG 8G ,G  G G G G G G G G G G G G G G xG lG `G TG HG <G 0G $G G G  G G G G  H H H H H H H H H 	H 
H H H H H H H H |H vH pH jH dH ^H XH RH LH FH @H :H 4H .H ( H "!H "H #H $H 
%H &H &H 'H (H )H *H +H ,H -H .H /H 0H 1H 2H 3H 4H 5H 6H 7H 8H 9H :H ;H z<H t=H n>H h?H b@H \AH VBH PCH JDH DEH >FH 8GH 2HH ,IH &JH  KH LH MH NH OH PH PH QH RH SH TH UH VH WH XH YH ZH [H \H ]H ^H _H `H aH bH cH dH ~eH xfH rgH lhH fiH `jH ZkH TlH NmH HnH BoH <pH 6qH 0rH *sH $tH uH vH wH xH yH  zH zH {H |H }H ~H H kH H eH H _H ܂H YH փH SH ЄH MH ʅH GH ĆH AH H ;H H 5H H /H H )H H #H H H H H H H H H H H H H |H H vH H pH H jH H dH H ^H ۗH XH ՘H RH ϙH LH ɚH FH ÛH @H H :H H 4H H .H H (H H "H H H H H H H H 
H H H H H {H H uH H oH H iH H cH H ]H ڬH WH ԭH QH ήH KH ȯH EH °H ?H H 9H H 3H H -H H 'H H !H H H H H H H H 	H H H H H zH H tH H nH H hH H bH H \H H VH H PH H JH H DH H >H H 8H H 2H H ,H H &H H  H H H H H H H H H H H H H yH H sH H mH H gH H aH H [H H UH H OH H IH H CH H =H H 7H H 1H H +H H %H H H H H H H H H H H H H ~H H xH H rH H lH H fH H `H H ZH H TH H NH H HH H BH H <H H 6H H 0H H *H H $H H H H H H H H H H H H  H }H H wH H qH H kH H eH H _H H, I k I I  I&I eII I I _II II YII II SII II MII II GII II AII II ;IyI II 5	Is	I 	I	I /
Im
I 
I
I )IgI II #IaI II I[I II IUI II IOI II III II ICI II I=I |II I7I vII I1I pII I+I jII I%I dII II ^II II XII II RII II LII II FII II @I~I II :IxI II 4IrI II .IlI II ( If I  I I "!I`!I !I!I "IZ"I "I"I #IT#I #I#I $IN$I $I$I 
%IH%I %I%I &IB&I &I&I &I<'I {'I'I 'I6(I u(I(I (I0)I o)I)I )I**I i*I*I *I$+I c+I+I +I,I ],I,I ,I-I W-I-I -I.I Q.I.I .I/I K/I/I /I0I E0I0I 0I 1I ?1I}1I 1I1I 92Iw2I 2I2I 33Iq3I 3I3I -4Ik4I 4I4I '5Ie5I 5I5I !6I_6I 6I6I 7IY7I 7I7I 8IS8I 8I8I 9IM9I 9I9I 	:IG:I :I:I ;IA;I ;I;I ;I;<I z<I<I <I5=I t=I=I =I/>I n>I>I >I)?I h?I?I ?I#@I b@I@I @IAI \AIAI AIBI VBIBI BICI PCICI CIDI JDIDI DIEI DEIEI EIEI >FI|FI FIFI 8GIvGI GIGI 2HIpHI HIHI ,IIjII IIII &JIdJI JIJI  KI^KI KIKI LIXLI LILI MIRMI MIMI NILNI NINI OIFOI OIOI PI@PI PIPI PI:QI yQIQI QI4RI sRIRI RI.SI mSISI SI(TI gTITI TI"UI aUIUI UIVI [VIVI VIWI UWIWI WIXI OXIXI XI
YI IYIYI YIZI CZIZI ZIZI =[I{[I [I $tIshowlegend¡y\          ??  ?  @???   ?)>؉?<?%??(?u
?E>?2>`>A>-I?!{?`?sX?9A?e?s?r|?s?<W?E?8?`"B?i?X?bTY?(O?CH?!D?pZ? T?M?vV?n]?!`?uY?u/T?-{k?vh?Cb?Dw?'x?t?vz?fu?Dw?Mq?t?o?xm?h?k?^h?[ f?/e?c?a?]Tf?r=c?_?fa?8a?h`?_?m^?#	]?E[?X?V?NU?S?R?WmS? P?`7O?N?U?5S?2hW?V?U?X?dW?0V?vT?R`S? Q?};P?#0N?0M?wM?لM?ԹU?\T?R?R?(Q?O?N?;jM?cM?SL?;K?+K?nP?
$O?O?F?(F?:F?aaE?}D?cD?QC?pB?0(B?kA?1a@?@???>?O=?s<?@B?B?|B?A?TA?|@?#@?m??@?:??w??1W>?JD??>?=?%>?=?_=?t=?=?=?<?l<?Ԫ;?:?-Q:?:?,9?8?58?r8?7?67?\ 7?6?46?T6?L5?5?5?&!5?lz4?Խ5?h6?x6?}86?5?&%5?4?T8?X7?.7?/6?6?b6?c5?=m5?35?G4?4?4?	5?M5?
4?xv5?N5?4?7?7?7?98?U8?/8?p8?)8?&7??]7?(6?D6?26?5?pn5?5?F5?95?-5?Q4?4?4?[4?3?0t3?]3?4?X4?[3?83?3?:3?^3?-3?2?7F2?)2?%1?VB2?F1?Ƴ1?`1?+1?0?DP3?4?4?44?s4?43?L3?2?22?p2?2?71?1?u1?21?\0?0?0?N0?W/?/?/?{/?Q/?}/?O/?"/?r/?.?C/?^/?%/?./?00?0?/?õ/?q/?0/?;.?.?<.?c.?x`.?iV.?.?o-.?[.?_g.?@I.?	.?-?Mz-?D-?-?=?O>?=?=?=?e=?=?=?4=?>?
=?E=?U=?>?D??
@?@?@@?@?@?xs@?ռ@?.@?=u@?@?????:??>?>?>?>?>?\??2??n??*!??>?>?.>?v>?^_>?g=?
>?=?e=?=?=?O=?=?=?t>?q>?>?B=?<=?-=?L8=?%<?<?+>?'>?=?u=?k=?<&=?<?<?]<?Qu<?B<?><?v<?hj<?$<?j<?Q<?<?r;?;?;?w;?;?;?;?;?F;?	;?M:?:?$j:?;:?9?	9?ݢ9?&:?49?9?59?9?
9?9?9?9?U9?99?^9?>R9?a9?F9?!T9?c9?69?+&9?8?8?8?^8?G;8?*J8?<8?px9?89?D@9?޿9?09?C9?+9?Rl9?39?+9?n8?98?8?'8?R8?&8?8?S8?:?~e:?85:?QI:?J&:?^9?K:?:?g9?9?9?9?9?<9?a9?29?9?9?,9?9?3T9?d-9?
9?8? 8?K8?ŗ8?X8?ܓ8? a8?I8?58?-8?+8?z8?M8?38?)8?C	8?8?j:?~:?U:?,:?::?J>?>?>?B@?*A?JZB?B?B?,A?KA?UA?A?A??}A?A?^B?ȦB?B?mhB?gB?B?B?A?tA?A=B?B?A?A?̰A?	~A?`OA?9lA?\B?9~B?F?F?F?J?F?NF?F?UE?NF?E?'E?E?.E?UE??E?E?%SE?7F?*F?TF?~6F?F?E?E?|E?ME?x%E?D?LD?E?D?gD?iD?ֿD?
D?L2E?GE?E?PD?XD?2D?D?aD?ZD?TD?SD?3D?yD?XD?D?D?(D?(D?ZD?2D?АD?7qD?ND?Y)D?YD?0D?X#D?C?dC?C?C?XC?)C?$qC?FC?R"C?1C?B?uC?NC?B?B?bB?\B?JB?FB?%B?B'B?A?CB?B?B?JoB?kB?gB?]B?FB?*B?!B?:C?C?&C?\C?B?
B?CB?)C?B?B?B?B?B? wB?3CB?iB?B?B?sB?cB?pJB?(B?B?A?A?'A?^>B?6B?B?1B?B?tA? B?mB?SLB?4FB?{"B?A?uA?]B?mB?fB?)BB?B?A?A?A?A?eA?YA?G:A?A?<#A?.A?(A?2A?A?@?ͻ@?@@?@?	@?no@?zG@?*@?y@?4@?@?@?v@?]@?@?jA?2@?@?@?@?
A?YA?;A?=A?A?A?(kA?C]A?JA?Z1A?1A?A?G@?@?@?n}@?f]@?%6@?.@?Z&@?@?*@?H@?$@?@?	????)??{??C??Mp??AZ??E?ͤE?ˁE?TE?3IE?=E?E?D?D?D?D?D?D?D?uD?D?pvD?yD?shD?WD?DnD?F?8F?_PF?:/F?v0F?F? F?WE?E?E?E?E?aF?E?E?HE?#E?E?ՅE?{E?5OE?,E?#E?b
E?rD?D?ZD?ɷD?ؑD?՛D?GD?YD?<E?4E?E E?	E?XE?`E?@E?)E?E?|D?E?2E?Y~E?<E?nE?dE?VAE?" E?#E?LE?.E?%E?E?MD?D? E?E?`D?D?tD?D?QgE?ASE?;E?(E?E?E?D?D?[D?D? D?lD?VD?:D?;D?RC?D?9C?C?D?C?eC?VC?C?C?OC?IxC?2iC?YHC?C?C?
C?C?C?YpC?uC?VC?0C?C?fC?C?~C?9hC?KC?/C?e4C?)C?C?CC?C?@B?B?C?B?B?B?B?jB?^B?gtE?`ZE?{AE?6'E?nE?E?D?D?D?D?D?FwD?}D?vD?hQD?BD?6(D?,D?+D?e D?
D?.C?C?LC?zC?C?6C?lC?UH?DH?H?WH?4H?HH?H?I?I?I?I?<I?I?I?uI??J?
+J?{(J?J?VI?I?I?mI?jI?$I?I?I?I?wN?typescatterx\  ?   @  @@  @  @  @  @   A  A   A  A  A   B  HB  pB  B  B  B  B  HC  C  C  C  D  /D  HD  aD  zD  D ;E  zE @E E E  E F @F +F ;F  KF ZF `jF  zF ЄF F pF @F F F F F PF  F F F F `F 0F  F  G G G G G pG XG @G ( G $G 'G +G /G 3G 7G ;G h?G PCG 8GG  KG OG RG VG ZG ^G bG xfG `jG HnG 0rG vG  zG }G G ܂G ЄG ĆG G G G G G |G pG dG XG LG @G 4G (G G G G G G G ԭG ȯG PG DG 8G ,G  G G G G G G G G G G G G G G xG lG `G TG HG <G 0G $G G G  G G G G  H H H H H H H H H 	H 
H H H H H H H H |H vH pH jH dH ^H XH RH LH FH @H :H 4H .H ( H "!H "H #H $H 
%H &H &H 'H (H )H *H +H ,H -H .H /H 0H 1H 2H 3H 4H 5H 6H 7H 8H 9H :H ;H z<H t=H n>H h?H b@H \AH VBH PCH JDH DEH >FH 8GH 2HH ,IH &JH  KH LH MH NH OH PH PH QH RH SH TH UH VH WH XH YH ZH [H \H ]H ^H _H `H aH bH cH dH ~eH xfH rgH lhH fiH `jH ZkH TlH NmH HnH BoH <pH 6qH 0rH *sH $tH uH vH wH xH yH  zH zH {H |H }H ~H H kH H eH H _H ܂H YH փH SH ЄH MH ʅH GH ĆH AH H ;H H 5H H /H H )H H #H H H H H H H H H H H H H |H H vH H pH H jH H dH H ^H ۗH XH ՘H RH ϙH LH ɚH FH ÛH @H H :H H 4H H .H H (H H "H H H H H H H H 
H H H H H {H H uH H oH H iH H cH H ]H ڬH WH ԭH QH ήH KH ȯH EH °H ?H H 9H H 3H H -H H 'H H !H H H H H H H H 	H H H H H zH H tH H nH H hH H bH H \H H VH H PH H JH H DH H >H H 8H H 2H H ,H H &H H  H H H H H H H H H H H H H yH H sH H mH H gH H aH H [H H UH H OH H IH H CH H =H H 7H H 1H H +H H %H H H H H H H H H H H H H ~H H xH H rH H lH H fH H `H H ZH H TH H NH H HH H BH H <H H 6H H 0H H *H H $H H H H H H H H H H H H  H }H H wH H qH H kH H eH H _H H, I k I I  I&I eII I I _II II YII II SII II MII II GII II AII II ;IyI II 5	Is	I 	I	I /
Im
I 
I
I )IgI II #IaI II I[I II IUI II IOI II III II ICI II I=I |II I7I vII I1I pII I+I jII I%I dII II ^II II XII II RII II LII II FII II @I~I II :IxI II 4IrI II .IlI II ( If I  I I "!I`!I !I!I "IZ"I "I"I #IT#I #I#I $IN$I $I$I 
%IH%I %I%I &IB&I &I&I &I<'I {'I'I 'I6(I u(I(I (I0)I o)I)I )I**I i*I*I *I$+I c+I+I +I,I ],I,I ,I-I W-I-I -I.I Q.I.I .I/I K/I/I /I0I E0I0I 0I 1I ?1I}1I 1I1I 92Iw2I 2I2I 33Iq3I 3I3I -4Ik4I 4I4I '5Ie5I 5I5I !6I_6I 6I6I 7IY7I 7I7I 8IS8I 8I8I 9IM9I 9I9I 	:IG:I :I:I ;IA;I ;I;I ;I;<I z<I<I <I5=I t=I=I =I/>I n>I>I >I)?I h?I?I ?I#@I b@I@I @IAI \AIAI AIBI VBIBI BICI PCICI CIDI JDIDI DIEI DEIEI EIEI >FI|FI FIFI 8GIvGI GIGI 2HIpHI HIHI ,IIjII IIII &JIdJI JIJI  KI^KI KIKI LIXLI LILI MIRMI MIMI NILNI NINI OIFOI OIOI PI@PI PIPI PI:QI yQIQI QI4RI sRIRI RI.SI mSISI SI(TI gTITI TI"UI aUIUI UIVI [VIVI VIWI UWIWI WIXI OXIXI XI
YI IYIYI YIZI CZIZI ZIZI =[I{[I [I $tIshowlegend¡y\                                        >ډ>*>`>~6>
@>c3>Sr'>&N}?,[?>a??tJs?yd?aT?ǰ???^?7}u?nBV?v?`Oi?lc?yU?%L?F?kC?]5?q3?[l?h?5y?t?o?
{?r?m?i?e?c?Ɗ`?g?e?zb?x(a?\?X?V?)c?`?#^?2\?mY?W?viU? S?Q?I=P?0O?M?J?oH?F?vE?C?NA?????-#A???|=?=?;?R:?9?3:?Q8?b7?!6?5?b3?/3?kl2?4?b44?&2?wm1?5_0?v>0?`/?p.?J.?/?/? (3?(h2?M1?P0?ں0?Sy0?'2?2?7??>?=?x;?_<?W]<?S<?|#;?YC:?c9?d8?7?7?6?6? 5?4?"7?^6?ܟ5?4?ʖ4?4?3?2?>2?U1?Ϯ1?E1?^r1?2?%v1?0?g0?740?/??/?/?1?>9?L8?=?z<?<?*=?[<?@<?a;?Q;?:?o:?4;?Kq:?9?9?9?-9?9?q:?A?9A?@?a!@?Z@?F?F?
|F?}E?d=E?D?E?3?D?,C?]C?B?2B?A?EA?_A?@?@?.@???X??>?3@?A??!t??,>?yi>?	>??=?X^=?-<?z<?<?3;?o;?8j;?:?:?h:?_:?K:?:? J:?9?cn9?F9?9?ǝ:?kG:?:?r:?g6:?7:? :?@9?qd:?	9?0:?e;?r:?P:?t&:?9?9?:?:?:?v:?T:?
:?+9?9?9?J9?8?}z9?)9?T8?W8?m7?ϕ7?e7?7?6?U6?6?;?b;?G;?:?&:?;n:?:?t9?:?:?Z:?#F:?q:?$:?T:?w:?6:?29?j9?[9?n9?09?N8?e8?Ym8?8?}8?-8?H8?S8?7?i7?7?7?:}8?58?7?8?Y9?I9?78?h8?_8?8?&8?g9?9?8?8?8?DV8?8?7?27?e7?y7?ց8?]8?K8?|8?ش7?7?Q7?Y7?K8?8?	7?y7?[:7??7?8?9?O	9?8?x8?v8?b8?=7?=7?f7?7?7?37?#Z7?m,7?6?K6?6?p6?+6?5?5?§5?5?U5?e5?:4?84?X4?w4?54?4?3?3?.g3?$3?c2?42?[2?g2?2?@2? 2?l2?uq2?D2?4?{4?c4?Iu4?{4?7?D7?q7?78?)8?7?7?e7? F7?z7?R7?O7?<7?7?6?6?6?˸6?J6?R6?_6?Z6?5?n5?S5?5?V;6?6?6?5?5?5?N5?C6?^6?56?6?J6?/.6?M<?`<?i<?<?~<?<?B<?<?~<?Wc<?G<?<?w<?~;?3<?<?;?n;?	;?';?;?
v;?~p;?.;?:?:?:?{:?/:?:?o:?_:?:l:?ۓ:?:?3~:?<[:?P:?W3:?4:?(:?29?9?%9?9?9?9?A9?k9?b9?'9?:?9?9?u:?{:?X:?-0:?i,:?E\:?M):?J:?:?9?;?P6;?];?7_;?p$;?K;?su;?V;?/;?[;?;? ;?;?;?;?;?;?1c;?K;?+;?>;?W;?:?\:?G:?w:?_:?,:?9?9?9?9?9?ʈ9?O9?)9?9?8?8?8?8?Du8?`8?
_8?A88?18?708?8?"8?8?V7?'8?7?7?G7?ܟ7?n7?xR7?p7?`7?C7?@h7?<7?C7?>7?=9?69?9?S9? 9?{8?8?8?8?8?5v8?K8?@~8?8?Z8?D8?8?7?8?7?7?7?7?7?7?f7?97?B7?"7?7?6?w6?6?Q6?6?e6?|:6?i86?TY6?36?6?6?g7?]7?kM7?I7?^7?7?67?pU7?	47?E87?h7?dc7?O7?\7?W7?Z7?x7?ڰ7?\7?)m7?W7?q9?{8?8?W9?vh9?t9?a9?a9?D9?09?9?a59?c49?#9?9?8?8?8?]8?8?m8?$H8?)8?8?	>:?:?Sg:?WO:??:?:?Q}:?]:?A;:?;:?9?:?W9?|9?9?9?Ԍ9?v9?r9?k9?c9?E9?á9?9?;9?r9?@Y9?lV9?q89?,9?wO9?>9?)D9?=99?)9?i:?9?9?\7:?:?':?:?D9?9?9?9?$=?1=?r<?<?=?=?(=?%=?=?=?=?C>?>?>?u>?>?>?%v>?Ɠ>?H>?Rn>?^>?^>?P>?@>?!>?u>?=?=?=?=?;=?0=?=?t=?N=?AU=?J8=?q=?t<?aq=?@?@?@?`@?'@?@?á@?@?m@?i@?<@?k@?@???????1
@???+@?[@?????????}????2@?@?/@?@?@?@?<@?x@?'c@?Y?BX?X?X?Y?X?X?¼X?X?JY?4Y?	Y?X?QX?ƕX?omX?<[X?mX?&~X?VX?)X?3W?W?W?+zW?_W?BVW?+W?7W?5W?V?XV?;V?QV?1V? V?%V?V?V?nV?PV?'V?V?<U?>V?UV?U?U?ZV?y2V?MV?"V?c~V?neV?8oV?^V?7V?hV?	V?U?(U?sU?6U?U?oU?-KU?2.U?k$U?9U?CU?]U?FU?.U?!-U?eU?T?T?\T?T?T?T?ZT?tT?\T??T?BMT?@T?"T?T?=S?S?[S? S?3S?){S?maS?VS?aBS?Q)S?S?R?UR?R?R?gR?5R?WR?\R?<R?R?Q?RQ?Q?Q?ĖQ?qQ?	\Q?RQ?GQ?"Q?Q?P?P?1P?ˎP?P?P?pP?IP?=P?9P?P?O?UO?UO?O?O?O?O?MO?O?O?^O?O?eO?HO?j(O?iO?JO?0+O?$O?)'O?O?O?JN?N?N?"L?typescatterx\  ?   @  @@  @  @  @  @   A  A   A  A  A   B  HB  pB  B  B  B  B  HC  C  C  C  D  /D  HD  aD  zD  D ;E  zE @E E E  E F @F +F ;F  KF ZF `jF  zF ЄF F pF @F F F F F PF  F F F F `F 0F  F  G G G G G pG XG @G ( G $G 'G +G /G 3G 7G ;G h?G PCG 8GG  KG OG RG VG ZG ^G bG xfG `jG HnG 0rG vG  zG }G G ܂G ЄG ĆG G G G G G |G pG dG XG LG @G 4G (G G G G G G G ԭG ȯG PG DG 8G ,G  G G G G G G G G G G G G G G xG lG `G TG HG <G 0G $G G G  G G G G  H H H H H H H H H 	H 
H H H H H H H H |H vH pH jH dH ^H XH RH LH FH @H :H 4H .H ( H "!H "H #H $H 
%H &H &H 'H (H )H *H +H ,H -H .H /H 0H 1H 2H 3H 4H 5H 6H 7H 8H 9H :H ;H z<H t=H n>H h?H b@H \AH VBH PCH JDH DEH >FH 8GH 2HH ,IH &JH  KH LH MH NH OH PH PH QH RH SH TH UH VH WH XH YH ZH [H \H ]H ^H _H `H aH bH cH dH ~eH xfH rgH lhH fiH `jH ZkH TlH NmH HnH BoH <pH 6qH 0rH *sH $tH uH vH wH xH yH  zH zH {H |H }H ~H H kH H eH H _H ܂H YH փH SH ЄH MH ʅH GH ĆH AH H ;H H 5H H /H H )H H #H H H H H H H H H H H H H |H H vH H pH H jH H dH H ^H ۗH XH ՘H RH ϙH LH ɚH FH ÛH @H H :H H 4H H .H H (H H "H H H H H H H H 
H H H H H {H H uH H oH H iH H cH H ]H ڬH WH ԭH QH ήH KH ȯH EH °H ?H H 9H H 3H H -H H 'H H !H H H H H H H H 	H H H H H zH H tH H nH H hH H bH H \H H VH H PH H JH H DH H >H H 8H H 2H H ,H H &H H  H H H H H H H H H H H H H yH H sH H mH H gH H aH H [H H UH H OH H IH H CH H =H H 7H H 1H H +H H %H H H H H H H H H H H H H ~H H xH H rH H lH H fH H `H H ZH H TH H NH H HH H BH H <H H 6H H 0H H *H H $H H H H H H H H H H H H  H }H H wH H qH H kH H eH H _H H, I k I I  I&I eII I I _II II YII II SII II MII II GII II AII II ;IyI II 5	Is	I 	I	I /
Im
I 
I
I )IgI II #IaI II I[I II IUI II IOI II III II ICI II I=I |II I7I vII I1I pII I+I jII I%I dII II ^II II XII II RII II LII II FII II @I~I II :IxI II 4IrI II .IlI II ( If I  I I "!I`!I !I!I "IZ"I "I"I #IT#I #I#I $IN$I $I$I 
%IH%I %I%I &IB&I &I&I &I<'I {'I'I 'I6(I u(I(I (I0)I o)I)I )I**I i*I*I *I$+I c+I+I +I,I ],I,I ,I-I W-I-I -I.I Q.I.I .I/I K/I/I /I0I E0I0I 0I 1I ?1I}1I 1I1I 92Iw2I 2I2I 33Iq3I 3I3I -4Ik4I 4I4I '5Ie5I 5I5I !6I_6I 6I6I 7IY7I 7I7I 8IS8I 8I8I 9IM9I 9I9I 	:IG:I :I:I ;IA;I ;I;I ;I;<I z<I<I <I5=I t=I=I =I/>I n>I>I >I)?I h?I?I ?I#@I b@I@I @IAI \AIAI AIBI VBIBI BICI PCICI CIDI JDIDI DIEI DEIEI EIEI >FI|FI FIFI 8GIvGI GIGI 2HIpHI HIHI ,IIjII IIII &JIdJI JIJI  KI^KI KIKI LIXLI LILI MIRMI MIMI NILNI NINI OIFOI OIOI PI@PI PIPI PI:QI yQIQI QI4RI sRIRI RI.SI mSISI SI(TI gTITI TI"UI aUIUI UIVI [VIVI VIWI UWIWI WIXI OXIXI XI
YI IYIYI YIZI CZIZI ZIZI =[I{[I [I $tIlinedashdashwidth@  y\  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?  ?typescatternameWeighted Importance Samplingx\  ?   @  @@  @  @  @  @   A  A   A  A  A   B  HB  pB  B  B  B  B  HC  C  C  C  D  /D  HD  aD  zD  D ;E  zE @E E E  E F @F +F ;F  KF ZF `jF  zF ЄF F pF @F F F F F PF  F F F F `F 0F  F  G G G G G pG XG @G ( G $G 'G +G /G 3G 7G ;G h?G PCG 8GG  KG OG RG VG ZG ^G bG xfG `jG HnG 0rG vG  zG }G G ܂G ЄG ĆG G G G G G |G pG dG XG LG @G 4G (G G G G G G G ԭG ȯG PG DG 8G ,G  G G G G G G G G G G G G G G xG lG `G TG HG <G 0G $G G G  G G G G  H H H H H H H H H 	H 
H H H H H H H H |H vH pH jH dH ^H XH RH LH FH @H :H 4H .H ( H "!H "H #H $H 
%H &H &H 'H (H )H *H +H ,H -H .H /H 0H 1H 2H 3H 4H 5H 6H 7H 8H 9H :H ;H z<H t=H n>H h?H b@H \AH VBH PCH JDH DEH >FH 8GH 2HH ,IH &JH  KH LH MH NH OH PH PH QH RH SH TH UH VH WH XH YH ZH [H \H ]H ^H _H `H aH bH cH dH ~eH xfH rgH lhH fiH `jH ZkH TlH NmH HnH BoH <pH 6qH 0rH *sH $tH uH vH wH xH yH  zH zH {H |H }H ~H H kH H eH H _H ܂H YH փH SH ЄH MH ʅH GH ĆH AH H ;H H 5H H /H H )H H #H H H H H H H H H H H H H |H H vH H pH H jH H dH H ^H ۗH XH ՘H RH ϙH LH ɚH FH ÛH @H H :H H 4H H .H H (H H "H H H H H H H H 
H H H H H {H H uH H oH H iH H cH H ]H ڬH WH ԭH QH ήH KH ȯH EH °H ?H H 9H H 3H H -H H 'H H !H H H H H H H H 	H H H H H zH H tH H nH H hH H bH H \H H VH H PH H JH H DH H >H H 8H H 2H H ,H H &H H  H H H H H H H H H H H H H yH H sH H mH H gH H aH H [H H UH H OH H IH H CH H =H H 7H H 1H H +H H %H H H H H H H H H H H H H ~H H xH H rH H lH H fH H `H H ZH H TH H NH H HH H BH H <H H 6H H 0H H *H H $H H H H H H H H H H H H  H }H H wH H qH H kH H eH H _H H, I k I I  I&I eII I I _II II YII II SII II MII II GII II AII II ;IyI II 5	Is	I 	I	I /
Im
I 
I
I )IgI II #IaI II I[I II IUI II IOI II III II ICI II I=I |II I7I vII I1I pII I+I jII I%I dII II ^II II XII II RII II LII II FII II @I~I II :IxI II 4IrI II .IlI II ( If I  I I "!I`!I !I!I "IZ"I "I"I #IT#I #I#I $IN$I $I$I 
%IH%I %I%I &IB&I &I&I &I<'I {'I'I 'I6(I u(I(I (I0)I o)I)I )I**I i*I*I *I$+I c+I+I +I,I ],I,I ,I-I W-I-I -I.I Q.I.I .I/I K/I/I /I0I E0I0I 0I 1I ?1I}1I 1I1I 92Iw2I 2I2I 33Iq3I 3I3I -4Ik4I 4I4I '5Ie5I 5I5I !6I_6I 6I6I 7IY7I 7I7I 8IS8I 8I8I 9IM9I 9I9I 	:IG:I :I:I ;IA;I ;I;I ;I;<I z<I<I <I5=I t=I=I =I/>I n>I>I >I)?I h?I?I ?I#@I b@I@I @IAI \AIAI AIBI VBIBI BICI PCICI CIDI JDIDI DIEI DEIEI EIEI >FI|FI FIFI 8GIvGI GIGI 2HIpHI HIHI ,IIjII IIII &JIdJI JIJI  KI^KI KIKI LIXLI LILI MIRMI MIMI NILNI NINI OIFOI OIOI PI@PI PIPI PI:QI yQIQI QI4RI sRIRI RI.SI mSISI SI(TI gTITI TI"UI aUIUI UIVI [VIVI VIWI UWIWI WIXI OXIXI XI
YI IYIYI YIZI CZIZI ZIZI =[I{[I [I $tI4c6e0de0c-3901-11f0-234e-bd09c571f662/d508a1aa913b68dlayoutautosize¥xaxistickvals  ?   AtitletextDealer showingticktextA10templatelayout coloraxiscolorbarticksoutlinewidth    xaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhitehovermodeclosestpaper_bgcolorwhitegeoshowlakesèshowlandélandcolor#E5ECF6bgcolorwhitesubunitcolorwhitelakecolorwhitecolorscalesequential    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921diverging    #8e0152=ͧ#c51b7d>Lͧ#de77ae>#f1b6da>ͧ#fde0ef?   #f7f7f7?#e6f5d0?333#b8e186?Lͧ#7fbc41?fff#4d9221?  #276419sequentialminus    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921yaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhiteshapedefaultslinecolor#2a3f5fhoverlabelalignleftmapboxstylelightpolarangularaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6radialaxisgridcolorwhitetickslinecolorwhiteautotypenumbersstrictfontcolor#2a3f5fternaryaaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6caxisgridcolorwhitetickslinecolorwhitebaxisgridcolorwhitetickslinecolorwhiteannotationdefaultsarrowhead    arrowwidth?  arrowcolor#2a3f5fplot_bgcolor#E5ECF6titlex=Lͥscenexaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitezaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhiteyaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitecolorway#636efa#EF553B#00cc96#ab63fa#FFA15A#19d3f3#FF6692#B6E880#FF97FF#FECB52data scatterpolargltypescatterpolarglmarkercolorbarticksoutlinewidth    carpetbaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitetypecarpetaaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitescatterpolartypescatterpolarmarkercolorbarticksoutlinewidth    parcoordslinecolorbarticksoutlinewidth    typeparcoordsscattertypescattermarkercolorbarticksoutlinewidth    histogram2dcontourcolorbarticksoutlinewidth    typehistogram2dcontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcolorbarticksoutlinewidth    typecontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattercarpettypescattercarpetmarkercolorbarticksoutlinewidth    mesh3dcolorbarticksoutlinewidth    typemesh3dsurfacecolorbarticksoutlinewidth    typesurfacecolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattermapboxtypescattermapboxmarkercolorbarticksoutlinewidth    scattergeotypescattergeomarkercolorbarticksoutlinewidth    histogramtypehistogrammarkercolorbarticksoutlinewidth    pietypepieautomarginêchoroplethcolorbarticksoutlinewidth    typechoroplethheatmapglcolorbarticksoutlinewidth    typeheatmapglcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921bartypebarerror_ycolor#2a3f5ferror_xcolor#2a3f5fmarkerlinecolor#E5ECF6width?   heatmapcolorbarticksoutlinewidth    typeheatmapcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcarpetcolorbarticksoutlinewidth    typecontourcarpettabletypetableheaderlinecolorwhitefillcolor#C8D4E3cellslinecolorwhitefillcolor#EBF0F8scatter3dlinecolorbarticksoutlinewidth    typescatter3dmarkercolorbarticksoutlinewidth    barpolartypebarpolarmarkerlinecolor#E5ECF6width?   scattergltypescatterglmarkercolorbarticksoutlinewidth    histogram2dcolorbarticksoutlinewidth    typehistogram2dcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scatterternarytypescatterternarymarkercolorbarticksoutlinewidth    heightC  marginl    b    r    tBp  titleyaxistickvals  @A  AtitletextPlayer sumticktext  @A  AwidthC  configshowLink¨editableªresponsiveêstaticPlotªscrollZoomæframesdatazmax?  y(  @A  PA  `A  pA  A  A  A  A  A  AtypeheatmapcolorscaleBlueredzminʿ  z(-x78
?uD`EOMaR>c>(z|"%/M36X$?Bqa?(F
WUu!k',XB6>="?a?(8q6#)P90"49C;(?hMb?(;pWUX!p)R03$s87.?,f?(|o!%&'37qp6?h?(BԭE!#,@i055G?\l?(8&'{-Y8J?l?(Y8t#J,38pA?mqp?(/GA#0+-37?>%Q?transposeéshowscaleáx(  ?   @  @@  @  @  @  @   A  A   A5c6e0de0c-3901-11f0-234e-bd09c571f662/b6b6df0af3e3a8aelayoutxaxistypelogtitletextSteps to Finish Racetemplatelayout coloraxiscolorbarticksoutlinewidth    xaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhitehovermodeclosestpaper_bgcolorwhitegeoshowlakesèshowlandélandcolor#E5ECF6bgcolorwhitesubunitcolorwhitelakecolorwhitecolorscalesequential    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921diverging    #8e0152=ͧ#c51b7d>Lͧ#de77ae>#f1b6da>ͧ#fde0ef?   #f7f7f7?#e6f5d0?333#b8e186?Lͧ#7fbc41?fff#4d9221?  #276419sequentialminus    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921yaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhiteshapedefaultslinecolor#2a3f5fhoverlabelalignleftmapboxstylelightpolarangularaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6radialaxisgridcolorwhitetickslinecolorwhiteautotypenumbersstrictfontcolor#2a3f5fternaryaaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6caxisgridcolorwhitetickslinecolorwhitebaxisgridcolorwhitetickslinecolorwhiteannotationdefaultsarrowhead    arrowwidth?  arrowcolor#2a3f5fplot_bgcolor#E5ECF6titlex=Lͥscenexaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitezaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhiteyaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitecolorway#636efa#EF553B#00cc96#ab63fa#FFA15A#19d3f3#FF6692#B6E880#FF97FF#FECB52data scatterpolargltypescatterpolarglmarkercolorbarticksoutlinewidth    carpetbaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitetypecarpetaaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitescatterpolartypescatterpolarmarkercolorbarticksoutlinewidth    parcoordslinecolorbarticksoutlinewidth    typeparcoordsscattertypescattermarkercolorbarticksoutlinewidth    histogram2dcontourcolorbarticksoutlinewidth    typehistogram2dcontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcolorbarticksoutlinewidth    typecontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattercarpettypescattercarpetmarkercolorbarticksoutlinewidth    mesh3dcolorbarticksoutlinewidth    typemesh3dsurfacecolorbarticksoutlinewidth    typesurfacecolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattermapboxtypescattermapboxmarkercolorbarticksoutlinewidth    scattergeotypescattergeomarkercolorbarticksoutlinewidth    histogramtypehistogrammarkercolorbarticksoutlinewidth    pietypepieautomarginêchoroplethcolorbarticksoutlinewidth    typechoroplethheatmapglcolorbarticksoutlinewidth    typeheatmapglcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921bartypebarerror_ycolor#2a3f5ferror_xcolor#2a3f5fmarkerlinecolor#E5ECF6width?   heatmapcolorbarticksoutlinewidth    typeheatmapcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcarpetcolorbarticksoutlinewidth    typecontourcarpettabletypetableheaderlinecolorwhitefillcolor#C8D4E3cellslinecolorwhitefillcolor#EBF0F8scatter3dlinecolorbarticksoutlinewidth    typescatter3dmarkercolorbarticksoutlinewidth    barpolartypebarpolarmarkerlinecolor#E5ECF6width?   scattergltypescatterglmarkercolorbarticksoutlinewidth    histogram2dcolorbarticksoutlinewidth    typehistogram2dcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scatterternarytypescatterternarymarkercolorbarticksoutlinewidth    marginlBH  bBH  rBH  tBp  yaxistitletextPercent of EpisodesconfigshowLink¨editableªresponsiveêstaticPlotªscrollZoomæframesdatay-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= = = = = = = = = =-==========="="="="="="="="="="=J>J>J>J>J>J>J>J>J>J>J>J>J>J>J>J>J>J>J>J>>>>>>>>>>>>>>>>>>>>)>)>)>)>)>)>)>)>)>)>)>)>)>)>)>)>)>)>)>)>j<>j<>j<>j<>j<>j<>j<>j<>j<>j<>j<>j<>j<>j<>j<>j<>j<>j<>Q>Q>Q>Q>Q>Q>Q>Q>Q>Q>Q>Q>Q>Q>Q>Q>Q>Q>Q>Q>Q>Mb>Mb>Mb>Mb>Mb>Mb>Mb>Mb>Mb>Mb>Mb>Mb>Mb>Mb>Mb>Mb>ףp>ףp>ףp>ףp>ףp>ףp>ףp>ףp>ףp>ףp>ףp>ףp>ףp>ףp>Hz>Hz>Hz>Hz>Hz>Hz>Hz>Hz>Hz>Hz>>>>>>>>>>>>>>C>C>C>C>C>C>C>C>C>C>C>C>C>C>>>>>>>>>>>>>>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>Z>Z>Z>Z>Z>Z>Z>Z>Z>Z>Z>Z>Z>Z>>>>>>>>>>>>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>>>>>>>>>>>>>>>>>>  >  >  >  >  >  >ˡ>ˡ>ˡ>ˡ>ˡ>ˡ>ˡ>ˡ>ˡ>ˡ>ˡ>I>I>I>I>I>I>I>I>I>I>I>I>I>z>z>z>z>z>z>z>z>z>z>z>z>z>z>z>z>=
>=
>=
>=
>=
>">">">">">">">">>>>>>>>>>>>B`>B`>B`>B`>B`>B`>B`>B`>B`>x>x>x>x>x>x>x>x>{>{>{>{>{>{>{>{>{>33>33>33>33>33>33>33>33>33>33>>>>>>>>>>j>j>j>j>j>j>j>j>j> ? ? ? ? ? ? ? ? ?S?S?S?S?S?S?S?S?S?S?S?y?y?y?y?y?y?y?y?y?y?y?y?y?y?9?9?9?9?9?9?9?q=
?q=
?q=
?q=
?q=
?q=
?I?I?I?I?I?I?I?I??????????&?&?&?&?&?&?&?&?&?&????????z?z?z?z?z?z?E?E?E?E?E?E?E?b?b?b?b?b?b?b?#?#?#?#?#?#?#?j?j?j?j?j?j?j?j?j?j?v?v?v?v?v?v?v?v?%!?%!?%!?%!?%!?%!?%!?%!?%!?%!?o#?o#?o#?o#?o#?o#?o#?o#?#?#?B`%?B`%?B`%?B`%?B`%?B`%?B`%?l'?l'?l'?l'?l'?l'?l'?l'?9(?9(?9(?9(?9(?q=*?q=*?q=*?q=*?q=*?q=*?+?+?+?+?+?+?,?,?,?,?-?-?-?-?/?/?/?/?/? 0? 0? 0? 0?-2?-2?-2?-2?-2?-2?-2?-2?t3?t3?t3?t3?t3?5?5?5?5?5?5?5?5?+6?+6?+6?+6?Q8?Q8?Q8?Q8?Q8?Q8?Q8?9?9?9?:?:?:?:?;?;?;?;?;?;?j<?j<?j<??5>??5>??5>??5>??5>??5>??5>?A@?A@?A@?A@?A@?A@?A@?A@?GA?GA?GA?GA?\B?\B?\B?\B?\B?D?D?D?D?D?D?ZD?TE?TE?TE?TE?TE?TE?lG?lG?lG?lG?lG?lG?L7I?L7I?L7I?L7I?L7I?L7I?L7I?^I?^I?K?K?K?K?K?1L?1L?1L?1L?VM?VM?VM?VM?{N?{N?{N?{N?N?N?N?O?O?O?ףP?ףP?ףP?ףP?&Q?&Q?Q?Q?Q?!R?!R?!R?33S?33S?S?S?S?zT?zT?}?U?}?U?}?U?U?U?V?=
W?=
W?=
W?=
W?W?W?W?X?X?X?X?XY?XY?HZ?HZ?HZ?HZ?HZ?HZ?"[?\?\?\?\?\?\?p]?p]?p]?]?]??5^?|_?|_?|_?|_?|_?w_?`?`?`?`?Jb?Jb?Jb?Jb?Jb?\b?\b?b?c?c?c?d?d?/d?/d?/d?e?B`e?ˡe?Te?$f?f?f?yf?+g?g?g?g?'1h?9h?9h?h?L7i?xi?q=j?q=j?q=j?k?k?k?k?k?1l?1l?Dl?Dl?l?Vm?m?m?m?n?n?n?o?o?)\o?o?;o? p?Nbp?shq?shq?shq?shq?q?q?nr?nr?!r?r?33s?ts?Fs?s?jt?jt?jt?t?}?u?u?u?v?Ev?=
w?=
w?=
w?Kw?Pw?bx?bx?Qx?ux?x?Xy?Xy?y?#y?z?5^z?z?"{?"{?Zd{?{?m{?j|?j|?|?|?/}?p}?-}??5~??5~?v~?R~?~?d;?|?w?  ?typescatternameMonte Carlo Exploring Startsx  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  pA  pA  pA  pA  pA  pA  pA  pA  pA  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A   B   B   B   B   B   B   B   B   B   B   B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B   B   B   B   B   B   B   B   B  $B  $B  $B  $B  $B  $B  $B  $B  $B  $B  $B  (B  (B  (B  (B  (B  (B  (B  (B  (B  ,B  ,B  ,B  ,B  ,B  ,B  ,B  ,B  0B  0B  0B  0B  0B  0B  0B  0B  0B  4B  4B  4B  4B  4B  4B  4B  4B  4B  4B  8B  8B  8B  8B  8B  8B  8B  8B  8B  <B  <B  <B  <B  <B  <B  <B  <B  <B  @B  @B  @B  @B  @B  @B  @B  @B  @B  DB  DB  DB  DB  DB  DB  DB  DB  DB  DB  DB  HB  HB  HB  HB  HB  HB  HB  HB  HB  HB  HB  HB  HB  HB  LB  LB  LB  LB  LB  LB  LB  PB  PB  PB  PB  PB  PB  TB  TB  TB  TB  TB  TB  TB  TB  XB  XB  XB  XB  XB  XB  XB  XB  XB  \B  \B  \B  \B  \B  \B  \B  \B  \B  \B  `B  `B  `B  `B  `B  `B  `B  dB  dB  dB  dB  dB  dB  hB  hB  hB  hB  hB  hB  hB  lB  lB  lB  lB  lB  lB  lB  pB  pB  pB  pB  pB  pB  pB  tB  tB  tB  tB  tB  tB  tB  tB  tB  tB  xB  xB  xB  xB  xB  xB  xB  xB  |B  |B  |B  |B  |B  |B  |B  |B  |B  |B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B   C   C   C  C  C  C  C  C  C  C  C  C  	C  
C  
C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C   C   C  !C  $C  %C  'C  (C  )C  )C  )C  )C  *C  +C  ,C  ,C  -C  .C  /C  1C  3C  5C  7C  7C  7C  9C  :C  <C  AC  DC  FC  KC  KC  KC  LC  NC  OC  OC  PC  QC  RC  SC  SC  \C  cC  kC  mC  nC  oC  oC  qC  sC  tC  xC  xC  yC C C C  C  C  C C  C  C  C  C  C  Cy@K:K;PqI;K;mާ;2;2;K<<ާ8<ާ8<PqI<:Z<2k<{<K<C<<y<mާ<&C<ާ<<Pq<<:<h<h<h<<K=K=C=C===XG=y=#=,=,=u4=u4=ާ8=;<=A=>E=:Z=:Z=:Z=:Z=:Z=m^=zb=f=6o=6o=Gw=Gw={=  =\2=\2=K=d=}==C=qɐ====*.=XG=`=y=㒡==?ť=mާ==)=)=T\=T\===ާ==;ڼ=i==%=>=Pq=Pq=~==ڼ==e=e=:=:=S=m=L=z===2=2=a=6=O=h==G=v===   >.>.>%>\2>>>K>d>d>Pq	>}
>~>>>C>ڼ>q>>>7>>e>>!>:>:>XG>S>`>m>y>L >!>z">#>$>?%>m'>m'>(>)>2+>,>a->6/>6/>&C0>O1>T\2>u4>u4>5>6>G7>ާ8>v9>:>;>;<>=>i>>  @>A>.B>%C>>E>>E>"XG>"XG>dH>PqI>L>L>L>CN>CN>ڼO>qP>R>R>7S>T>eV>W>!X>*.Y>:Z>XG[>S\>`]>m^>y_>a>a>zb>c>d>?e>f>mg>h>2k>2k>l>am>)n>6o>&Cp>Oq>T\r>hs>ut>u>Gw>Gw>ާx>vy>z>{>;|>}>i~>  >L>>㒁>.>z>%>>\2>>>>?Ņ>K>ц>"X>mއ>d>Pq>Pq>>}>2>>>>a>>)>C>6>ڼ>&C>qɐ>O>֑>T\>>h>u>u>>>>>>G>!>ާ>*.>>>>XG>͛>S>;ڜ>m>m>m>i>  >  >L>>㒡>.>z>%>>\2>>>>?ť>K>Ѧ>"X>mާ>d>>Pq>>}>2>~>>>a>>)>C>6>ڼ>&C>O>O>ֱ>T\>>h>u>u>>>e>>>G>!>ާ>*.>v>:>>XG>ͻ>S>;ڼ>m>m>m>i>y>  >L>>>.>z>%>>\2>?>?>?>K>>"X>m>d>>Pq>>}>2>~>>>a>>)>C>6>ڼ>&C>q>O>>T\>>h>7>u>>>>>>G>!>ާ>v>v>:>>XG>>S>;>`>m>m>i>  >  >L>>>.>z>%>>\2>>>>>?>K>>"X>m>>>Pq>>}>2>>>>a>>)>6>6>ڼ>&C>O>O>>T\>>h>7>>>>e>>>G>!>ާ>*.>v>:>XG>XG>>S>;>`>m>m>i>   ?   ?L ?L ?q ??O???.?T\?z??%?h??7?\2?u???>????e?K????G?G?m?!?d?ާ??*.	?Pq	?v	?	?:
?}
?
?2?XG?~???S??;?a?`???)?m?C?i?6?y?ڼ?  ?&C?L?q??O???.?T\?z??%?h??7?\2?u???>????e?K???"X?"X?G?m?!?d?ާ??*.?Pq?v??:?}??2?XG?~???S??;?a?`???m?m?C?i?6?y?ڼ?   ?&C ?L ?q ?!?O!?!?!?."?T\"?z"?"?%#?h#?#?7#?\2$?u$?$?$?>%?%??%?e&?K&?&?&?"X'?"X'?G'?m'?!(?ާ(?ާ(?(?*.)?Pq)?v)?)?:*?}*?*?XG+?XG+?~+?+?,?S,?,?;,?a-?`-?-?-?).?m.?C.?i.?6/?y/?ڼ/?  0?&C0?L0?q0?1?O1?1?.2?.2?T\2?z2?2?%3?h3?3?73?\24?u4?4?4?5?5??5?e6?6?6?6?7?"X7?G7?m7?!8?d8?ާ8?8?*.9?Pq9?v9?9?::?}:?:?2;?~;?~;?;?<?S<?<?;<?a=?`=?=?=?)>?m>?C>?i>?6??y??ڼ??  @?&C@?L@?q@?A?OA?A?A?.B?T\B?zB?B?%C?hC?C?7C?\2D?uD?D?D?>E?E??E?eF?KF?F?F?"XG?"XG?GG?mG?!H?dH?ާH?H?*.I?PqI?vI?I?:J?J?J?2K?XGK?~K?K?L?SL?L?;L?aM?`M?M?M?)N?mN?CN?iN?6O?yO?ڼO?  P?&CP?LP?qP?Q?OQ?Q?Q?.R?T\R?R?R?%S?hS?S?7S?\2T?uT?T?T?>U?U??U?eV?KV?V?V?W?"XW?GW?mW?!X?dX?ާX?X?*.Y?PqY?vY?Y?:Z?}Z?Z?2[?XG[?~[?[?\?S\?\?;\?a]?`]?]?]?)^?m^?C^?i^?6_?y_?ڼ_?  `?&C`?L`?q`?a?Oa?a?a?.b?T\b?zb?b?%c?hc?c?7c?\2d?ud?d?d?>e?e??e?ef?Kf?f?f?g?"Xg?Gg?mg?!h?dh?h?h?*.i?Pqi?vi?i?:j?}j?j?2k?XGk?~k?k?l?Sl?l?;l?am?`m?m?m?)n?mn?Cn?in?6o?yo?ڼo?  p?&Cp?Lp?qp?q?Oq?q?q?.r?T\r?zr?r?%s?hs?s?7s?\2t?ut?t?t?>u?u??u?ev?Kv?v?v?w?"Xw?Gw?mw?!x?dx?ާx?x?*.y?Pqy?vy?y?:z?}z?z?2{?XG{?~{?{?|?S|?|?;|?a}?`}?}?}?)~?m~?C~?i~?6?y?ڼ?  ?typescatternameRandom Policyx@  A  A  A  A  B  B  B  B  $B  0B  0B  <B  @B  HB  TB  dB  pB  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B   C  C  C  C  C  C  C  
C  C  C  C  C  C  C  C  C  C  C  C  C  C   C  !C  %C  %C  *C  .C  /C  1C  2C  4C  5C  9C  ?C  AC  BC  CC  HC  JC  QC  UC  XC  ZC  aC  aC  eC  eC  fC  fC  iC  oC  wC  xC  zC  C  C  C  C  C  C C C C C C C C  C  C C  C  C C C  C  C  C C  C  C C C  C  C  C  C  C  C C C C C  C  C  C  C  C  C  C C C C  C  C C  C  C C C  C C C  C C C  C C C C  C  C  C  C C C  C C C C  C C C  C  C  C C  C  C  C  C C @D @D D  D D D 	D  
D  
D 
D 
D D  D D D D  D  D D D  D  D @D D D D @D  D  D D D  D @D @D @D @D   D @ D !D @"D "D "D #D %D %D &D @'D 'D @)D @*D +D @,D .D  /D @/D /D /D /D 0D  1D 1D  2D 2D @3D  4D :D :D  ;D ;D  <D @<D <D =D @>D  ?D  @D @D BD  CD @GD  HD HD HD ID @JD JD  KD  KD KD KD  LD MD OD PD RD  SD SD  TD @WD @YD YD YD  [D  [D  \D @\D \D \D _D @aD aD bD  cD cD cD cD eD hD  jD @lD  nD  nD  nD nD  oD  oD qD qD rD  sD sD  tD uD @vD vD vD  wD wD wD xD zD  {D @|D  }D @}D  ~D @D D `D `D D  D D D D D D  D  D D  D D `D D D D D  D  D  D @D `D D  D `D  D @D D D  D `D D D D D D  D D  D D D  D D  D D D D D D D @D D D D D  D  D D D `D D  D @D `D D D D D @D @D D D @D D  D `D D  D  D  D @D D  D @D @D @D D D D @D D D  D @D @D D  D  D @D `D D D D D  D @D D D  D @D @D `D @D D D D D D  D `D `D D  D D D  D  D  D @D D D D `D D D  D  D  D `D D  D  D  D D D @D `D D  D  D D D D  D D D @D D D D D D D @D  D D  D D D  D `D D D D  D  D D D D D  D D D @D `D @D `D `D D D D  D D D D @D `D D D @D  D D D @D D D  D D @D D D D @D `D D @D @ E ` E  E E E pE E pE E  E 0E pE E E E E @E 0E PE pE `	E 	E 	E 	E 
E E  E E E  E E E E  E 0E E  E pE E @E E  E PE E E  E E  E PE E E  E 0E PE PE PE E E E E PE pE E E  E E PE E E 0E E   E P!E !E @#E $E @$E P%E `%E %E %E &E 'E  'E P'E `'E (E P)E )E  *E *E *E *E p+E +E +E 0,E 0,E ,E ,E ,E -E -E .E .E p/E 1E 1E P2E p2E 3E  4E `4E P5E p5E 5E 5E  6E P9E 9E :E :E :E 0;E ;E 0=E 0>E p>E  ?E p?E  @E @@E @E @E  BE `BE BE 0CE @CE `CE CE  DE PDE `DE @EE `EE `EE EE EE EE EE EE GE  GE GE GE IE @JE JE @KE KE KE pLE LE PNE 0OE OE  PE PE PE 0PE QE SE TE @TE PTE UE @VE pVE VE WE XE YE PZE ZE [E \E  ]E  _E _E 0`E aE @bE bE cE dE  eE PfE `fE 0gE PgE gE gE hE `hE hE iE jE kE 0kE kE  lE  mE pmE pmE oE oE oE @pE `qE qE @tE PtE uE uE `vE 0xE 0xE  yE @yE pyE zE  {E {E |E @|E  }E }E 0~E ~E E E PE XE E E  E HE E E E E ȂE E 8E @E E `E `E pE E E E ؅E xE E E E  E  E E E  E E E ؊E E E E E E E E E @E xE E E E E `E E `E hE E ؐE E E E E hE E E E E PE E E E  E hE E PE E  E  E xE  E E E 0E HE pE PE  E إE E E `E E 0E `E  E  E E pE E HE E E @E E E E E pE 8E HE E E E @E pE E E E E  E E E XE `E E E `E E 8E HE E E E HE XE `E E HE  E E E E  E HE E E pE @E 0E E @E E HE hE `E pE E `E pE E  E  E E  E  E pE E E F F F XF F tF  F F F F x	F 4
F tF F  F tF  F F F F <F dF F xF F5c6e0de0c-3901-11f0-234e-bd09c571f662/acf9294267fab534layoutautosize¥xaxistickvals  ?   AtitletextDealer showingticktextA10templatelayout coloraxiscolorbarticksoutlinewidth    xaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhitehovermodeclosestpaper_bgcolorwhitegeoshowlakesèshowlandélandcolor#E5ECF6bgcolorwhitesubunitcolorwhitelakecolorwhitecolorscalesequential    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921diverging    #8e0152=ͧ#c51b7d>Lͧ#de77ae>#f1b6da>ͧ#fde0ef?   #f7f7f7?#e6f5d0?333#b8e186?Lͧ#7fbc41?fff#4d9221?  #276419sequentialminus    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921yaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhiteshapedefaultslinecolor#2a3f5fhoverlabelalignleftmapboxstylelightpolarangularaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6radialaxisgridcolorwhitetickslinecolorwhiteautotypenumbersstrictfontcolor#2a3f5fternaryaaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6caxisgridcolorwhitetickslinecolorwhitebaxisgridcolorwhitetickslinecolorwhiteannotationdefaultsarrowhead    arrowwidth?  arrowcolor#2a3f5fplot_bgcolor#E5ECF6titlex=Lͥscenexaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitezaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhiteyaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitecolorway#636efa#EF553B#00cc96#ab63fa#FFA15A#19d3f3#FF6692#B6E880#FF97FF#FECB52data scatterpolargltypescatterpolarglmarkercolorbarticksoutlinewidth    carpetbaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitetypecarpetaaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitescatterpolartypescatterpolarmarkercolorbarticksoutlinewidth    parcoordslinecolorbarticksoutlinewidth    typeparcoordsscattertypescattermarkercolorbarticksoutlinewidth    histogram2dcontourcolorbarticksoutlinewidth    typehistogram2dcontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcolorbarticksoutlinewidth    typecontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattercarpettypescattercarpetmarkercolorbarticksoutlinewidth    mesh3dcolorbarticksoutlinewidth    typemesh3dsurfacecolorbarticksoutlinewidth    typesurfacecolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattermapboxtypescattermapboxmarkercolorbarticksoutlinewidth    scattergeotypescattergeomarkercolorbarticksoutlinewidth    histogramtypehistogrammarkercolorbarticksoutlinewidth    pietypepieautomarginêchoroplethcolorbarticksoutlinewidth    typechoroplethheatmapglcolorbarticksoutlinewidth    typeheatmapglcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921bartypebarerror_ycolor#2a3f5ferror_xcolor#2a3f5fmarkerlinecolor#E5ECF6width?   heatmapcolorbarticksoutlinewidth    typeheatmapcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcarpetcolorbarticksoutlinewidth    typecontourcarpettabletypetableheaderlinecolorwhitefillcolor#C8D4E3cellslinecolorwhitefillcolor#EBF0F8scatter3dlinecolorbarticksoutlinewidth    typescatter3dmarkercolorbarticksoutlinewidth    barpolartypebarpolarmarkerlinecolor#E5ECF6width?   scattergltypescatterglmarkercolorbarticksoutlinewidth    histogram2dcolorbarticksoutlinewidth    typehistogram2dcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scatterternarytypescatterternarymarkercolorbarticksoutlinewidth    heightC  marginl    b    r    tBp  titleyaxistickvals  @A  AtitletextPlayer sumticktext  @A  AwidthC  configshowLink¨editableªresponsiveêstaticPlotªscrollZoomæframesdatazmax?  y(  @A  PA  `A  pA  A  A  A  A  A  AtypeheatmapcolorscaleBlueredzminʿ  z(KQ4x˾J׾ ܾ¶1pA!>?(ժ=\=*ً<<ș;;¤=>f8"?<s?(־==8m=1<F<4<U>;>@'?mr?()>=j= =B$=i=55>t>(?Ps?(">\>\=5=1=˲=CI>0>@+?s?(29>>	.>=_=-=+>>4??u?(%6$><===
z=>?G?}~w?(!=3S=4_<pIR= ?_K?GXx?(7N;/hQ(|½`>0NA?y?(&w-dy¸;FYc>_?transposeéshowscaleáx(  ?   @  @@  @  @  @  @   A  A   A5c6e0de0c-3901-11f0-234e-bd09c571f662/e97923405a5e6801layoutxaxistickvals(  ?   @  @@  @  @  @  @   A  A   AtitletextDealer showingticktextA@   @@  @  @  @  @  A   A  A   templatelayout coloraxiscolorbarticksoutlinewidth    xaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhitehovermodeclosestpaper_bgcolorwhitegeoshowlakesèshowlandélandcolor#E5ECF6bgcolorwhitesubunitcolorwhitelakecolorwhitecolorscalesequential    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921diverging    #8e0152=ͧ#c51b7d>Lͧ#de77ae>#f1b6da>ͧ#fde0ef?   #f7f7f7?#e6f5d0?333#b8e186?Lͧ#7fbc41?fff#4d9221?  #276419sequentialminus    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921yaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhiteshapedefaultslinecolor#2a3f5fhoverlabelalignleftmapboxstylelightpolarangularaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6radialaxisgridcolorwhitetickslinecolorwhiteautotypenumbersstrictfontcolor#2a3f5fternaryaaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6caxisgridcolorwhitetickslinecolorwhitebaxisgridcolorwhitetickslinecolorwhiteannotationdefaultsarrowhead    arrowwidth?  arrowcolor#2a3f5fplot_bgcolor#E5ECF6titlex=Lͥscenexaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitezaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhiteyaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitecolorway#636efa#EF553B#00cc96#ab63fa#FFA15A#19d3f3#FF6692#B6E880#FF97FF#FECB52data scatterpolargltypescatterpolarglmarkercolorbarticksoutlinewidth    carpetbaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitetypecarpetaaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitescatterpolartypescatterpolarmarkercolorbarticksoutlinewidth    parcoordslinecolorbarticksoutlinewidth    typeparcoordsscattertypescattermarkercolorbarticksoutlinewidth    histogram2dcontourcolorbarticksoutlinewidth    typehistogram2dcontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcolorbarticksoutlinewidth    typecontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattercarpettypescattercarpetmarkercolorbarticksoutlinewidth    mesh3dcolorbarticksoutlinewidth    typemesh3dsurfacecolorbarticksoutlinewidth    typesurfacecolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattermapboxtypescattermapboxmarkercolorbarticksoutlinewidth    scattergeotypescattergeomarkercolorbarticksoutlinewidth    histogramtypehistogrammarkercolorbarticksoutlinewidth    pietypepieautomarginêchoroplethcolorbarticksoutlinewidth    typechoroplethheatmapglcolorbarticksoutlinewidth    typeheatmapglcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921bartypebarerror_ycolor#2a3f5ferror_xcolor#2a3f5fmarkerlinecolor#E5ECF6width?   heatmapcolorbarticksoutlinewidth    typeheatmapcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcarpetcolorbarticksoutlinewidth    typecontourcarpettabletypetableheaderlinecolorwhitefillcolor#C8D4E3cellslinecolorwhitefillcolor#EBF0F8scatter3dlinecolorbarticksoutlinewidth    typescatter3dmarkercolorbarticksoutlinewidth    barpolartypebarpolarmarkerlinecolor#E5ECF6width?   scattergltypescatterglmarkercolorbarticksoutlinewidth    histogram2dcolorbarticksoutlinewidth    typehistogram2dcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scatterternarytypescatterternarymarkercolorbarticksoutlinewidth    heightC  marginl    b    rA   tA  yaxistickvals(  @A  PA  `A  pA  A  A  A  A  A  AtitletextPlayer sumticktext(  @A  PA  `A  pA  A  A  A  A  A  AwidthC  configshowLink¨editableªresponsiveêstaticPlotªscrollZoomæframesdatazmax?  y(  @A  PA  `A  pA  A  A  A  A  A  AtypeheatmapcolorscaleGreyszminʿ  z(  ?  ?  ?  ?  ?  ?  ?      (  ?  ?  ?  ?  ?  ?        (  ?  ?  ?  ?  ?  ?        (  ?  ?  ?  ?  ?  ?        (  ?  ?  ?  ?  ?  ?        (  ?  ?  ?  ?  ?  ?        (  ?  ?  ?  ?  ?  ?        (  ?  ?  ?  ?  ?  ?        (  ?  ?  ?  ?  ?  ?  ?      (  ?  ?  ?  ?  ?  ?  ?      transposeéshowscale¡x(  ?   @  @@  @  @  @  @   A  A   A5c6e0de0c-3901-11f0-234e-bd09c571f662/dd4bace5c1b653a4layoutautosize¥xaxistickvals  ?   AtitletextDealer showingticktextA10templatelayout coloraxiscolorbarticksoutlinewidth    xaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhitehovermodeclosestpaper_bgcolorwhitegeoshowlakesèshowlandélandcolor#E5ECF6bgcolorwhitesubunitcolorwhitelakecolorwhitecolorscalesequential    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921diverging    #8e0152=ͧ#c51b7d>Lͧ#de77ae>#f1b6da>ͧ#fde0ef?   #f7f7f7?#e6f5d0?333#b8e186?Lͧ#7fbc41?fff#4d9221?  #276419sequentialminus    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921yaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhiteshapedefaultslinecolor#2a3f5fhoverlabelalignleftmapboxstylelightpolarangularaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6radialaxisgridcolorwhitetickslinecolorwhiteautotypenumbersstrictfontcolor#2a3f5fternaryaaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6caxisgridcolorwhitetickslinecolorwhitebaxisgridcolorwhitetickslinecolorwhiteannotationdefaultsarrowhead    arrowwidth?  arrowcolor#2a3f5fplot_bgcolor#E5ECF6titlex=Lͥscenexaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitezaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhiteyaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitecolorway#636efa#EF553B#00cc96#ab63fa#FFA15A#19d3f3#FF6692#B6E880#FF97FF#FECB52data scatterpolargltypescatterpolarglmarkercolorbarticksoutlinewidth    carpetbaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitetypecarpetaaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitescatterpolartypescatterpolarmarkercolorbarticksoutlinewidth    parcoordslinecolorbarticksoutlinewidth    typeparcoordsscattertypescattermarkercolorbarticksoutlinewidth    histogram2dcontourcolorbarticksoutlinewidth    typehistogram2dcontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcolorbarticksoutlinewidth    typecontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattercarpettypescattercarpetmarkercolorbarticksoutlinewidth    mesh3dcolorbarticksoutlinewidth    typemesh3dsurfacecolorbarticksoutlinewidth    typesurfacecolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattermapboxtypescattermapboxmarkercolorbarticksoutlinewidth    scattergeotypescattergeomarkercolorbarticksoutlinewidth    histogramtypehistogrammarkercolorbarticksoutlinewidth    pietypepieautomarginêchoroplethcolorbarticksoutlinewidth    typechoroplethheatmapglcolorbarticksoutlinewidth    typeheatmapglcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921bartypebarerror_ycolor#2a3f5ferror_xcolor#2a3f5fmarkerlinecolor#E5ECF6width?   heatmapcolorbarticksoutlinewidth    typeheatmapcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcarpetcolorbarticksoutlinewidth    typecontourcarpettabletypetableheaderlinecolorwhitefillcolor#C8D4E3cellslinecolorwhitefillcolor#EBF0F8scatter3dlinecolorbarticksoutlinewidth    typescatter3dmarkercolorbarticksoutlinewidth    barpolartypebarpolarmarkerlinecolor#E5ECF6width?   scattergltypescatterglmarkercolorbarticksoutlinewidth    histogram2dcolorbarticksoutlinewidth    typehistogram2dcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scatterternarytypescatterternarymarkercolorbarticksoutlinewidth    heightC  marginl    b    r    tBp  titleyaxistickvals  @A  AtitletextPlayer sumticktext  @A  AwidthC  configshowLink¨editableªresponsiveêstaticPlotªscrollZoomæframesdatazmax?  y(  @A  PA  `A  pA  A  A  A  A  A  AtypeheatmapcolorscaleBlueredzminʿ  z(Glz0P "f%q,>̺>(={߃u8co$>i>&?|d?(WfXfm`+iF0>'>*?Re?(ǜI,K=FTL%xF+V>>)?Ne?(I)q i ŧ?&\>v>-?g?(5
O0 tX	=>n??B7?4i?(7Jx1Ӿ񨽧>c"?7H?]o?(X Mweپuc辌p!=`n?'K?Qo?(-񕻾Ӿ;Ⱦ2sT>DTD?q?(ӾI쾄 .eվ*dVR:>S?transposeéshowscaleáx(  ?   @  @@  @  @  @  @   A  A   A5c6e0de0c-3901-11f0-234e-bd09c571f662/8b2f6661ab801d2clayoutxaxistypelogtitletextSteps to Finish Racetemplatelayout coloraxiscolorbarticksoutlinewidth    xaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhitehovermodeclosestpaper_bgcolorwhitegeoshowlakesèshowlandélandcolor#E5ECF6bgcolorwhitesubunitcolorwhitelakecolorwhitecolorscalesequential    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921diverging    #8e0152=ͧ#c51b7d>Lͧ#de77ae>#f1b6da>ͧ#fde0ef?   #f7f7f7?#e6f5d0?333#b8e186?Lͧ#7fbc41?fff#4d9221?  #276419sequentialminus    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921yaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhiteshapedefaultslinecolor#2a3f5fhoverlabelalignleftmapboxstylelightpolarangularaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6radialaxisgridcolorwhitetickslinecolorwhiteautotypenumbersstrictfontcolor#2a3f5fternaryaaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6caxisgridcolorwhitetickslinecolorwhitebaxisgridcolorwhitetickslinecolorwhiteannotationdefaultsarrowhead    arrowwidth?  arrowcolor#2a3f5fplot_bgcolor#E5ECF6titlex=Lͥscenexaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitezaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhiteyaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitecolorway#636efa#EF553B#00cc96#ab63fa#FFA15A#19d3f3#FF6692#B6E880#FF97FF#FECB52data scatterpolargltypescatterpolarglmarkercolorbarticksoutlinewidth    carpetbaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitetypecarpetaaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitescatterpolartypescatterpolarmarkercolorbarticksoutlinewidth    parcoordslinecolorbarticksoutlinewidth    typeparcoordsscattertypescattermarkercolorbarticksoutlinewidth    histogram2dcontourcolorbarticksoutlinewidth    typehistogram2dcontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcolorbarticksoutlinewidth    typecontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattercarpettypescattercarpetmarkercolorbarticksoutlinewidth    mesh3dcolorbarticksoutlinewidth    typemesh3dsurfacecolorbarticksoutlinewidth    typesurfacecolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattermapboxtypescattermapboxmarkercolorbarticksoutlinewidth    scattergeotypescattergeomarkercolorbarticksoutlinewidth    histogramtypehistogrammarkercolorbarticksoutlinewidth    pietypepieautomarginêchoroplethcolorbarticksoutlinewidth    typechoroplethheatmapglcolorbarticksoutlinewidth    typeheatmapglcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921bartypebarerror_ycolor#2a3f5ferror_xcolor#2a3f5fmarkerlinecolor#E5ECF6width?   heatmapcolorbarticksoutlinewidth    typeheatmapcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcarpetcolorbarticksoutlinewidth    typecontourcarpettabletypetableheaderlinecolorwhitefillcolor#C8D4E3cellslinecolorwhitefillcolor#EBF0F8scatter3dlinecolorbarticksoutlinewidth    typescatter3dmarkercolorbarticksoutlinewidth    barpolartypebarpolarmarkerlinecolor#E5ECF6width?   scattergltypescatterglmarkercolorbarticksoutlinewidth    histogram2dcolorbarticksoutlinewidth    typehistogram2dcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scatterternarytypescatterternarymarkercolorbarticksoutlinewidth    marginlBH  bBH  rBH  tBp  yaxistitletextPercent of EpisodesconfigshowLink¨editableªresponsiveêstaticPlotªscrollZoomæframesdatayo;o;B`;B`;B`;B`;B`;
#<
#<
#<D<D<o<o<o<o<C<1<1<1<1<j<j<h<h<h<h<h<h<<<o=C=C='='='='='='='=X94=X94=X94=j<=j<=`P=`P=`P=`P=`P=T=Ga=Ga=Ga=hm=hm=hm=#y=#y=#y=}=L7=L7=L7=L7=L7=t=t=t=t=t=P=P=-=-=-=
ף=
ף=
ף=T=1=1=1={=-=-=Q=Q=Q=v=v=v============d;=d;=d;=d;=d;=S=S=x=x=x=====F==   >   >   >   >   >$>$>$>$>$>$>L7	>L7	>L7	>Nb>Nb>Nb>Nb>Nb>Nb>Nb>n>n>>>>u>u>u>->->->->->!>!>!>!>/$>/$>/$>(>(>(>(>+>+>{.>{.>{.>/>-2>-2>-2>X94>X94>Q8>Q8>Q8>Q8>j<>j<>j<>j<>|?>|?>|?>7A>7A>C>C>9H>9H>9H>9H>9H>N>N>N>N>N>N>S>S>S>S>S>V>V>?5^>?5^>?5^>?5^>?5^>?5^>?5^>?5^>d;_>Zd>Zd>Zd>Zd>Zd>rh>rh>rh>rh>k>k>k>ףp>ףp>ףp>ףp>ףp>!r>!r>u>u>u>#y>#y>#y>#y>|>|>|>}>~>  >\>\>\>\>\>>>>$>$>$>$>>>>'1>^>^>^>q=>Ƌ>Ƌ>Ƌ>I>V>V>V>V>)\>)\>>>>>>>>>>z>>>>>>>>>>>>">">(>(>->->->?5>Ġ>Ġ>Ġ>Ġ>Ġ>ʡ>ʡ>Т>Т>/ݤ>/ݤ>/ݤ>/ݤ>B`>y>y>y>l>r>r>>~>~>~>V>V>V>V>V>{>{> > > > >33>33>33>33>33>33>X9>X9>j>ȶ>ȶ>ȶ>ȶ>Q>Q>Q>#۹>#۹>#۹>5^>Zd>Zd>>>>p>>>>  >  >7>7>7>o>o>o>>>>>ˡ>$>>q=>q=>q=>q=>q=>q=>q=>C>C>I>I>>O>V>V>Nb>Nb>Nb>Nb>n>n>n>n>t>t>>>>>=
>=
>=
>b>b>>>>>>">(>(>->->->>>>>>>G>M>M>>S>/>/>/>B`>T>ff>l>l>r>r>>>>~>D>D>D>D>{>{>{>>>> >>>>33>33>33>X9>X9>>>>>>>>Q>>5^>5^>5^>m>m>m>>>v>v>v>|>|> ? ? ?%?%????M?M?o?o?o???/?/?/?/?/?ˡ?ˡ?ˡ?T?$?ff?y?y?+?'1?'1?'1?'1?r?9??L7	?x	?q=
?q=
?q=
?~
?????I?I?I?D??h?h?h??{?V????)\?;?;?ף?ף?ף?`?&?sh???-?n???z?z?z?z?z?z?}??}??}?????+?+?K?K?K???b?u?u???????5^??Zd?Zd?Zd??(?(?j?/?/?/?-?-???5?v?R??w?w?w?A ?A ? ? ?%!?G!?!?!?M"?M"?\"?o#?o#?S#?
#?
#?/$?/$?/$?/$?%?ˡ%?ˡ%?$&?$&?ff&?+'?+'?+'?'?'?'?r(?r(?9(?(?x)?x)?^)?)?+?+?+?+?+?+?+?I,?I,?D,?V-?V-?O-?V.?V.?V.?V.?.?.?/?/?/? 0? 0?sh1?sh1?sh1?sh1?sh1?1?1?n2?n2?2?2?333?t3?3?3?X94?z4?j4?}?5?}?5?5?5?E6?E6?6?6?=
7?K7?P7?7?Q8?Q8?u8?8?9?9?9?#9?5^:?5^:?:?";?";?Zd;?;?m;?j<?j<?<?<?/=?-=?-=??5>??5>?v>?R>?>?|??|??  @?  @?A@?@?%A?%A?GA?A?A?JB?MB?\B?B?oC?SC?C?D?D?D?D?/D?E?ˡE?ˡE?TE?$F?F?F?yF?+G?G?G?G?'1H?H?H?H?L7I?^I?^I?q=J?q=J?J?J?CK?CK?K?1L?1L?DL?DL?L?OM?OM?hM?M?VN?VN?N?N?O?O?O? P? P?ףP?ףP?`P?shQ?shQ?Q?Q?nR?nR?R?R?33S?tS?FS?S?X9T?zT?T?T?}?U?U?U?V?+V?+V?V?=
W?KW?W?W?QX?QX?X?X?Y?XY?#Y?#Y?Z?5^Z?Z?HZ?"[?Zd[?[?m[?(\?j\?\?\?/]?p]?-]?]??5^?v^?R^?d;_?d;_?|_?  `?  `?A`?`?`?%a?Ga?7a?a?Jb?Mb?\b?b?oc?Sc?
c?
c?d?Zd?d?/d?e?B`e?ˡe?Te?$f?fff?f?yf?+g?lg?g?g?'1h?rh?L7i?L7i?L7i?xi?^i?i?q=j?~j?j?k?Ck?k?k?1l?Il?l?l?Vm?Om?hm?m?{n?Vn?n?n?)\o?)\o?o?;o?Nbp?Nbp?ףp?`p?&q?shq?q?q?-r?nr?!r?r?33s?ts?s?s?X9t?zt?jt?t?}?u?u?v?v?Ev?v?v?=
w?Kw?Pw?w?bx?Qx?ux?x?y?Xy?y?#y?z?5^z?z?Hz?"{?Zd{?{?m{?(|?j|?|?|?/}?p}?-}?}??5~?v~?R~?~?d;?|?w?  ?typescatternameOff policy MC Controlx   A   A  0A  0A  0A  0A  0A  @A  @A  @A  PA  PA  `A  `A  `A  `A  pA  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A   B   B   B   B   B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B   B   B  $B  $B  $B  (B  (B  (B  ,B  ,B  ,B  4B  4B  4B  4B  4B  4B  4B  4B  8B  8B  8B  8B  8B  <B  <B  @B  @B  @B  DB  HB  HB  HB  LB  PB  TB  TB  TB  TB  TB  XB  XB  XB  XB  XB  XB  \B  \B  \B  `B  `B  `B  `B  `B  `B  `B  dB  dB  hB  hB  hB  lB  lB  lB  pB  pB  pB  pB  pB  tB  tB  tB  tB  |B  |B  |B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B   C   C   C   C   C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  	C  
C  
C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C   C   C  !C  !C  !C  #C  $C  $C  $C  %C  %C  'C  'C  (C  (C  (C  )C  *C  *C  +C  +C  +C  ,C  ,C  ,C  ,C  ,C  ,C  /C  0C  0C  1C  2C  3C  3C  3C  4C  5C  6C  7C  7C  8C  8C  9C  :C  :C  ;C  >C  >C  >C  >C  ?C  ?C  ?C  AC  AC  BC  CC  DC  DC  DC  FC  FC  FC  GC  GC  MC  MC  MC  NC  NC  PC  PC  QC  SC  TC  TC  TC  VC  VC  VC  WC  WC  XC  XC  XC  YC  YC  ZC  ZC  ZC  [C  [C  ]C  ]C  ]C  ^C  ^C  _C  _C  _C  `C  `C  aC  aC  aC  aC  aC  bC  bC  bC  cC  dC  eC  fC  fC  gC  hC  hC  hC  hC  iC  jC  lC  mC  nC  oC  oC  oC  pC  qC  qC  rC  rC  sC  sC  sC  tC  uC  vC  vC  vC  xC  yC  zC  |C  }C  }C  ~C  C  C  C  C  C C  C C  C  C C  C C C  C  C  C  C  C  C C C C  C C  C C C  C  C  C C C  C  C  C C  C  C  C C C C  C C C C  C C C  C C C C  C  C C  C C  C  C C C C  C  C C C  C C  C  C C C  C C C C  C  C  C  C  C  C  C C C  C  C C  C  C  C C C C  C  C C  C C C  C C  C  C  C  C C C  C C C C  C  C  C C C C C  C C C C C C C C C C C C C C  C  C  C  C C  C C C C C  C C C C C  C  C C C  C C  C C  C  C C  C C C C C  C  C C C C  C  C  C C C  C  C C  C  C  C  C C C  C  C  C C C  C C  C  C  C C C C  C  C C  C C  C C C  C  C C  C  C  C  C C  C  C  C C C C C  C C C C  C C C  C  C C C  C  C C  C  C  C  C C  C  C C C  C  C C C C  C  C  C  C C C  C  C  C C C  C  C C C  C C  C  C  C C C C C  C  C  C C C   D @ D D @D @D D D D D  D D D D  D D @D D  D @D D D  	D @
D 
D @D D  D D D  D @D D @D @D D @D @D  D D D D  D @D D D  D D @D D  D @D @D D D @D  D D  !D !D "D "D #D  $D @$D $D $D  %D  %D )D  *D *D *D *D  +D ,D  -D @-D @.D /D 3D @5D 5D 6D @7D  9D :D :D ;D ;D  <D @=D  @D  AD  BD CD DD DD @ED  ID ID ID KD @LD @MD MD @ND ND OD  QD QD RD  SD SD  TD  TD TD UD @VD VD  XD [D @^D @^D _D  bD  bD bD cD cD  dD dD  eD eD fD iD @jD @mD @nD nD @pD pD qD qD  rD zD D D `D  D  D D  D D  D `D D @D `D D D  D  Dyo;o;;;;;
#<
#<
#<
#<X94<B`e<B`e<B`e<u<t<t<t<
ף<
ף<h<h<h<h<h<h<h<h<h<o=o=o=w=w=w=w=w=w=w=1,=1,=1,=Q8=Q8=Q8=D=D=D=T=T=T=T=xi=xi=xi=xi=xi=u=u=u=%=%=%=L7=L7=L7=L7=O=O=====P=-=-=-=w=
ף=
ף= = = = = = =X9=X9=================d;=d;=d;=d;=d;=x=x=x=x=x=======%>%>%>%>%>%>>>>+>+>+>'1>C>C>C>V>V>V>n>n>n>n>z>z>>>>>>>>>w>w>w>
#>
#>
#>
#>T%>T%>(>(>(>{.>{.>{.>{.>{.>-2>-2>-2>-2>Q8>Q8>Q8>Q8>Q8>Q8>5^:>5^:>|?>|?>|?>|?>|?>7A>7A>C>C>D>ˡE>9H>9H>9H>L>L>L>L>M>R>R>R>R>R>T>T>Z>Z>Z>Z>Z>?5^>?5^>?5^>?5^>d;_>Ga>Ga>Zd>Zd>Zd>~j>~j>~j>~j>~j>~j>Dl>Dl>n>n>ףp>ףp>u>u>u>u>u>w>w>m{>m{>m{>m{>}>}>>>>%>J>J>>>>>>+>+>+>+>+>L7>L7>L7>L7>q=>q=>I>I>I>I>ҍ>ҍ>ҍ>V>َ>n>n>n>n>n>n>n>z>z>z>z>+>+>+>+>P>P>b>>>>>>㥛>㥛>(>>->->R>R>w>w>ʡ>ʡ>ʡ>ʡ>S>S>S>T>T>T>T>T>r>r>r>r>r>>x>1>1>1>1>1>h>h>h>{>>> > >&>&>->->33>33>X9>X9>E>E>E>E>η>η>η>#۹>#۹>#۹>#۹>Zd>Zd>Zd>>>>>>>>>>>7>7>>>>>>>$>$>$>>>>9>9>>>>>>>I>V>V>V>V>;>;>;>Nb>`>>>t>t>t>>>>>>+>=
>u>u>u>>>>(>(>(>(>/>/>d;>d;>d;>d;>w>A>>>>>>
>
>B`>B`>B`>T>l>l>l>>>>>>>>1>1>{>{>{>{>>>ף>ף>ף>->->->F>F>F>X9>}?>}?>>>>>>#>#>#>#>Zd>Zd>Zd>m>p>p>p>>>>A ?A ?A ? ?%?%????M?M?\?o?o?
?
?
?Z?Z?ˡ?ˡ?ˡ?ˡ?ˡ?$?$?y?y?y?+?l?'1?'1?'1?9?9??L7	?^	?^	?
?
?
?
?C?C???I?I?O?O?O?O???V?V????)\?? ? ?Nb?ף?`????-?-?33?33?33?33?t?F??j?j?j????E?E?E?+?=
?=
?K???b?u?u???#?#?#????H?Zd?Zd??m?j?j?p?p?p?p??5??5??5?w?w?w?w?w?w? ? ? ?%!?%!?7!?7!?!?M"?M"?\"?o#?o#?#?#?
#?$?Z$?%?%?%?ˡ%?ˡ%?T%?&?&?&?y&?l'?l'?'?'1(?'1(?r(?L7)?L7)?L7)?)?)?)?q=*?~*?*?+?C+?+?+?1,?I,?D,?h-?h-?h-?h-?.?.?.?.?.?/?)\/? 0? 0? 0?Nb0?ף0?`0?&1?sh1?n2?n2?n2?n2?2?2?333?F3?F3?3?j4?j4?j4?}?5?}?5?5?5?6?E6?6?6?K7?K7?7?7?b8?u8?u8?X9?X9?X9?#9?#9?:?:?:?H:?";?Zd;?;?m;?(<?<?<?<?p=?p=?-=?=??5>?v>?>?>?|??|??  @?  @?@?@?@?GA?GA?7A?JB?JB?B?B?B?oC?SC?C?
C?D?ZD?D?/D?B`E?B`E?ˡE?ffF?ffF?ffF?F?yF?+G?lG?G?'1H?'1H?9H?9H?H?L7I?^I?^I?I?q=J?J?J?K?K?K?K?1L?IL?DL?L?VM?OM?hM?{N?{N?VN?N?N?O?)\O?O?NbP?NbP?NbP?ףP?`P?&Q?shQ?Q?-R?-R?!R?!R?33S?33S?tS?X9T?X9T?X9T?T?T?T?}?U?U?U?V?V?V?V?KW?KW?PW?bX?bX?QX?uX?Y?Y?XY?Y?#Y?Z?5^Z?Z?HZ?"[?Zd[?m[?m[?j\?j\?/]?/]?/]?p]?-]?]?v^?v^?R^?d;_?d;_?|_?w_?  `?A`?`?`?%a?Ga?7a?a?Jb?\b?\b?b?oc?Sc?c?d?d?d?d?/d?e?B`e?ˡe?Te?$f?fff?yf?yf?+g?lg?g?g?'1h?rh?9h?h?L7i?xi?^i?i?~j?~j?j?k?Ck?k?k?Il?Il?Dl?l?Vm?Om?hm?m?{n?Vn?n?n?o?)\o?o?;o? p?Nbp?ףp?`p?&q?shq?q?q?nr?nr?!r?r?33s?ts?Fs?s?X9t?zt?jt?t?}?u?u?u?v?Ev?+v?v?=
w?Kw?Pw?w?Qx?Qx?ux?x?y?Xy?#y?#y?z?5^z?z?Hz?"{?Zd{?{?(|?(|?j|?|?|?/}?p}?-}?}??5~?v~?R~?~?d;?|?w?  ?typescatternameRandom Policyx   A   A  @A  @A  @A  @A  PA  PA  PA  PA  `A  pA  pA  pA  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A   B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B   B   B   B   B   B  $B  $B  $B  $B  $B  (B  (B  (B  (B  (B  ,B  ,B  ,B  0B  0B  0B  4B  4B  4B  4B  4B  4B  8B  8B  8B  <B  <B  <B  @B  DB  DB  DB  HB  HB  HB  LB  LB  LB  LB  PB  PB  TB  TB  TB  TB  TB  TB  TB  XB  \B  \B  \B  `B  `B  `B  `B  dB  dB  hB  hB  hB  lB  lB  lB  lB  lB  pB  pB  pB  pB  tB  tB  tB  tB  tB  tB  xB  xB  |B  |B  |B  |B  |B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B   C   C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  	C  	C  
C  
C  
C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C   C   C   C   C  !C  !C  "C  "C  "C  "C  #C  $C  %C  %C  %C  'C  'C  (C  (C  )C  )C  )C  *C  +C  +C  +C  ,C  ,C  ,C  ,C  ,C  -C  -C  .C  .C  /C  /C  /C  /C  0C  0C  1C  1C  1C  2C  2C  2C  3C  3C  3C  4C  6C  6C  7C  8C  8C  9C  9C  :C  :C  :C  :C  ;C  ;C  ;C  <C  =C  =C  =C  >C  @C  @C  BC  BC  BC  CC  DC  DC  GC  GC  GC  HC  HC  IC  JC  JC  KC  KC  KC  LC  LC  NC  NC  NC  NC  NC  PC  PC  QC  QC  QC  RC  SC  TC  TC  TC  VC  VC  WC  XC  YC  YC  [C  [C  [C  [C  \C  \C  ]C  ]C  _C  _C  `C  `C  `C  `C  aC  aC  bC  bC  cC  cC  cC  dC  eC  gC  gC  hC  iC  jC  kC  kC  kC  nC  nC  oC  oC  oC  oC  pC  rC  tC  uC  uC  uC  vC  vC  vC  xC  xC  xC  {C  |C  |C  ~C C C  C  C  C C C  C  C  C C  C  C C  C  C C  C C C C C C C  C  C  C C C C C C C C C C  C  C C C  C C C  C C C  C  C  C C C C C C  C  C C  C  C  C  C C C  C C C  C  C  C  C C C C C C  C  C  C C C  C C  C C C C C  C  C  C  C C  C C  C  C  C C C  C C  C C C C C  C  C C C C  C C C C C C  C  C C  C C C  C  C C C C  C  C  C  C  C C C  C C C  C  C C  C C C  C  C  C C C  C  C  C C C C C C  C  C C C C  C  C  C  C  C C C C  C  C C  C C C  C C  C  C C C C C C C  C C  C  C  C  C  C C  C C C  C C  C  C C C C C  C  C C C  C C C C C  C C C C  C C C C C  C  C  C C  C C C  C  C C C C  C  C  C C C C  C C C  C C C C  C  C @ D  D  D D D  D  D D  D D  D D  D D  D @	D  
D  
D 
D 
D  D  D  D @D @D D D D  D D D  D @D D  D  D D D  D D D D D D @D D D  D D D D D @ D  !D @!D !D  "D #D #D  %D  %D %D @'D 'D @(D  )D *D @+D  ,D ,D .D /D 0D  1D  1D 1D 5D 6D 8D @9D :D :D @<D =D >D  ?D ?D @D @D AD  BD @CD CD DD @ED ED @FD GD  HD  ID  JD  KD  ND OD SD SD  TD  VD VD WD @YD \D _D `D aD bD eD  gD @gD hD lD oD  qD @qD tD uD  vD @yD @yD  {D @|D  D D D D D @D D D  D D  D  D  D  D @D D  D  D  D D D @D D D D D D D5c6e0de0c-3901-11f0-234e-bd09c571f662/47097f3aa74a6daflayoutxaxistypelogtitletextSteps to Finish Racetemplatelayout coloraxiscolorbarticksoutlinewidth    xaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhitehovermodeclosestpaper_bgcolorwhitegeoshowlakesèshowlandélandcolor#E5ECF6bgcolorwhitesubunitcolorwhitelakecolorwhitecolorscalesequential    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921diverging    #8e0152=ͧ#c51b7d>Lͧ#de77ae>#f1b6da>ͧ#fde0ef?   #f7f7f7?#e6f5d0?333#b8e186?Lͧ#7fbc41?fff#4d9221?  #276419sequentialminus    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921yaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhiteshapedefaultslinecolor#2a3f5fhoverlabelalignleftmapboxstylelightpolarangularaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6radialaxisgridcolorwhitetickslinecolorwhiteautotypenumbersstrictfontcolor#2a3f5fternaryaaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6caxisgridcolorwhitetickslinecolorwhitebaxisgridcolorwhitetickslinecolorwhiteannotationdefaultsarrowhead    arrowwidth?  arrowcolor#2a3f5fplot_bgcolor#E5ECF6titlex=Lͥscenexaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitezaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhiteyaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitecolorway#636efa#EF553B#00cc96#ab63fa#FFA15A#19d3f3#FF6692#B6E880#FF97FF#FECB52data scatterpolargltypescatterpolarglmarkercolorbarticksoutlinewidth    carpetbaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitetypecarpetaaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitescatterpolartypescatterpolarmarkercolorbarticksoutlinewidth    parcoordslinecolorbarticksoutlinewidth    typeparcoordsscattertypescattermarkercolorbarticksoutlinewidth    histogram2dcontourcolorbarticksoutlinewidth    typehistogram2dcontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcolorbarticksoutlinewidth    typecontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattercarpettypescattercarpetmarkercolorbarticksoutlinewidth    mesh3dcolorbarticksoutlinewidth    typemesh3dsurfacecolorbarticksoutlinewidth    typesurfacecolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattermapboxtypescattermapboxmarkercolorbarticksoutlinewidth    scattergeotypescattergeomarkercolorbarticksoutlinewidth    histogramtypehistogrammarkercolorbarticksoutlinewidth    pietypepieautomarginêchoroplethcolorbarticksoutlinewidth    typechoroplethheatmapglcolorbarticksoutlinewidth    typeheatmapglcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921bartypebarerror_ycolor#2a3f5ferror_xcolor#2a3f5fmarkerlinecolor#E5ECF6width?   heatmapcolorbarticksoutlinewidth    typeheatmapcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcarpetcolorbarticksoutlinewidth    typecontourcarpettabletypetableheaderlinecolorwhitefillcolor#C8D4E3cellslinecolorwhitefillcolor#EBF0F8scatter3dlinecolorbarticksoutlinewidth    typescatter3dmarkercolorbarticksoutlinewidth    barpolartypebarpolarmarkerlinecolor#E5ECF6width?   scattergltypescatterglmarkercolorbarticksoutlinewidth    histogram2dcolorbarticksoutlinewidth    typehistogram2dcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scatterternarytypescatterternarymarkercolorbarticksoutlinewidth    marginlBH  bBH  rBH  tBp  yaxistitletextPercent of EpisodesconfigshowLink¨editableªresponsiveêstaticPlotªscrollZoomæframesdatayQ8=Q8=Q8=Q8=Q8=Q8=Q8=Q8=Q8=Q8=Q8=Q8=Q8=Q8=Q8=Q8=Q8=Q8=Q8=Q8=Q8=Q8=Q8=Q8=Q8=Q8=Q8=Q8=Q8=Q8=Q8=Q8=Q8=Q8=Q8=Q8=Q8=Q8=Q8=Q8=Q8=Q8=Q8=Q8=Q8=>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>)\>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>/>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>X9>7>7>7>7>7>7>7>7>7>7>7>7>7>7>7>7>7>7>7>7>7>7>7>7>7>7>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>{>{>{>{>{>{>{>{>{>{>{>{>{>{>{>{>{>{>{>{>{>{>{>{>{>{>{>{>{>{>{>{>{>{>{>{>{>{>{>{>{>{>{>{>{>{>o?o?o?o?o?o?o?o?o?o?o?o?o?o?o?o?o?o?o?o?o?o?o?o?o?o?o?o?o?o?o?o?o?o?o?o?o?o?o?o?o?o?o?o?o?o?o?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?33?33?33?33?33?33?33?33?33?33?33?33?33?33?33?33?33?33?33?33?33?33?33?33?33?33?33?+?+?+?+?+?+?+?+?+?+?+?+?+?(?(?(?(?(?(?(?(?(?(?(?(?(?(?(?(?(?(?(?(?(?(?7!?7!?7!?7!?7!?7!?7!?7!?7!?7!?7!?7!?7!?7!?7!?7!?7!?7!?7!?7!?7!?Z$?Z$?Z$?Z$?Z$?Z$?Z$?Z$?Z$?Z$?Z$?C+?C+?C+?C+?C+?C+?C+?C+?C+?C+?C+?C+?C+?C+?C+?C+?C+?C+?C+?C+?C+?C+?C+?C+?C+?C+?C+? 0? 0? 0? 0? 0? 0? 0? 0? 0? 0? 0? 0? 0? 0? 0? 0? 0? 0? 0?=
7?=
7?=
7?=
7?=
7?=
7?=
7?=
7?=
7?=
7?=
7?=
7?=
7?=
7?=
7?=
7?=
7?=
7?=
7?=
7?=
7?=
7?=
7?=
7?=
7?=
7?=
7?Zd;?Zd;?Zd;?Zd;?Zd;?Zd;?Zd;?Zd;?Zd;?Zd;?Zd;?Zd;?Zd;?Zd;?Zd;?Zd;?Zd;?GA?GA?GA?GA?GA?GA?GA?GA?GA?GA?GA?GA?GA?GA?GA?GA?GA?GA?GA?GA?GA?GA?GA?ZD?ZD?ZD?ZD?ZD?ZD?ZD?ZD?ZD?ZD?ZD?ZD?^I?^I?^I?^I?^I?^I?^I?^I?^I?^I?^I?^I?^I?^I?^I?^I?^I?^I?^I?^I?^I?IL?IL?IL?IL?IL?IL?IL?IL?IL?IL?O?O?O?O?O?O?O?O?O?O?O?O?O?R?R?R?R?R?R?R?R?R?R?R?R?R?zT?zT?zT?zT?zT?zT?=
W?=
W?=
W?=
W?=
W?=
W?=
W?=
W?=
W?=
W?X?X?X?X?X?X?X?5^Z?5^Z?5^Z?5^Z?5^Z?5^Z?(\?(\?(\?(\?(\?(\?(\?R^?R^?R^?R^?R^?R^?R^?R^?R^?R^?A`?A`?A`?A`?A`?A`?a?a?a?a?a?a?Sc?Sc?Sc?Sc?Sc?Sc?/d?/d?/d?/d?/d?/d?+g?+g?+g?+g?+g?+g?+g?+g?+g?9h?9h?9h?9h?9h?9h?^i?^i?^i?^i?j?j?j?j?k?k?k?k?Il?Il?m?m?m?m?m?m?)\o?)\o?)\o?)\o?)\o?)\o?Nbp?Nbp?Nbp?Nbp?shq?shq?shq?shq?nr?nr?nr?nr?33s?33s?33s?Fs?Fs?zt?zt?zt?jt?}?u?}?u?u?u?Ev?Ev?=
w?=
w?=
w?Pw?Pw?Qx?Qx?Qx?y?y?y?Xy?#y?#y?z?z?z?Hz?Zd{?Zd{?{?m{?(|?j|?|?|?/}?-}?-}?}?v~?v~?R~?~?|?|?w?  ?typescatternameMonte Carlo ϵ-Softx  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A  0A  0A  0A  0A  0A  0A  0A  0A  0A  0A  0A  0A  0A  0A  0A  0A  0A  0A  0A  0A  0A  0A  0A  0A  0A  0A  0A  0A  0A  0A  0A  0A  0A  0A  0A  0A  0A  0A  0A  0A  0A  0A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A   B   B   B   B   B   B   B   B   B   B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B   B   B   B   B   B   B   B   B   B   B  $B  $B  $B  $B  $B  $B  (B  (B  (B  (B  (B  (B  ,B  ,B  ,B  ,B  ,B  ,B  0B  0B  0B  0B  0B  0B  4B  4B  4B  4B  4B  4B  4B  4B  4B  8B  8B  8B  8B  8B  8B  <B  <B  <B  <B  @B  @B  @B  @B  DB  DB  DB  DB  HB  HB  LB  LB  LB  LB  LB  LB  PB  PB  PB  PB  PB  PB  TB  TB  TB  TB  XB  XB  XB  XB  \B  \B  \B  \B  `B  `B  `B  dB  dB  hB  hB  hB  lB  pB  pB  tB  tB  xB  xB  |B  |B  |B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  Byo;o;o;o;
#<
#<
#<
#<
#<
#<o<o<o<o<o<o<t<t<<<<<<<<<h<h<h<+=+=+=+=w=w=w=w=w=w=
#='= 0= 0=X94=D=D=D=D=Ga=Ga=Ga=Ga=Ga=Ga=Ga=hm=hm=hm=}=}=}=}=L7=L7=L7=L7=L7=sh=sh=sh=sh=t====ʡ=ʡ=ʡ=ʡ===== = = =X9=X9=j=j=j=j==========`==="="="=l=l=l=l=l=l============J>J>J>>>>+>+>L7	>L7	>O>O>O>O>n>n>n>n>n>z>z>u>u>u>u>>>->->->!>!>!>!>(>(>(>(>(>(>(>V->V->V->V->{.>-2>-2>-2>-2>X94>X94>j<>j<>j<>j<>j<>j<>j<>j<>|?>|?>|?>\B>\B>\B>ˡE>ˡE>ˡE>^I>^I>^I>^I>L>L>L>M>`P>`P>`P>R>R>V>V>V>bX>bX>"[>"[>"[>/]>/]>Ga>Ga>Ga>Ga>Sc>Sc>fff>fff>fff>k>k>k>k>k>ףp>ףp>ףp>ףp>ףp>!r>!r>u>u>u>w>w>x>|>|>|>|>~>~>>>o>o>o>o>o>>+>+>+>+>+>+>+>'1>'1>^>^>^>>>O>O>O>O>O>)\>)\>)\>)\>Nb>Nb>>>>t>t>t>z>z>>>>b>b>b>b>>>>>>>>>>d;>d;>d;>d;>d;>Ġ>Ġ>Ġ>ʡ>ʡ>
ף>
ף>
ף>
ף>Z>/ݤ>ff>ff>ff>l>l>>r>>~>~>~>1>1>1>V>V>>>>>>>>>>!>!>33>j>j>j>}?>K>K>K>K>Ը>Ը>Ը>X>5^>5^>Zd>Zd>p>p>p>p>v>v>  >  >  >>>>>>>>>ˡ>ˡ>ˡ>+>+>+>'1>'1>L7>L7>^>C>C>C>>I>O>O>V>V>>;>;>`>`>sh>n>n>>>>>>>+>+>P>P>>>>>>>(>(>(>>->->R>R>A>A>A>G>G>>Z>Z>Z>Z>Z>y>y>y>y>y>>>>>x>1>1>1>1>1>V>V>h>{>>>>>>>>->X9>X9>X9>X9>>>>E>>Q>Q>Q>#>#>#>5^>H>m>m>j>v>v>v>v>   ?   ?   ?A ?7?7?7?7?7?M?M?M??????/?/?/?/?/??ˡ?ˡ?T?$?y?y?y?l?l???'1????L7	?
?
?
?
?
?
?C?C??D?D?D?D??V???????????;?ף?ף?ף?`????-?-?n?t?t?t?t???X9?z??????????????Q?Q???X?X?#?#??5^?H?H?"?Zd??m?j?j???p?p???v?v?d;?d;?d;?|?w?   ?A ? ? ?%!?!?!?!?J"?"?"?"?
#?
#?
#?
#?$?Z$?/$?/$?$&?$&?$&?$&?$&?ff&?y&?y&?+'?l'?'?'?r(?r(?(?(?L7)?x)?q=*?q=*?q=*?~*?+?+?+?+?+?1,?I,?O-?O-?O-?O-?V.?V.?V.?V.?.?.?)\/?)\/?/?;/? 0?Nb0?`0?`0?sh1?sh1?1?-2?-2?!2?!2?2?333?t3?3?3?z4?z4?j4?4?}?5?5?6?6?E6?K7?K7?K7?K7?P7?b8?b8?Q8?u8?8?9?#9?#9?#9?:?5^:?:?H:?";?;?;?m;?(<?j<?<?<?/=?p=?=?=??5>?v>?R>?>?d;??|??w??  @?@?@?%A?%A?GA?7A?A?JB?\B?\B?B?SC?SC?D?D?D?D?D?E?E?B`E?ˡE?TE?$F?ffF?yF?yF?+G?G?G?G?'1H?rH?9H?H?xI?xI?^I?I?q=J?~J?J?K?CK?1L?1L?1L?DL?DL?L?hM?hM?hM?M?VN?VN?N?N?)\O?)\O?O?;O?NbP?NbP?&Q?&Q?&Q?shQ?Q?Q?nR?nR?!R?R?33S?tS?S?S?X9T?zT?jT?}?U?}?U?U?U?V?EV?=
W?=
W?=
W?KW?PW?bX?bX?X?X?X?Y?XY?Y?#Y?Z?Z?Z?HZ?"[?Zd[?[?m[?j\?j\?\?\?/]?p]?-]?]??5^?v^?R^?^?d;_?w_?w_?  `?`?`?`?%a?Ga?a?a?Jb?Mb?\b?b?Sc?Sc?c?d?d?Zd?d?e?e?ˡe?ˡe?Te?$f?fff?f?yf?lg?lg?g?'1h?'1h?9h?9h?h?L7i?xi?^i?i?~j?~j?j?k?Ck?k?k?1l?Il?Dl?l?Vm?Om?hm?m?{n?Vn?n?n?o?)\o?o?;o? p?Nbp?ףp?`p?&q?shq?q?-r?-r?nr?!r?r?33s?ts?Fs?s?X9t?zt?jt?t?}?u?u?u?v?Ev?+v?v?Kw?Kw?Pw?w?bx?Qx?ux?x?Xy?Xy?y?#y?z?5^z?z?Hz?"{?Zd{?{?m{?(|?j|?|?|?/}?p}?-}?}??5~?v~?R~?~?d;?|?w?  ?typescatternameRandom Policyx  @A  @A  PA  PA  `A  `A  `A  `A  `A  `A  pA  pA  pA  pA  pA  pA  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A   B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B   B  $B  $B  (B  (B  (B  ,B  ,B  ,B  ,B  ,B  ,B  0B  0B  4B  4B  8B  8B  8B  8B  8B  8B  8B  <B  <B  <B  @B  @B  @B  DB  DB  HB  HB  LB  LB  LB  LB  PB  PB  PB  PB  PB  TB  TB  XB  XB  XB  XB  \B  \B  `B  `B  `B  dB  dB  dB  dB  hB  hB  hB  hB  hB  hB  hB  lB  lB  lB  lB  pB  tB  tB  tB  tB  xB  xB  |B  |B  |B  |B  |B  |B  |B  |B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B   C   C   C   C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  	C  	C  	C  
C  
C  
C  
C  
C  
C  
C  
C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C   C   C  !C  !C  !C  !C  "C  "C  #C  #C  #C  $C  %C  %C  (C  (C  )C  )C  )C  +C  +C  .C  /C  /C  /C  /C  /C  0C  0C  0C  0C  0C  1C  1C  2C  2C  4C  5C  5C  5C  5C  5C  7C  7C  8C  9C  :C  ;C  ;C  <C  <C  <C  <C  =C  >C  >C  >C  >C  ?C  ?C  ?C  @C  AC  BC  BC  BC  CC  CC  CC  DC  EC  GC  GC  HC  IC  IC  IC  IC  JC  JC  JC  KC  MC  MC  MC  MC  MC  OC  OC  OC  PC  PC  QC  QC  QC  RC  RC  RC  RC  RC  SC  TC  TC  VC  XC  ZC  ZC  ZC  [C  [C  \C  ]C  ^C  _C  _C  _C  `C  aC  aC  aC  aC  aC  aC  cC  cC  dC  eC  eC  eC  eC  gC  hC  iC  iC  iC  jC  jC  jC  kC  lC  lC  lC  nC  oC  oC  oC  pC  qC  qC  qC  sC  sC  tC  wC  wC  wC  wC  {C  {C  |C  ~C  C  C  C  C C  C  C  C  C C C C C C C  C  C  C  C  C  C  C C C C  C C C  C C C  C  C C C  C  C  C  C C C C  C C  C C  C C  C  C  C  C C  C  C  C C C C C  C C  C  C C C C C C  C C C  C C  C  C C C  C  C C  C C C C  C C C  C  C  C  C  C C C C C  C  C  C  C C C  C  C C C  C C  C  C C C  C C C  C  C C  C  C C C  C  C C  C  C C C C C  C  C  C  C C C C  C C  C C  C  C  C  C C  C C  C C C  C C  C C C  C C  C  C  C  C C  C  C C  C C  C  C C C  C C  C C  C  C C  C  C C C C  C  C C C  C C  C  C  C C C  C C C C  C C C  C C C  C  C C C  C C C  C  C  C C C  C C C C  C C C C C C C C  C C C C C C  C  C  C  C  C C  C C  C C C C  C C C C  C C  C C @ D @ D @ D  D @D  D  D @D @D @D D  D D D  D @D @D D D D  	D @	D 
D 
D D @D  D @D  D D D D  D @D D D D D  D  D D  D D D D  D @D D D @D @D D  "D  "D  #D  $D @$D @$D $D $D &D @'D  (D (D  *D @*D @*D *D  +D  +D @+D @+D @,D ,D -D  .D .D  /D  /D  0D  1D 2D @4D 4D  6D 6D  7D 7D @9D  ;D ;D ;D @<D =D >D ?D  @D @BD DD  ED ED GD HD ID LD  MD MD MD MD @ND  PD  TD @VD  WD @YD ]D ^D  `D aD  bD bD eD @gD  hD @hD  jD jD jD jD @mD mD  nD @qD @rD @uD vD vD  yD `D D `D `D D @D D  D `D D  D D  D  D @D  D D D D  D D D `D D D5c6e0de0c-3901-11f0-234e-bd09c571f662/e01572e8e76890cdlayoutxaxistypelogtitletextSteps to Finish Racetemplatelayout coloraxiscolorbarticksoutlinewidth    xaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhitehovermodeclosestpaper_bgcolorwhitegeoshowlakesèshowlandélandcolor#E5ECF6bgcolorwhitesubunitcolorwhitelakecolorwhitecolorscalesequential    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921diverging    #8e0152=ͧ#c51b7d>Lͧ#de77ae>#f1b6da>ͧ#fde0ef?   #f7f7f7?#e6f5d0?333#b8e186?Lͧ#7fbc41?fff#4d9221?  #276419sequentialminus    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921yaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhiteshapedefaultslinecolor#2a3f5fhoverlabelalignleftmapboxstylelightpolarangularaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6radialaxisgridcolorwhitetickslinecolorwhiteautotypenumbersstrictfontcolor#2a3f5fternaryaaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6caxisgridcolorwhitetickslinecolorwhitebaxisgridcolorwhitetickslinecolorwhiteannotationdefaultsarrowhead    arrowwidth?  arrowcolor#2a3f5fplot_bgcolor#E5ECF6titlex=Lͥscenexaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitezaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhiteyaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitecolorway#636efa#EF553B#00cc96#ab63fa#FFA15A#19d3f3#FF6692#B6E880#FF97FF#FECB52data scatterpolargltypescatterpolarglmarkercolorbarticksoutlinewidth    carpetbaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitetypecarpetaaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitescatterpolartypescatterpolarmarkercolorbarticksoutlinewidth    parcoordslinecolorbarticksoutlinewidth    typeparcoordsscattertypescattermarkercolorbarticksoutlinewidth    histogram2dcontourcolorbarticksoutlinewidth    typehistogram2dcontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcolorbarticksoutlinewidth    typecontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattercarpettypescattercarpetmarkercolorbarticksoutlinewidth    mesh3dcolorbarticksoutlinewidth    typemesh3dsurfacecolorbarticksoutlinewidth    typesurfacecolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattermapboxtypescattermapboxmarkercolorbarticksoutlinewidth    scattergeotypescattergeomarkercolorbarticksoutlinewidth    histogramtypehistogrammarkercolorbarticksoutlinewidth    pietypepieautomarginêchoroplethcolorbarticksoutlinewidth    typechoroplethheatmapglcolorbarticksoutlinewidth    typeheatmapglcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921bartypebarerror_ycolor#2a3f5ferror_xcolor#2a3f5fmarkerlinecolor#E5ECF6width?   heatmapcolorbarticksoutlinewidth    typeheatmapcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcarpetcolorbarticksoutlinewidth    typecontourcarpettabletypetableheaderlinecolorwhitefillcolor#C8D4E3cellslinecolorwhitefillcolor#EBF0F8scatter3dlinecolorbarticksoutlinewidth    typescatter3dmarkercolorbarticksoutlinewidth    barpolartypebarpolarmarkerlinecolor#E5ECF6width?   scattergltypescatterglmarkercolorbarticksoutlinewidth    histogram2dcolorbarticksoutlinewidth    typehistogram2dcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scatterternarytypescatterternarymarkercolorbarticksoutlinewidth    marginlBH  bBH  rBH  tBp  yaxistitletextPercent of EpisodesconfigshowLink¨editableªresponsiveêstaticPlotªscrollZoomæframesdatay=========================================================================M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>M>  >  >  >  >  >  >  >  >  >  >  >  >  >  >  >  >  >  >  >  >  >  >  >  >  >  >  >  >  >  >  >  >  >  >  >  >  >  >  >  >  >  >  >  >  >  >  >  >  >n>n>n>n>n>n>n>n>n>n>n>n>n>n>n>n>n>n>n>n>n>n>n>n>n>n>n>n>n>n>n>n>n>n>n>n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>!>!>!>!>!>!>!>!>!>!>!>!>!>!>!>!>!>!>!>!>!> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?I?E?E?E?E?E?E?E?E?E?E?E?E?E?E?E?E?E?E?E?E?E?E?E?E?E?E?E?E?E?E?E?E?E?E?E?E?E?E?E?j?j?j?j?j?j?j?j?j?j?j?j?j?j?j?j?j?j?j?j?j?j?j?j?%!?%!?%!?%!?%!?%!?%!?%!?%!?%!?%!?%!?%!?%!?%!?%!?%!?%!?T%?T%?T%?T%?T%?T%?T%?T%?T%?T%?T%?T%?T%?T%?T%?T%?T%?T%?T%?+?+?+?+?+?+?+?+?+?+?+?+?+?+?+?+?+?+?+?+?+?+?1?1?1?1?1?1?1?1?1?1?1?1?1?1?1?1?1?1?1?1?1?1?1?1?4?4?4?4?4?4?4?4?4?4?4?4?4?5^:?5^:?5^:?5^:?5^:?5^:?5^:?5^:?5^:?5^:?5^:?5^:?5^:?5^:?5^:?5^:?5^:?5^:?5^:?5^:?5^:?d;??d;??d;??d;??d;??d;??d;??d;??d;??d;??d;??d;??d;??d;??d;??d;??d;??d;??d;??
C?
C?
C?
C?
C?
C?
C?
C?
C?
C?
C?
C?
C?
C?
C?
C?
C?
C?lG?lG?lG?lG?lG?lG?lG?lG?lG?lG?lG?lG?lG?lG?K?K?K?K?K?K?K?K?K?K?K?K?K?K?K?K?{N?{N?{N?{N?{N?{N?{N?{N?{N?{N?NbP?NbP?NbP?NbP?NbP?NbP?NbP?NbP?NbP?S?S?S?S?S?S?S?S?S?S?S?S?S?S?EV?EV?EV?EV?EV?EV?EV?EV?EV?XY?XY?XY?XY?XY?XY?XY?XY?XY?XY?XY?XY?HZ?HZ?HZ?HZ?HZ?HZ?\?\?\?\?\?\?\?\?^?^?^?^?^?^?^?^?a?a?a?a?a?a?a?a?a?a?a?Jb?c?c?c?c?c?c?d?d?d?d?fff?fff?fff?fff?fff?fff?fff?rh?rh?rh?rh?rh?rh?rh?rh?L7i?L7i?L7i?~j?~j?~j?~j?~j?k?k?k?k?hm?hm?hm?hm?hm?hm?hm?hm?{n?{n?o?o?o?o?o?o?Nbp?Nbp?Nbp?q?q?q?q?q?r?r?r?r?r?Fs?Fs?Fs?jt?jt?jt?jt?}?u?}?u?Ev?Ev?Ev?Ev?=
w?=
w?=
w?Kw?Qx?Qx?Qx?Qx?ux?Xy?Xy?Xy?z?z?z?z?z?"{?"{?Zd{?m{?m{?(|?j|?|?|?p}?p}?-}?}??5~?~?~?~?|?|?w?  ?typescatternameMonte Carlo Exploring Startsx  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  @A  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  PA  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  `A  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  pA  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A   B   B   B   B   B   B   B   B   B   B   B   B   B   B   B   B   B   B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B   B   B   B   B   B   B  $B  $B  $B  $B  $B  $B  $B  $B  (B  (B  (B  (B  (B  (B  (B  (B  ,B  ,B  ,B  ,B  ,B  ,B  ,B  ,B  ,B  ,B  ,B  0B  4B  4B  4B  4B  4B  4B  8B  8B  8B  8B  <B  <B  <B  <B  <B  <B  <B  @B  @B  @B  @B  @B  @B  @B  @B  DB  DB  DB  HB  HB  HB  HB  HB  LB  LB  LB  LB  PB  PB  PB  PB  PB  PB  PB  PB  TB  TB  XB  XB  XB  XB  XB  XB  \B  \B  \B  `B  `B  `B  `B  `B  dB  dB  dB  dB  dB  hB  hB  hB  lB  lB  lB  lB  pB  pB  tB  tB  tB  tB  xB  xB  xB  |B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  ByD;D;D;;;;B`;u<u<u<u<u<u<u<u<㥛<㥛<㥛<㥛<1<1<j<j<<<<<<<<<+=+=P=P=P=P=j<=j<=j<=j<=j<=j<=j<=j<=j<=`P=`P=`P=`P=`P=Y=Y=q=q=q=q=q=q=+=+=+=+=+=+=+=)\=)\=)\=)\=P=P=P=P=-=-=-======{={={=E=E=E=E=j=j=j===\=9=9=9===="="="="="="=G=G=G=S=B`=============J>J>J>>>>+>+>O>O>O>O>O>O>Nb>Nb>Nb>t>t>t>+>+>+>>>>>>>R>R>w>!>!>/$>/$>/$>y&>y&>1,>1,>1,>1,>1,>/>/>/>E6>E6>E6>E6>E6>E6>E6>Q8>Q8>p=>p=>p=>p=>p=>7A>7A>7A>7A>C>C>ˡE>ˡE>^I>^I>^I>^I>K>K>`P>`P>`P>`P>`P>V>V>V>V>V>=
W>bX>Z>Z>"[>?5^>?5^>?5^>A`>A`>Sc>Sc>Sc>B`e>B`e>fff>rh>rh>Dl>Dl>Dl>Dl>n>n>q>q>q>Fs>Fs>x>x>x>x>x>m{>m{>m{>}>}>%>%>%>%>\>\>\>>>>>>$>$>>9>9>9>9>C>C>C>C>C>̌>̌>̌>sh>sh>sh>sh>sh>sh>sh>sh>sh>z>z>z>z>z>z>>>+>+>P>P>b>>>>">">">(>(>R>R>R>R>R>w>w>Ġ>Ġ>G>ʡ>Т>Т>
ף>
ף>B`>B`>B`>l>l>l>l>>>>>>~>>>V>V>V>{>{>>>>ף>ף>&>>33>33>33>j>j>j>}?>η>η>η>η>η>Q>X>X>Zd>Zd>Zd>Zd>>>>>>>>>>>J>J>J>o>o>>>$>$>$>$>>'1>'1>'1>L7>L7>q=>q=>C>C>I>I>>>>;>;>;>;>Nb>`>>>t>t>t>z>z>>>+>+>=
>P>u>u>>>>>>>>>/>?5>?5>d;>d;>A>A>>>>>>
>
>/>/>ff>ff>ff>l>l>>>>>>~>1>1>1>D>V>>>>&>&>&>&>&>>!>!>F>F>X9>j>}?>E>E>K>K>>>>5^>5^>5^>m>m>m>>>>>|>|>|>   ? ? ? ?G?G?7?M?M?M?S?S?S?S??
????/?ˡ?ˡ?ˡ?ff?ff?ff??y?l?l???r?r?9?L7	?L7	?	?	?	?q=
?C?C?C?C??I?I?I?O?O?O?O??????)\?)\?)\??;?Nb?Nb?&?&?&????!?!?!?F?F?F?F?X9?X9?j?j?}??}????E?E???=
?K?b?b?b?????????5^?H?H????j?j?j???????R?R?R??w?w?w?A ?A ?%!?%!?%!?7!?7!?!?M"?M"?\"?o#?o#?S#?#?
#?$?Z$?$?/$?%?B`%?ˡ%?T%?$&?ff&?y&?y&?l'?l'?'?'?'1(?9(?9(?(?L7)?x)?^)?)?q=*?*?*?C+?C+?+?1,?1,?D,?D,?V-?V-?h-?h-?{.?{.?V.?.?/?/?)\/?/?;/? 0?Nb0?`0?`0?&1?sh1?1?1?n2?n2?!2?333?333?t3?X94?X94?X94?z4?j4?}?5?}?5?5?5?+6?+6?+6?6?=
7?K7?7?7?b8?u8?u8?X9?X9?X9?#9?#9?:?:?:?";?";?m;?m;?m;?j<?j<?<?/=?/=?p=?=?=??5>?R>?R>?>?|??|??w??  @?@?@?@?GA?GA?7A?A?JB?\B?\B?B?oC?C?C?ZD?ZD?ZD?D?/D?B`E?B`E?ˡE?$F?$F?ffF?F?+G?+G?lG?G?G?'1H?9H?9H?L7I?L7I?xI?^I?I?q=J?~J?J?K?CK?K?K?IL?IL?L?L?OM?OM?hM?{N?{N?VN?N?O?O?O?O?;O? P?NbP?ףP?`P?shQ?shQ?Q?-R?-R?!R?!R?R?33S?FS?FS?S?zT?zT?jT?T?}?U?U?U?EV?EV?+V?V?=
W?KW?W?W?bX?QX?uX?X?Y?Y?Y?Z?Z?Z?Z?"[?"[?Zd[?m[?m[?j\?j\?\?\?p]?p]?-]??5^??5^?v^?R^?^?d;_?|_?w_?  `?A`?`?`?Ga?Ga?7a?a?Jb?Mb?\b?b?oc?c?c?d?d?Zd?d?ˡe?ˡe?ˡe?ˡe?Te?fff?fff?yf?yf?+g?g?g?g?'1h?rh?9h?L7i?L7i?xi?^i?q=j?q=j?~j?j?k?Ck?k?1l?1l?Il?Dl?l?Om?Om?hm?m?{n?Vn?n?n?o?)\o?o?;o? p?Nbp?ףp?`p?&q?shq?q?q?-r?nr?r?r?33s?ts?Fs?s?X9t?jt?jt?t?}?u?u?u?v?Ev?+v?v?=
w?Kw?Pw?w?bx?Qx?x?x?y?Xy?y?#y?z?5^z?z?Hz?"{?Zd{?{?m{?(|?j|?|?|?/}?p}?-}?}??5~?v~?R~?~?d;?|?w?  ?typescatternameRandom Policyx  0A  0A  0A  PA  PA  PA  `A  pA  pA  pA  pA  pA  pA  pA  pA  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A   B   B   B   B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B   B   B   B  $B  $B  (B  ,B  ,B  ,B  ,B  ,B  ,B  0B  0B  0B  4B  8B  <B  <B  <B  <B  <B  <B  <B  <B  @B  DB  DB  DB  HB  HB  HB  LB  LB  LB  PB  PB  TB  TB  TB  TB  TB  TB  \B  \B  \B  `B  `B  `B  dB  dB  dB  hB  hB  hB  hB  hB  hB  lB  lB  pB  tB  tB  xB  xB  xB  |B  |B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B   C   C  C  C  C  C  C  C  C  C  C  C  C  C  C  	C  
C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C   C   C  !C  !C  "C  #C  #C  $C  $C  $C  $C  %C  &C  'C  'C  )C  )C  )C  *C  *C  +C  +C  ,C  ,C  -C  .C  0C  0C  1C  3C  3C  4C  5C  5C  5C  5C  6C  7C  7C  8C  8C  9C  9C  :C  ;C  ;C  ;C  ;C  <C  <C  =C  =C  >C  >C  >C  ?C  ?C  @C  @C  @C  AC  AC  BC  CC  CC  CC  DC  FC  GC  GC  GC  HC  HC  HC  HC  HC  IC  JC  JC  KC  KC  LC  MC  OC  PC  PC  QC  QC  RC  UC  UC  VC  VC  VC  XC  XC  XC  YC  YC  ZC  ZC  [C  [C  [C  \C  ]C  ]C  ^C  _C  _C  `C  aC  aC  aC  bC  bC  bC  bC  cC  eC  fC  iC  iC  jC  kC  kC  kC  lC  lC  lC  mC  oC  pC  pC  qC  sC  tC  tC  vC  wC  wC  xC  xC  xC  zC  |C  |C  |C  |C  }C  ~C  ~C  ~C  C  C  C  C  C  C C C C  C  C  C C  C C C  C  C  C C C  C C C C  C  C  C  C C C  C  C  C  C  C C  C  C C C  C C  C  C  C C C C C C C  C  C C  C  C C C C  C  C  C C C  C  C  C  C C C C  C  C  C  C C C  C  C  C C C  C C C  C C C  C C  C C  C  C C C  C C  C C  C  C  C C C  C  C C  C  C C  C C  C C C C C  C  C C  C  C C C C C C C  C  C C  C C C  C C  C  C C  C  C  C  C C  C C C C  C  C C  C  C  C  C C  C  C C C  C  C  C C  C  C C C C  C  C C C C C C  C  C  C  C  C C C C C C  C  C  C  C C C  C C C  C C C  C C  C  C  C C C  C C  C C C C  C C C  C  C  C C  C C C  C C C  C  C C C  C  C C  C  C  C  C  C C  C C C  C C C  C  C C  C  C C C C C  C C C  C C  C  C  C  C C C  C C  C  C  C C  C  C  C  C C  C C C  C  C  C  C C  C  D @D D D D D D D @D @D D @D  D D @	D  
D  
D 
D 
D  D  D @D @D D @D @D D D  D @D D D D @D @D D D D D  D @D D @D D  D @D @D D D D @D @D D @D  D  D D D @D D D D D D  D  !D  !D @!D @!D @#D  %D  %D  %D %D %D (D  )D  )D )D  +D +D +D +D  -D  .D .D /D  1D  1D 2D @4D  5D 5D 5D  6D @6D 6D :D ;D <D  =D =D ?D @AD BD @DD DD ED @GD  HD @HD  KD @KD KD  ND  ND ND @OD @PD  RD  UD  VD  VD WD  XD @XD  YD YD ZD [D  \D ^D ^D @_D bD @cD @fD lD lD oD sD  tD @xD xD  {D @{D D D D D  D D  D `D D D `D  D `D D @D  D D  D D D D5c6e0de0c-3901-11f0-234e-bd09c571f662/10b6971fa80c859dlayoutautosize¥xaxistickvals  ?   AtitletextDealer showingticktextA10templatelayout coloraxiscolorbarticksoutlinewidth    xaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhitehovermodeclosestpaper_bgcolorwhitegeoshowlakesèshowlandélandcolor#E5ECF6bgcolorwhitesubunitcolorwhitelakecolorwhitecolorscalesequential    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921diverging    #8e0152=ͧ#c51b7d>Lͧ#de77ae>#f1b6da>ͧ#fde0ef?   #f7f7f7?#e6f5d0?333#b8e186?Lͧ#7fbc41?fff#4d9221?  #276419sequentialminus    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921yaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhiteshapedefaultslinecolor#2a3f5fhoverlabelalignleftmapboxstylelightpolarangularaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6radialaxisgridcolorwhitetickslinecolorwhiteautotypenumbersstrictfontcolor#2a3f5fternaryaaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6caxisgridcolorwhitetickslinecolorwhitebaxisgridcolorwhitetickslinecolorwhiteannotationdefaultsarrowhead    arrowwidth?  arrowcolor#2a3f5fplot_bgcolor#E5ECF6titlex=Lͥscenexaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitezaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhiteyaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitecolorway#636efa#EF553B#00cc96#ab63fa#FFA15A#19d3f3#FF6692#B6E880#FF97FF#FECB52data scatterpolargltypescatterpolarglmarkercolorbarticksoutlinewidth    carpetbaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitetypecarpetaaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitescatterpolartypescatterpolarmarkercolorbarticksoutlinewidth    parcoordslinecolorbarticksoutlinewidth    typeparcoordsscattertypescattermarkercolorbarticksoutlinewidth    histogram2dcontourcolorbarticksoutlinewidth    typehistogram2dcontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcolorbarticksoutlinewidth    typecontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattercarpettypescattercarpetmarkercolorbarticksoutlinewidth    mesh3dcolorbarticksoutlinewidth    typemesh3dsurfacecolorbarticksoutlinewidth    typesurfacecolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattermapboxtypescattermapboxmarkercolorbarticksoutlinewidth    scattergeotypescattergeomarkercolorbarticksoutlinewidth    histogramtypehistogrammarkercolorbarticksoutlinewidth    pietypepieautomarginêchoroplethcolorbarticksoutlinewidth    typechoroplethheatmapglcolorbarticksoutlinewidth    typeheatmapglcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921bartypebarerror_ycolor#2a3f5ferror_xcolor#2a3f5fmarkerlinecolor#E5ECF6width?   heatmapcolorbarticksoutlinewidth    typeheatmapcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcarpetcolorbarticksoutlinewidth    typecontourcarpettabletypetableheaderlinecolorwhitefillcolor#C8D4E3cellslinecolorwhitefillcolor#EBF0F8scatter3dlinecolorbarticksoutlinewidth    typescatter3dmarkercolorbarticksoutlinewidth    barpolartypebarpolarmarkerlinecolor#E5ECF6width?   scattergltypescatterglmarkercolorbarticksoutlinewidth    histogram2dcolorbarticksoutlinewidth    typehistogram2dcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scatterternarytypescatterternarymarkercolorbarticksoutlinewidth    heightC  marginl    b    r    tBp  titleyaxistickvals  @A  AtitletextPlayer sumticktext  @A  AwidthC  configshowLink¨editableªresponsiveêstaticPlotªscrollZoomæframesdatazmax?  y(  @A  PA  `A  pA  A  A  A  A  A  AtypeheatmapcolorscaleBlueredzminʿ  z(<.#oq (8gĭ1D'>9>(bM?M$xDH۽Uf>;>'?=f?(oRTTIF4>@e>)?|g?(U%00b>-^8mP> >+?g?(m" 'ںJq>>.?h?(+juG>=v>?}G4?d*k?(IY롾˹JԾC|k>j"?$G?˳o?(n5о^A{>Y?M?p?(	Oؾ_(j3>C?Or?(:ݾ꾠k ־L_'<>kT?transposeéshowscaleáx(  ?   @  @@  @  @  @  @   A  A   A5c6e0de0c-3901-11f0-234e-bd09c571f662/8998d22fe9cbcd7dlayoutxaxistypelogtitletextEpisodestemplatelayout coloraxiscolorbarticksoutlinewidth    xaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhitehovermodeclosestpaper_bgcolorwhitegeoshowlakesèshowlandélandcolor#E5ECF6bgcolorwhitesubunitcolorwhitelakecolorwhitecolorscalesequential    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921diverging    #8e0152=ͧ#c51b7d>Lͧ#de77ae>#f1b6da>ͧ#fde0ef?   #f7f7f7?#e6f5d0?333#b8e186?Lͧ#7fbc41?fff#4d9221?  #276419sequentialminus    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921yaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhiteshapedefaultslinecolor#2a3f5fhoverlabelalignleftmapboxstylelightpolarangularaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6radialaxisgridcolorwhitetickslinecolorwhiteautotypenumbersstrictfontcolor#2a3f5fternaryaaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6caxisgridcolorwhitetickslinecolorwhitebaxisgridcolorwhitetickslinecolorwhiteannotationdefaultsarrowhead    arrowwidth?  arrowcolor#2a3f5fplot_bgcolor#E5ECF6titlex=Lͥscenexaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitezaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhiteyaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitecolorway#636efa#EF553B#00cc96#ab63fa#FFA15A#19d3f3#FF6692#B6E880#FF97FF#FECB52data scatterpolargltypescatterpolarglmarkercolorbarticksoutlinewidth    carpetbaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitetypecarpetaaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitescatterpolartypescatterpolarmarkercolorbarticksoutlinewidth    parcoordslinecolorbarticksoutlinewidth    typeparcoordsscattertypescattermarkercolorbarticksoutlinewidth    histogram2dcontourcolorbarticksoutlinewidth    typehistogram2dcontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcolorbarticksoutlinewidth    typecontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattercarpettypescattercarpetmarkercolorbarticksoutlinewidth    mesh3dcolorbarticksoutlinewidth    typemesh3dsurfacecolorbarticksoutlinewidth    typesurfacecolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattermapboxtypescattermapboxmarkercolorbarticksoutlinewidth    scattergeotypescattergeomarkercolorbarticksoutlinewidth    histogramtypehistogrammarkercolorbarticksoutlinewidth    pietypepieautomarginêchoroplethcolorbarticksoutlinewidth    typechoroplethheatmapglcolorbarticksoutlinewidth    typeheatmapglcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921bartypebarerror_ycolor#2a3f5ferror_xcolor#2a3f5fmarkerlinecolor#E5ECF6width?   heatmapcolorbarticksoutlinewidth    typeheatmapcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcarpetcolorbarticksoutlinewidth    typecontourcarpettabletypetableheaderlinecolorwhitefillcolor#C8D4E3cellslinecolorwhitefillcolor#EBF0F8scatter3dlinecolorbarticksoutlinewidth    typescatter3dmarkercolorbarticksoutlinewidth    barpolartypebarpolarmarkerlinecolor#E5ECF6width?   scattergltypescatterglmarkercolorbarticksoutlinewidth    histogram2dcolorbarticksoutlinewidth    typehistogram2dcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scatterternarytypescatterternarymarkercolorbarticksoutlinewidth    legendyʾLͫorientationhmarginlBH  bBH  rBH  tBp  yaxisrange̽  @titletext/Mean square error <br> (average over 1000 runs)titleInitial Value = 1.0configshowLink¨editableªresponsiveêstaticPlotªscrollZoomæframesdatay=|A+U@~D@ @?}s??*??%u?
j?qP?C?+9?Y+?G$?)??E? ?!>I>z>>	5>>Nʽ>5>C>=q>xܡ>6>Q>>?>ʐ>O>>>>φ>?>^ex>[p>j>g>yd>}_>cx[>V>Q>J>J>G>(E>M*A>.<>h7>4>.>z(>m&>(>$>-#>
9"> >0>r{>[>-A>W>8>2>Qz>	>>>>+>y >0==y===si=$=Ҷ=1=i3=====>D='=W==m=e=typescatternameOrdinary importance samplingx  ?   @  @@  @  @  @  @   A  A   A  0A  @A  PA  `A  pA  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A   B  B  B  B  B  B  B  B   B  $B  (B  ,B  0B  4B  8B  <B  @B  DB  HB  LB  PB  TB  XB  \B  `B  dB  hB  lB  pB  tB  xB  |B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  By/?o??????v?f? W?L??B?v8?+-?$?	?5?
??>G>>5>)>>>>ʍ>R>N0>:>->}>>k7>4|>Zr>h>a>sm\>X>Q>a{K>rH>+E>ZB>jW=>/?;>n5>?5>fi2>3>K2>F/>*>W*>m&>s!>#] >s@>K>I>>>7>>Z>w>>[>2>;>">5 >P$==g=R==^4=[=N#=t=H=ؽ=;=ZE=0=h#=1==l=W=&='=~== d=+==g=typescatternameWeighted importance samplingx  ?   @  @@  @  @  @  @   A  A   A  0A  @A  PA  `A  pA  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A  A   B  B  B  B  B  B  B  B   B  $B  (B  ,B  0B  4B  8B  <B  @B  DB  HB  LB  PB  TB  XB  \B  `B  dB  hB  lB  pB  tB  xB  |B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B5c6e0de0c-3901-11f0-234e-bd09c571f662/cc789608a7b2df16layoutautosize¥xaxistickvals  ?   AtitletextticktextA10templatelayout coloraxiscolorbarticksoutlinewidth    xaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhitehovermodeclosestpaper_bgcolorwhitegeoshowlakesèshowlandélandcolor#E5ECF6bgcolorwhitesubunitcolorwhitelakecolorwhitecolorscalesequential    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921diverging    #8e0152=ͧ#c51b7d>Lͧ#de77ae>#f1b6da>ͧ#fde0ef?   #f7f7f7?#e6f5d0?333#b8e186?Lͧ#7fbc41?fff#4d9221?  #276419sequentialminus    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921yaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhiteshapedefaultslinecolor#2a3f5fhoverlabelalignleftmapboxstylelightpolarangularaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6radialaxisgridcolorwhitetickslinecolorwhiteautotypenumbersstrictfontcolor#2a3f5fternaryaaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6caxisgridcolorwhitetickslinecolorwhitebaxisgridcolorwhitetickslinecolorwhiteannotationdefaultsarrowhead    arrowwidth?  arrowcolor#2a3f5fplot_bgcolor#E5ECF6titlex=Lͥscenexaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitezaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhiteyaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitecolorway#636efa#EF553B#00cc96#ab63fa#FFA15A#19d3f3#FF6692#B6E880#FF97FF#FECB52data scatterpolargltypescatterpolarglmarkercolorbarticksoutlinewidth    carpetbaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitetypecarpetaaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitescatterpolartypescatterpolarmarkercolorbarticksoutlinewidth    parcoordslinecolorbarticksoutlinewidth    typeparcoordsscattertypescattermarkercolorbarticksoutlinewidth    histogram2dcontourcolorbarticksoutlinewidth    typehistogram2dcontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcolorbarticksoutlinewidth    typecontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattercarpettypescattercarpetmarkercolorbarticksoutlinewidth    mesh3dcolorbarticksoutlinewidth    typemesh3dsurfacecolorbarticksoutlinewidth    typesurfacecolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattermapboxtypescattermapboxmarkercolorbarticksoutlinewidth    scattergeotypescattergeomarkercolorbarticksoutlinewidth    histogramtypehistogrammarkercolorbarticksoutlinewidth    pietypepieautomarginêchoroplethcolorbarticksoutlinewidth    typechoroplethheatmapglcolorbarticksoutlinewidth    typeheatmapglcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921bartypebarerror_ycolor#2a3f5ferror_xcolor#2a3f5fmarkerlinecolor#E5ECF6width?   heatmapcolorbarticksoutlinewidth    typeheatmapcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcarpetcolorbarticksoutlinewidth    typecontourcarpettabletypetableheaderlinecolorwhitefillcolor#C8D4E3cellslinecolorwhitefillcolor#EBF0F8scatter3dlinecolorbarticksoutlinewidth    typescatter3dmarkercolorbarticksoutlinewidth    barpolartypebarpolarmarkerlinecolor#E5ECF6width?   scattergltypescatterglmarkercolorbarticksoutlinewidth    histogram2dcolorbarticksoutlinewidth    typehistogram2dcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scatterternarytypescatterternarymarkercolorbarticksoutlinewidth    heightC  marginl    b    r    tBp  titleAfter 500,000 episodesyaxistickvals  @A  AtitletextPlayer sumticktext  @A  AwidthC  configshowLink¨editableªresponsiveêstaticPlotªscrollZoomæframesdatazmax?  y(  @A  PA  `A  pA  A  A  A  A  A  AtypeheatmapcolorscaleBlueredzminʿ  z(>9 f"Vo S¶c.>	?(rdB_Ѿ!оo龛g$?V[s?(0%鶾bw־쾼8&?fs?(,N;@Ŝj>þgپ%?{r?(ha_Z8rb2ƾվcԾ*?#t?(lqGiwuVv蝾 'eо=ݾ+J7?v?(iVbI"/).y	|۾fϾ_C?x?(NHV~3Z@
ƾL۾$I?w?(x_]w\u@K
̽Ͼ׾@?T`y?(|RFƾo׾ZO㾙K>^?transposeéshowscaleáx(  ?   @  @@  @  @  @  @   A  A   A5c6e0de0c-3901-11f0-234e-bd09c571f662/985b842d3ecfdc58layoutautosize¥xaxistickvals  ?   AtitletextDealer showingticktextA10templatelayout coloraxiscolorbarticksoutlinewidth    xaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhitehovermodeclosestpaper_bgcolorwhitegeoshowlakesèshowlandélandcolor#E5ECF6bgcolorwhitesubunitcolorwhitelakecolorwhitecolorscalesequential    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921diverging    #8e0152=ͧ#c51b7d>Lͧ#de77ae>#f1b6da>ͧ#fde0ef?   #f7f7f7?#e6f5d0?333#b8e186?Lͧ#7fbc41?fff#4d9221?  #276419sequentialminus    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921yaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhiteshapedefaultslinecolor#2a3f5fhoverlabelalignleftmapboxstylelightpolarangularaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6radialaxisgridcolorwhitetickslinecolorwhiteautotypenumbersstrictfontcolor#2a3f5fternaryaaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6caxisgridcolorwhitetickslinecolorwhitebaxisgridcolorwhitetickslinecolorwhiteannotationdefaultsarrowhead    arrowwidth?  arrowcolor#2a3f5fplot_bgcolor#E5ECF6titlex=Lͥscenexaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitezaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhiteyaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitecolorway#636efa#EF553B#00cc96#ab63fa#FFA15A#19d3f3#FF6692#B6E880#FF97FF#FECB52data scatterpolargltypescatterpolarglmarkercolorbarticksoutlinewidth    carpetbaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitetypecarpetaaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitescatterpolartypescatterpolarmarkercolorbarticksoutlinewidth    parcoordslinecolorbarticksoutlinewidth    typeparcoordsscattertypescattermarkercolorbarticksoutlinewidth    histogram2dcontourcolorbarticksoutlinewidth    typehistogram2dcontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcolorbarticksoutlinewidth    typecontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattercarpettypescattercarpetmarkercolorbarticksoutlinewidth    mesh3dcolorbarticksoutlinewidth    typemesh3dsurfacecolorbarticksoutlinewidth    typesurfacecolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattermapboxtypescattermapboxmarkercolorbarticksoutlinewidth    scattergeotypescattergeomarkercolorbarticksoutlinewidth    histogramtypehistogrammarkercolorbarticksoutlinewidth    pietypepieautomarginêchoroplethcolorbarticksoutlinewidth    typechoroplethheatmapglcolorbarticksoutlinewidth    typeheatmapglcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921bartypebarerror_ycolor#2a3f5ferror_xcolor#2a3f5fmarkerlinecolor#E5ECF6width?   heatmapcolorbarticksoutlinewidth    typeheatmapcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcarpetcolorbarticksoutlinewidth    typecontourcarpettabletypetableheaderlinecolorwhitefillcolor#C8D4E3cellslinecolorwhitefillcolor#EBF0F8scatter3dlinecolorbarticksoutlinewidth    typescatter3dmarkercolorbarticksoutlinewidth    barpolartypebarpolarmarkerlinecolor#E5ECF6width?   scattergltypescatterglmarkercolorbarticksoutlinewidth    histogram2dcolorbarticksoutlinewidth    typehistogram2dcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scatterternarytypescatterternarymarkercolorbarticksoutlinewidth    heightC  marginl    b    r    tBp  titleyaxistickvals  @A  Atitletextticktext  @A  AwidthC  configshowLink¨editableªresponsiveêstaticPlotªscrollZoomæframesdatazmax?  y(  @A  PA  `A  pA  A  A  A  A  A  AtypeheatmapcolorscaleBlueredzminʿ  z(122!:H&P:G6T;>
>(  67  4X!;-  J%?1?Z?(8 &##f3(!u4GÞ0?Bl?(հݾ_7"7fI9p@/E>:?1k?(f:$, n7v>PS{g#?sT`?(ӰݾV?Gm;N'(!*a"=?Nl?(⾊Y& @'C0 .  : :?^h?(>6`'-b)Z)B  >md?ٶm?(ܾ$I"=i>?[o?(ىJ%9'*$9{W8?q\?transposeéshowscale¡x(  ?   @  @@  @  @  @  @   A  A   A4c6e0de0c-3901-11f0-234e-bd09c571f662/369509f17cc5b5alayoutautosize¥xaxistickvals  ?   AtitletextDealer showingticktextA10templatelayout coloraxiscolorbarticksoutlinewidth    xaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhitehovermodeclosestpaper_bgcolorwhitegeoshowlakesèshowlandélandcolor#E5ECF6bgcolorwhitesubunitcolorwhitelakecolorwhitecolorscalesequential    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921diverging    #8e0152=ͧ#c51b7d>Lͧ#de77ae>#f1b6da>ͧ#fde0ef?   #f7f7f7?#e6f5d0?333#b8e186?Lͧ#7fbc41?fff#4d9221?  #276419sequentialminus    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921yaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhiteshapedefaultslinecolor#2a3f5fhoverlabelalignleftmapboxstylelightpolarangularaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6radialaxisgridcolorwhitetickslinecolorwhiteautotypenumbersstrictfontcolor#2a3f5fternaryaaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6caxisgridcolorwhitetickslinecolorwhitebaxisgridcolorwhitetickslinecolorwhiteannotationdefaultsarrowhead    arrowwidth?  arrowcolor#2a3f5fplot_bgcolor#E5ECF6titlex=Lͥscenexaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitezaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhiteyaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitecolorway#636efa#EF553B#00cc96#ab63fa#FFA15A#19d3f3#FF6692#B6E880#FF97FF#FECB52data scatterpolargltypescatterpolarglmarkercolorbarticksoutlinewidth    carpetbaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitetypecarpetaaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitescatterpolartypescatterpolarmarkercolorbarticksoutlinewidth    parcoordslinecolorbarticksoutlinewidth    typeparcoordsscattertypescattermarkercolorbarticksoutlinewidth    histogram2dcontourcolorbarticksoutlinewidth    typehistogram2dcontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcolorbarticksoutlinewidth    typecontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattercarpettypescattercarpetmarkercolorbarticksoutlinewidth    mesh3dcolorbarticksoutlinewidth    typemesh3dsurfacecolorbarticksoutlinewidth    typesurfacecolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattermapboxtypescattermapboxmarkercolorbarticksoutlinewidth    scattergeotypescattergeomarkercolorbarticksoutlinewidth    histogramtypehistogrammarkercolorbarticksoutlinewidth    pietypepieautomarginêchoroplethcolorbarticksoutlinewidth    typechoroplethheatmapglcolorbarticksoutlinewidth    typeheatmapglcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921bartypebarerror_ycolor#2a3f5ferror_xcolor#2a3f5fmarkerlinecolor#E5ECF6width?   heatmapcolorbarticksoutlinewidth    typeheatmapcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcarpetcolorbarticksoutlinewidth    typecontourcarpettabletypetableheaderlinecolorwhitefillcolor#C8D4E3cellslinecolorwhitefillcolor#EBF0F8scatter3dlinecolorbarticksoutlinewidth    typescatter3dmarkercolorbarticksoutlinewidth    barpolartypebarpolarmarkerlinecolor#E5ECF6width?   scattergltypescatterglmarkercolorbarticksoutlinewidth    histogram2dcolorbarticksoutlinewidth    typehistogram2dcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scatterternarytypescatterternarymarkercolorbarticksoutlinewidth    heightC  marginl    b    r    tBp  titleyaxistickvals  @A  AtitletextPlayer sumticktext  @A  AwidthC  configshowLink¨editableªresponsiveêstaticPlotªscrollZoomæframesdatazmax?  y(  @A  PA  `A  pA  A  A  A  A  A  AtypeheatmapcolorscaleBlueredzminʿ  z(i!(c/'3ƾ\Tk='>(bájο8f=ء>?K?(D"<sxE=>$Q?K?(`0Vy;E[$jxݽM>i>?J?(6(O<R@DA0> >kj?NK?(T'&l'M)3**8Nt>Դ>,A ?KM?(VOI痱}о6߾PE>??0?S?(2īM䱾L~ƾ7+cv!=?h5?ÙT?(gܶԾ_jnQᾢDzx>i,?uX?((ZQɝLsﾷP>48?transposeéshowscaleáx(  ?   @  @@  @  @  @  @   A  A   A5c6e0de0c-3901-11f0-234e-bd09c571f662/70ef6091712c9d41layoutxaxistickvals(  ?   @  @@  @  @  @  @   A  A   AtitletextDealer showingticktextA@   @@  @  @  @  @  A   A  A   templatelayout coloraxiscolorbarticksoutlinewidth    xaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhitehovermodeclosestpaper_bgcolorwhitegeoshowlakesèshowlandélandcolor#E5ECF6bgcolorwhitesubunitcolorwhitelakecolorwhitecolorscalesequential    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921diverging    #8e0152=ͧ#c51b7d>Lͧ#de77ae>#f1b6da>ͧ#fde0ef?   #f7f7f7?#e6f5d0?333#b8e186?Lͧ#7fbc41?fff#4d9221?  #276419sequentialminus    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921yaxisgridcolorwhitezerolinewidth@   titlestandoffAp  tickszerolinecolorwhiteautomarginélinecolorwhiteshapedefaultslinecolor#2a3f5fhoverlabelalignleftmapboxstylelightpolarangularaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6radialaxisgridcolorwhitetickslinecolorwhiteautotypenumbersstrictfontcolor#2a3f5fternaryaaxisgridcolorwhitetickslinecolorwhitebgcolor#E5ECF6caxisgridcolorwhitetickslinecolorwhitebaxisgridcolorwhitetickslinecolorwhiteannotationdefaultsarrowhead    arrowwidth?  arrowcolor#2a3f5fplot_bgcolor#E5ECF6titlex=Lͥscenexaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitezaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhiteyaxisgridcolorwhitegridwidth@   backgroundcolor#E5ECF6ticksshowbackgroundízerolinecolorwhitelinecolorwhitecolorway#636efa#EF553B#00cc96#ab63fa#FFA15A#19d3f3#FF6692#B6E880#FF97FF#FECB52data scatterpolargltypescatterpolarglmarkercolorbarticksoutlinewidth    carpetbaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitetypecarpetaaxisgridcolorwhiteendlinecolor#2a3f5fminorgridcolorwhitestartlinecolor#2a3f5flinecolorwhitescatterpolartypescatterpolarmarkercolorbarticksoutlinewidth    parcoordslinecolorbarticksoutlinewidth    typeparcoordsscattertypescattermarkercolorbarticksoutlinewidth    histogram2dcontourcolorbarticksoutlinewidth    typehistogram2dcontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcolorbarticksoutlinewidth    typecontourcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattercarpettypescattercarpetmarkercolorbarticksoutlinewidth    mesh3dcolorbarticksoutlinewidth    typemesh3dsurfacecolorbarticksoutlinewidth    typesurfacecolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scattermapboxtypescattermapboxmarkercolorbarticksoutlinewidth    scattergeotypescattergeomarkercolorbarticksoutlinewidth    histogramtypehistogrammarkercolorbarticksoutlinewidth    pietypepieautomarginêchoroplethcolorbarticksoutlinewidth    typechoroplethheatmapglcolorbarticksoutlinewidth    typeheatmapglcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921bartypebarerror_ycolor#2a3f5ferror_xcolor#2a3f5fmarkerlinecolor#E5ECF6width?   heatmapcolorbarticksoutlinewidth    typeheatmapcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921contourcarpetcolorbarticksoutlinewidth    typecontourcarpettabletypetableheaderlinecolorwhitefillcolor#C8D4E3cellslinecolorwhitefillcolor#EBF0F8scatter3dlinecolorbarticksoutlinewidth    typescatter3dmarkercolorbarticksoutlinewidth    barpolartypebarpolarmarkerlinecolor#E5ECF6width?   scattergltypescatterglmarkercolorbarticksoutlinewidth    histogram2dcolorbarticksoutlinewidth    typehistogram2dcolorscale    #0d0887=9#46039f>c9#7201a8>#9c179e>9#bd3786?8#d8576b?*#ed7953?Gr#fb9f3a?c9#fdca26?  #f0f921scatterternarytypescatterternarymarkercolorbarticksoutlinewidth    heightC  marginl    b    rA   tA  yaxistickvals(  @A  PA  `A  pA  A  A  A  A  A  AtitletextPlayer sumticktext(  @A  PA  `A  pA  A  A  A  A  A  AwidthC  configshowLink¨editableªresponsiveêstaticPlotªscrollZoomæframesdatazmax?  y(  @A  PA  `A  pA  A  A  A  A  A  AtypeheatmapcolorscaleGreyszminʿ  z(fff?fff?fff?fff?fff?fff?ffffffffffff(fff?fff?fff?fff?fff?fff?ffffffffffff(fff?fff?fff?fff?fff?fff?ffffffffffff(fff?fff?fff?fff?fff?fff?ffffffffffff(fff?fff?fff?fff?fff?fff?ffffffffffff(fff?fff?fff?fff?fff?fff?ffffffffffff(fff?fff?fff?fff?fff?fff?ffffffffffff(fff?fff?fff?fff?fff?fff?ffffffffffff(fff?fff?fff?fff?fff?fff?ffffffffffff(fff?fff?fff?fff?fff?fff?fff?ffffffffftransposeéshowscale¡x(  ?   @  @@  @  @  @  @   A  A   Anbpkginstall_time_nsG:[instantiatedòinstalled_versionsStatisticsstdlibStatsBase0.33.21LinearAlgebrastdlibPlutoUI0.7.60HypertextLiteral0.9.5LaTeXStrings1.3.1PlutoPlotly0.4.6terminal_outputsStatistics@
[0m[1mResolving...[22m
[90m===[39m
[32m[1m  No Changes[22m[39m to `/tmp/jl_k1LQyO/Project.toml`
[32m[1m  No Changes[22m[39m to `/tmp/jl_k1LQyO/Manifest.toml`

[0m[1mInstantiating...[22m
[90m===[39m

[0m[1mPrecompiling...[22m
[90m===[39m
[32m[1m  Activating[22m[39m project at `/tmp/jl_k1LQyO`StatsBase@
[0m[1mResolving...[22m
[90m===[39m
[32m[1m  No Changes[22m[39m to `/tmp/jl_k1LQyO/Project.toml`
[32m[1m  No Changes[22m[39m to `/tmp/jl_k1LQyO/Manifest.toml`

[0m[1mInstantiating...[22m
[90m===[39m

[0m[1mPrecompiling...[22m
[90m===[39m
[32m[1m  Activating[22m[39m project at `/tmp/jl_k1LQyO`Base@
[0m[1mResolving...[22m
[90m===[39m
[32m[1m  No Changes[22m[39m to `/tmp/jl_k1LQyO/Project.toml`
[32m[1m  No Changes[22m[39m to `/tmp/jl_k1LQyO/Manifest.toml`

[0m[1mInstantiating...[22m
[90m===[39m

[0m[1mPrecompiling...[22m
[90m===[39m
[32m[1m  Activating[22m[39m project at `/tmp/jl_k1LQyO`nbpkg_sync@
[0m[1mResolving...[22m
[90m===[39m
[32m[1m  No Changes[22m[39m to `/tmp/jl_k1LQyO/Project.toml`
[32m[1m  No Changes[22m[39m to `/tmp/jl_k1LQyO/Manifest.toml`

[0m[1mInstantiating...[22m
[90m===[39m

[0m[1mPrecompiling...[22m
[90m===[39m
[32m[1m  Activating[22m[39m project at `/tmp/jl_k1LQyO`LinearAlgebra@
[0m[1mResolving...[22m
[90m===[39m
[32m[1m  No Changes[22m[39m to `/tmp/jl_k1LQyO/Project.toml`
[32m[1m  No Changes[22m[39m to `/tmp/jl_k1LQyO/Manifest.toml`

[0m[1mInstantiating...[22m
[90m===[39m

[0m[1mPrecompiling...[22m
[90m===[39m
[32m[1m  Activating[22m[39m project at `/tmp/jl_k1LQyO`PlutoUI@
[0m[1mResolving...[22m
[90m===[39m
[32m[1m  No Changes[22m[39m to `/tmp/jl_k1LQyO/Project.toml`
[32m[1m  No Changes[22m[39m to `/tmp/jl_k1LQyO/Manifest.toml`

[0m[1mInstantiating...[22m
[90m===[39m

[0m[1mPrecompiling...[22m
[90m===[39m
[32m[1m  Activating[22m[39m project at `/tmp/jl_k1LQyO`HypertextLiteral@
[0m[1mResolving...[22m
[90m===[39m
[32m[1m  No Changes[22m[39m to `/tmp/jl_k1LQyO/Project.toml`
[32m[1m  No Changes[22m[39m to `/tmp/jl_k1LQyO/Manifest.toml`

[0m[1mInstantiating...[22m
[90m===[39m

[0m[1mPrecompiling...[22m
[90m===[39m
[32m[1m  Activating[22m[39m project at `/tmp/jl_k1LQyO`PlutoPlotly@
[0m[1mResolving...[22m
[90m===[39m
[32m[1m  No Changes[22m[39m to `/tmp/jl_k1LQyO/Project.toml`
[32m[1m  No Changes[22m[39m to `/tmp/jl_k1LQyO/Manifest.toml`

[0m[1mInstantiating...[22m
[90m===[39m

[0m[1mPrecompiling...[22m
[90m===[39m
[32m[1m  Activating[22m[39m project at `/tmp/jl_k1LQyO`LaTeXStrings@
[0m[1mResolving...[22m
[90m===[39m
[32m[1m  No Changes[22m[39m to `/tmp/jl_k1LQyO/Project.toml`
[32m[1m  No Changes[22m[39m to `/tmp/jl_k1LQyO/Manifest.toml`

[0m[1mInstantiating...[22m
[90m===[39m

[0m[1mPrecompiling...[22m
[90m===[39m
[32m[1m  Activating[22m[39m project at `/tmp/jl_k1LQyO`enabled÷restart_recommended_msgrestart_required_msgbusy_packageswaiting_for_permission,waiting_for_permission_but_probably_disabled«cell_inputs $9fe42679-dce3-4ee3-b565-eed4ff7d8e4dcell_id$9fe42679-dce3-4ee3-b565-eed4ff7d8e4dcodemd"""
### Figure 5.2:

The optimal policy and state-value function for blackjack found by Monte Carlo ES.  The state value function shown was computed from the action-value function found by Monte Carlo ES
"""metadatashow_logsèdisabled®skip_as_script«code_folded$06960937-a87a-4015-bdeb-5d17aa41fe6bcell_id$06960937-a87a-4015-bdeb-5d17aa41fe6bcodefunction plot_blackjack_value(v)
	uagrid, nuagrid = make_value_grid(v)
	p1 = plot_value(uagrid, showscale=true, width = 400)
	p2 = plot_value(nuagrid, showscale=true, width = 400)
	
	(p1, p2)
endmetadatashow_logsèdisabled®skip_as_script«code_folded$abdcbbad-747a-41ba-a95d-82404e735793cell_id$abdcbbad-747a-41ba-a95d-82404e735793code;function make_ϵsoft_policy!(v::AbstractVector{T}, ϵ::T) where T <: Real
	vmax = maximum(v)
	v .= T.(isapprox.(v, vmax))
	s = sum(v)
	c = ϵ / length(v)
	d = one(T)/s - ϵ #value to add to actions that are maximizing
	for i in eachindex(v)
		if v[i] == 1
			v[i] = d + c
		else
			v[i] = c
		end
	end
	return v
endmetadatashow_logsèdisabled®skip_as_script«code_folded$846ccb44-a18b-4d87-bbf8-fc59eaf87708cell_id$846ccb44-a18b-4d87-bbf8-fc59eaf87708code`md"""
Number of Episodes: $(@bind opmc1 confirm(NumberField(1:10_000_000, default = 1_000)))
"""metadatashow_logsèdisabled®skip_as_script«code_folded$154edd83-350d-4acf-adfb-6a2d20599b53cell_id$154edd83-350d-4acf-adfb-6a2d20599b53codefunction showrace(track, π)
	@htl("""
		<div style = "display: flex;">
		$(rendertrack(track; episode = runrace(π; track = track)))
		$(rendertrack(track; episode = runrace(π; track = track)))
		</div>
	""")
endmetadatashow_logsèdisabled®skip_as_script«code_folded$ff9276eb-2151-4a6f-8257-8348047a9f4ecell_id$ff9276eb-2151-4a6f-8257-8348047a9f4ecodeيrace_episode2 = race_track_episode((position = rand(track2.start), velocity = (0, 0)), rand(racetrack_actions), π_racetrack_rand, track2)metadatashow_logsèdisabled®skip_as_script«code_folded$6f914006-1d8d-41f5-ae8a-fbe0b336946ccell_id$6f914006-1d8d-41f5-ae8a-fbe0b336946ccode[begin
	run3_2
	showrace(track2, create_policy_function(πstar3_racetrack2, track2_mdp))
endmetadatashow_logsèdisabled®skip_as_script«code_folded$4197cc28-b24c-48cb-bd8d-ef998983ad77cell_id$4197cc28-b24c-48cb-bd8d-ef998983ad77code'struct Ordinary <: ImportanceMethod endmetadatashow_logsèdisabled®skip_as_script«code_folded$e67d9deb-a074-48ba-84db-2e6938ea01f8cell_id$e67d9deb-a074-48ba-84db-2e6938ea01f8codeMfunction monte_carlo_pred_Q(π_target::Matrix{T}, π_behavior::Matrix{T}, mdp::MDP_Opaque{S, A, F, G}, γ::T; num_episodes::Integer = 1000, qinit::T = zero(T), Q::Matrix{T} = ones(T, length(mdp.actions), length(mdp.states)) .* qinit, historystateindex::Integer = 1, samplemethod::ImportanceMethod = Ordinary(), override_state_init::Bool = false, use_target_initial_action::Bool = false, sampleinds = 1:num_episodes) where {T <: AbstractFloat, S, A, F, G}
	
	check_policy(π_target, mdp)
	check_policy(π_behavior, mdp)
	@assert all(x -> x != 0, π_behavior) #behavior policy must have full coverage
	
	#initialize
	counts = zeros(T, length(mdp.actions), length(mdp.states))
	valuehistory = zeros(T, length(sampleinds))
	weighthistory = ones(T, length(sampleinds))
	sampleind = 1

	for i in 1:num_episodes
		#if only interested in one state then always initialize there
		s0 = override_state_init ? mdp.states[historystateindex] : mdp.state_init()
		π_init = use_target_initial_action ? π_target : π_behavior
		i_a0 = sample_action(π_init, mdp.statelookup[s0])
		a0 = mdp.actions[i_a0]
		# (s0, a0) = initialize_episode()
		(states, actions, rewards) = mdp.simulator(s0, a0, π_behavior)
	
		#update value function for each trajectory
		w = updateQ!(mdp, Q, counts, π_target, π_behavior, states, actions, rewards, γ, samplemethod)

		#for selected state check value
		if i == sampleinds[sampleind]
			valuehistory[sampleind] = sum(view(Q, :, historystateindex) .* view(π_target, :, historystateindex))
			weighthistory[sampleind] = w
			sampleind += 1
		end
	end
	return valuehistory, Q, weighthistory 
endmetadatashow_logsèdisabled®skip_as_script«code_folded$82a1f11e-b1b3-4c7d-ab9d-9f6136ae8195cell_id$82a1f11e-b1b3-4c7d-ab9d-9f6136ae8195code6const onestate_π_b = make_random_policy(onestate_mdp)metadatashow_logsèdisabled®skip_as_script«code_folded$11f8290f-f589-49ff-9602-99ccc4192884cell_id$11f8290f-f589-49ff-9602-99ccc4192884codeٕsampleracepolicy(create_policy_function(πstar1_racetrack2, track2_mdp); track = track2, trackname = "Track 2", policyname = "Off policy MC Control")metadatashow_logsèdisabled®skip_as_script«code_folded$7fb4244c-828a-49d6-a15b-178fa3a42e00cell_id$7fb4244c-828a-49d6-a15b-178fa3a42e00codev#policy defined in Example 5.1 which sticks on sums of 20 or 21
const π_blackjack1 = make_simple_blackjack_policy(20)metadatashow_logsèdisabled®skip_as_script«code_folded$0609ad22-0adc-4e4f-afed-b7a46d216576cell_id$0609ad22-0adc-4e4f-afed-b7a46d216576codeusampleracepolicy(create_policy_function(πstar2_racetrack1, track1_mdp); policyname = "Monte Carlo Exploring Starts")metadatashow_logsèdisabled®skip_as_script«code_folded$61eb74eb-88e0-42e6-a14b-3730a800694dcell_id$61eb74eb-88e0-42e6-a14b-3730a800694dcode8const onestate_π_target = reshape([1.0f0; 0.0f0], 2, 1)metadatashow_logsèdisabled®skip_as_script«code_folded$6a96304b-add3-4135-8ccf-46cc23859d53cell_id$6a96304b-add3-4135-8ccf-46cc23859d53code7md"""
#### Off-policy MC Control Racetrack Solution
"""metadatashow_logsèdisabled®skip_as_script«code_folded$c883748c-76b9-4086-8698-b40df51390dacell_id$c883748c-76b9-4086-8698-b40df51390dacodemd"""
> ### *Exercise 5.4* 
> The pseudocode for Monte Carlo ES is inefficient because, for each state-action pair, it maintains a list of all returns and repeatedly calculates their mean.  It would be more dfficient to use techniques similar to those explained in Section 2.4 to maintain just the mean and a count (for each state-action pair) and update them incrementally.  Describe how the pseudocode would be altered to achieve this.

Returns(s,a) will not maintain a list but instead be a list of single values for each state-action pair.  Additionally, another list Counts(s,a) should be initialized at 0 for each pair.  When new G values are obtained for state-action pairs, the Count(s,a) value should be incremented by 1.  Then Returns(s,a) can be updated with the following formula: 

$\text{Returns}(s,a) = \frac{\text{Returns}(s,a) \times (\text{Count}(s,a) - 1) + G(s,a)}{\text{Count}(s,a)} = \text{Returns}(s,a) + \frac{G(s,a) - \text{Returns}(s,a)}{\text{Count}(s,a)}$
"""metadatashow_logsèdisabled®skip_as_script«code_folded$f071b7e2-3f78-4132-8b84-f810f178c89dcell_id$f071b7e2-3f78-4132-8b84-f810f178c89dcodebegin 
	abstract type OneStateAction end
	struct Left <: OneStateAction end
	struct Right <: OneStateAction end
	struct OneState end

	const one_state_actions = [Left(), Right()]
	const one_state_action_lookup = Dict([Left() => 1, Right() => 2])
	
	one_state_step(::Right) = (0.0f0, true)
	one_state_step(::Left) = rand() <= 0.1 ? (1.0f0, true) : (0.0f0, false)

	

	function one_state_simulator(s0, a0::OneStateAction, π)
		state_history = [s0]
		action_history = Vector{OneStateAction}([a0])

		(r, term) = one_state_step(a0)
		reward_history = [r]
		
		while !term
			i_a = sample_action(π, 1)
			a = one_state_actions[i_a]
			push!(state_history, OneState())
			push!(action_history, a)
			(r, term) = one_state_step(a)
			push!(reward_history, r)
		end
		return (state_history, action_history, reward_history)	
	end
	const onestate_mdp = MDP_Opaque([OneState()], [Left(), Right()], () -> OneState(), one_state_simulator)
endmetadatashow_logsèdisabled®skip_as_script«code_folded$8d7b9826-b52c-4d5a-8c63-e83a1229a0becell_id$8d7b9826-b52c-4d5a-8c63-e83a1229a0becodecmd"""
Example trajectories after training for $(mcϵs2.episodes) episodes with ϵ= $(mcϵs2.ϵ)
"""metadatashow_logsèdisabled®skip_as_script«code_folded$67e535c7-437a-49ba-b5ab-9dfe63fe4aaacell_id$67e535c7-437a-49ba-b5ab-9dfe63fe4aaacode*md"""
#### Racetrack Environment Setup
"""metadatashow_logsèdisabled®skip_as_script«code_folded$c8f3f7e3-be7e-4615-a667-d9f789928883cell_id$c8f3f7e3-be7e-4615-a667-d9f789928883codeپ#updates the value estimates at a given state using the future discounted return and the importance-sampling ratio
updatevalue(::Ordinary, q::T, g::T, w::T, c::T) where T<:Real = (w*g - q)/cmetadatashow_logsèdisabled®skip_as_script«code_folded$30809344-b4ab-468b-b4b7-5ef3dca5ffc7cell_id$30809344-b4ab-468b-b4b7-5ef3dca5ffc7codemd"""
> ### *Exercise 5.2* 
> Suppose every-visit MC was used instead of first-visit MC on the blackjack task.  Would you expect the results to be very different?  Why or why not?

As an episode proceeds in blackjack the states will not repeat since every time a card is dealt the player sum changes, or the usable Ace flag changes.  Thus the check ensuring that only the first visit to a state is counted in the return average will have no effect on the MC evaluation.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$e2a720b0-a8c4-43a2-bf34-750ff3323004cell_id$e2a720b0-a8c4-43a2-bf34-750ff3323004codemd"""
## 5.4 Monte Carlo Control without Exploring Starts

To only way to ensure all state-action pairs are visited without exploring starts is to use a policy with a non-zero probability of visiting all such states.  One policy that meets this criterion is an *ϵ-soft* policy meaning that $\pi(a \vert s) > 0 \: \forall \: s \in \mathcal{S}$.  To achieve this with Monte Carlo Control, we simply update the policy to be $\epsilon$-greedy for every Q update, so the maximizing (greedy) action is given a probability $1 - \epsilon + \frac{\epsilon}{\vert \mathcal{A}(s) \vert}$ and all other actions are given the probability $\frac{\epsilon}{\vert \mathcal{A}(s) \vert}$.

Below is code implementing MC control for ϵ-soft policies.  It is mostly identical to the every visit method except the policy is always used to select the initial action and the policy update uses an ϵ-greedy update rather than a greedy one.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$1067fcc4-cbc6-453c-a996-d420c498619acell_id$1067fcc4-cbc6-453c-a996-d420c498619acodensampleracepolicy(create_policy_function(πstar1_racetrack1, track1_mdp); policyname = "Off policy MC Control")metadatashow_logsèdisabled®skip_as_script«code_folded$6496c993-6d47-4a6e-a497-2a2de172fbc3cell_id$6496c993-6d47-4a6e-a497-2a2de172fbc3codeYmd"""
### Off-policy Monte-Carlo Prediction Algorithm for Estimating $Q \approx q_π$
"""metadatashow_logsèdisabled®skip_as_script«code_folded$aa647f3e-a4b2-4825-bb2a-1c2469d2c0ebcell_id$aa647f3e-a4b2-4825-bb2a-1c2469d2c0ebcodeٜsampleracepolicy(create_policy_function(πstar2_racetrack2, track2_mdp); track = track2, trackname = "Track 2", policyname = "Monte Carlo Exploring Starts")metadatashow_logsèdisabled®skip_as_script«code_folded$1d3d509c-b11b-4c57-b100-9bcf0489af2bcell_id$1d3d509c-b11b-4c57-b100-9bcf0489af2bcodefunction create_greedy_policy(Q::Matrix{T}; c = 1000, π = copy(Q)) where T<:Real
	vhold = zeros(T, size(Q, 1))
	for j in 1:size(Q, 2)
		vhold .= Q[:, j]
		make_greedy_policy!(vhold; c = c)
		π[:, j] .= vhold
	end
	return π
endmetadatashow_logsèdisabled®skip_as_script«code_folded$989ccacd-b410-4967-bf6a-9244e3be785dcell_id$989ccacd-b410-4967-bf6a-9244e3be785dcode`md"""
Number of Episodes: $(@bind mces1 confirm(NumberField(1:10_000_000, default = 1_000)))
"""metadatashow_logsèdisabled®skip_as_script«code_folded$b352d98e-0854-45e3-ac73-8ef434525563cell_id$b352d98e-0854-45e3-ac73-8ef434525563codemd"""
##### Track 1
"""metadatashow_logsèdisabled®skip_as_script«code_folded$202eb066-877d-4537-85b2-31b41db8eca0cell_id$202eb066-877d-4537-85b2-31b41db8eca0codetinitialize_state_value(mdp::MDP_Opaque; vinit::T = 0.0f0) where T<:AbstractFloat = ones(length(mdp.states)) .* vinitmetadatashow_logsèdisabled®skip_as_script«code_folded$3955d71a-3105-445a-868d-66ba0b3dc515cell_id$3955d71a-3105-445a-868d-66ba0b3dc515codeيrace_episode1 = race_track_episode((position = rand(track1.start), velocity = (0, 0)), rand(racetrack_actions), π_racetrack_rand, track1)metadatashow_logsèdisabled®skip_as_script«code_folded$f406be9e-3e3f-4b55-99b0-4858c774ed96cell_id$f406be9e-3e3f-4b55-99b0-4858c774ed96code8md"""
## 5.2 Monte Carlo Estimation of Action Values
"""metadatashow_logsèdisabled®skip_as_script«code_folded$648bfc3f-0649-4401-a97f-89e21057f7b7cell_id$648bfc3f-0649-4401-a97f-89e21057f7b7codecmd"""
Example trajectories after training for $(mcϵs1.episodes) episodes with ϵ= $(mcϵs1.ϵ)
"""metadatashow_logsèdisabled®skip_as_script«code_folded$e10378eb-12b3-4468-9c22-1838107da450cell_id$e10378eb-12b3-4468-9c22-1838107da450code,md"""
### Example 5.5: Infinite Variance
"""metadatashow_logsèdisabled®skip_as_script«code_folded$2e57e4b5-d228-4ce3-b9d8-cf4375bb7c50cell_id$2e57e4b5-d228-4ce3-b9d8-cf4375bb7c50code%md"""
# Dependencies and Settings
"""metadatashow_logsèdisabled®skip_as_script«code_folded$edb4ad06-5e6e-48c4-9ee4-ae0b92927a91cell_id$edb4ad06-5e6e-48c4-9ee4-ae0b92927a91code@md"""
Example trajectories after $mces2 episodes of training
"""metadatashow_logsèdisabled®skip_as_script«code_folded$9df79a71-e58a-497b-bb02-debb69144925cell_id$9df79a71-e58a-497b-bb02-debb69144925code)const track1_mdp = make_track_mdp(track1)metadatashow_logsèdisabled®skip_as_script«code_folded$cebb79b7-c9d6-4b79-ba0e-b2f3c7587724cell_id$cebb79b7-c9d6-4b79-ba0e-b2f3c7587724codemd"""
> ### *Exercise 5.12: Racetrack (programming)*  
> Consider driving a race car around a turn like those shown in Figure 5.5.  You want to go as fast as possible, but not so fast as to run off the track.  In our simplified racetrack, the car is at one of a discrete set of grid positions, the cells in the diagram.  The velocity is also discrete, a number of grid cells moved horizontally and vertically per time step.  The actions are increments to the velocity components.  Each may be changed by +1, -1, or 0 in each step, for a total of nine (3x3) actions.  Both velocity components are restricted to be nonnegative and less than 5, and they cannot both be zero except at the starting line.  Each episode begins in one of the randomly selected start states with both velocity components zero and ends when the car crosses the finish line.  The rewards are -1 for each step until the car crosses the finish line.  If the car hits the track boundry, it is moved back to a random position on the starting line, both velocity components are reduced to zero, and the episode continues.  Before updating the car's location at each time step, check to see if the projected path of the car intersects the track boundary.  If it intersects the finish line, the episode ends; if it intersects anywhere else, the car is considered to have hit the track boundary and is sent back to the starting line.  To make the task more challenging, with probality 0.1 at each time step the velocity increments are both zero, independently of the intended increments.  Apply a Monte Carlo control method to this task to compute the optimal policy from each starting state.  Exhibit several trajectories following the optimal policy (but turn the noise off for these trajectories).
"""metadatashow_logsèdisabled®skip_as_script«code_folded$54f73eb8-dcea-4da0-83af-35720e56ccbccell_id$54f73eb8-dcea-4da0-83af-35720e56ccbccodebmonte_carlo_ϵsoft(mdp::MDP_Opaque, ϵ::T, γ::T, num_episodes; Q_init::Matrix{T} = initialize_state_action_value(mdp; qinit = zero(T)), π_init::Matrix{T} = make_random_policy(mdp; init = one(T)), quench_episode = num_episodes, decay_ϵ = false) where T <: Real = monte_carlo_ϵsoft(mdp, ϵ, π_init, Q_init, γ, num_episodes, quench_episode, decay_ϵ) metadatashow_logsèdisabled®skip_as_script«code_folded$418c045d-90c7-42d8-9126-90185f7e197bcell_id$418c045d-90c7-42d8-9126-90185f7e197bcode/figure_5_2(πstar_blackjack3, Qstar_blackjack3)metadatashow_logsèdisabled®skip_as_script«code_folded$6979db32-670d-466a-9a6e-97c2d8527f3dcell_id$6979db32-670d-466a-9a6e-97c2d8527f3dcodemd"""
> ### *Exercise 5.7* 
> In learning curves such as those shown in Figure 5.3 error generally decreases with training, as indeed happened for the ordinary importance-sampling method.  But for the weighted importance-sampling method error first increased and then decreased.  Why do you think this happened?

In figure 5.3, the true value is about -.277 and we initialized the value function at zero.  For any given episode it is likely that the observed return will be -1.0 or 1.0 for a win or a loss.  Weighted importance sampling won't update the state value for trajectories which cannot occur in the target policy, so for some of the runs at this early state the state value is unchanged at the 0 initial value.  It is only after a certain number of episodes have occured that all of the values will be updated and produce an estimate which is worse than the initial value.  Once many samples with non zero weight are collected for each run, then the estimate starts to approach the true value again.  If instead we initialized the state value far away from the true value, then you would not see the initial increase in estimate error.  See below for an example using an initial value of 1.  In this case, no update from weighted importance sampling would produce an error larger than the initial value.

$(figure5_3(;n = 1000, vinit = 1.0f0, episodes = 100, title = "Initial Value = 1.0", caption = "Blackjack State Estimate with Bad Initialization"))
"""metadatashow_logsèdisabled®skip_as_script«code_folded$cd928f87-2832-4595-8ce5-79b69cc56bd9cell_id$cd928f87-2832-4595-8ce5-79b69cc56bd9codeImd"""
#### Figure 5.5
A couple of right turns for the racetrack task.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$ba044e4f-e2a6-4f96-8756-5b24b1bb5ca2cell_id$ba044e4f-e2a6-4f96-8756-5b24b1bb5ca2codey#trajectory of a random episode, arrows indicate the velocity at each step
@htl("""
<div style = "display: flex; align-items: flex-end;">
$(rendertrack(track1; episode = race_episode1))
$(rendertrack(track2; episode = race_episode2))
</div>
""")
#using a random policy on track 1, the mean time to finish on track 1 is ~2800 steps.  The best possible time when we get "lucky" with random decisions is ~12 steps with worst times ~15-30k steps

#using a random policy on track 2, the mean time to finish on track 1 is ~300 steps.  The best possible time when we get "lucky" with random decisions is ~10 steps with worst times ~2k stepsmetadatashow_logsèdisabled®skip_as_script«code_folded$6d6e8916-9b36-4af1-b77d-86cb6a416f88cell_id$6d6e8916-9b36-4af1-b77d-86cb6a416f88codemd"""
##### Track 1
"""metadatashow_logsèdisabled®skip_as_script«code_folded$cede8090-5b1a-436b-a184-fca5c4d3de48cell_id$cede8090-5b1a-436b-a184-fca5c4d3de48codemd"""
> ### *Exercise 5.5* 
> Consider an MDP with a single nonterminal state and a single action that transitions back to the nonterminal state with probability $p$ and transitions to the terminal state with probability $1-p$.  Let the reward be +1 on all transitions, and let $\gamma=1$.  Suppose you observe one episode that lasts 10 steps, with a return of 10.  What are the first-visit and every-visit estimators of the value of the nonterminal state?

For the first-visit estimator, we only consider the single future reward from the starting state which would be 10.  There is nothing to average since we just have the single value of 10 for the episode.

For the every-visit estimator, we need to average together all 10 visits to the non-terminal state.  For the first visit, the future reward is 10.  For the second visit it is 9, third 8, and so forth.  The final visit has a reward of 1, so the value estimate is the average of 10, 9, ..., 1 which is $\frac{(1+10) \times 5}{10}=\frac{55}{10} = 5.5$
"""metadatashow_logsèdisabled®skip_as_script«code_folded$8668ffc3-6c8c-4c25-8d47-9977bef929d2cell_id$8668ffc3-6c8c-4c25-8d47-9977bef929d2code`md"""
Number of Episodes: $(@bind opmc2 confirm(NumberField(1:10_000_000, default = 1_000)))
"""metadatashow_logsèdisabled®skip_as_script«code_folded$5834c5e0-8a04-47ea-aab8-881c73d8fd4fcell_id$5834c5e0-8a04-47ea-aab8-881c73d8fd4fcodemd"""
##### Track 1
"""metadatashow_logsèdisabled®skip_as_script«code_folded$14536b70-35f0-46ba-93fc-3365a1e8c15ccell_id$14536b70-35f0-46ba-93fc-3365a1e8c15ccodemd"""
##### Results Summary
Off policy MC control training is slow because the random behavior policy takes a very long time to complete a race (~2500 or ~300 steps).  Even after 1000 episodes performance is indistinguishable from the random policy.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$39da4cf9-5265-41bc-83d4-311e86675db7cell_id$39da4cf9-5265-41bc-83d4-311e86675db7codem(πstar_blackjack3, Qstar_blackjack3) = off_policy_MC_control(blackjack_mdp, 1.0f0; num_episodes = 3_000_000)metadatashow_logsèdisabled®skip_as_script«code_folded$d97f693d-27f2-49be-a549-07a290c95b53cell_id$d97f693d-27f2-49be-a549-07a290c95b53code}#types allow dispatch for each sampling method based on different incremental update rules
abstract type ImportanceMethod endmetadatashow_logsèdisabled®skip_as_script«code_folded$f9bc84ff-c2f9-4ac2-b2ce-34dfcf837a73cell_id$f9bc84ff-c2f9-4ac2-b2ce-34dfcf837a73code-figure_5_2(πstar_blackjack, Qstar_blackjack)metadatashow_logsèdisabled®skip_as_script«code_folded$8f38a3e9-1872-4ea6-9a03-87112af4bf07cell_id$8f38a3e9-1872-4ea6-9a03-87112af4bf07code(#run n episodes of a race and measure the statistics of the time required to finish
function sampleracepolicy(π; n = 1000, trackname = "Track 1", policyname = "", kwargs...)
	trajs = [runrace(π; kwargs...)[1] for _ in 1:n]
	randomtrajs = [runrace(s -> rand(racetrack_actions); kwargs...)[1] for _ in 1:n]
	ls = filter(x -> x > 0, length.(trajs))
	randomls = filter(x -> x > 0, length.(randomtrajs))
	f1 = ecdf(ls)
	f2 = ecdf(randomls)
	t1 = scatter(x = f1.sorted_values, y = f1.(f1.sorted_values), name = "$policyname")
	t2 = scatter(x = f2.sorted_values, y = f2.(f2.sorted_values), name = "Random Policy")
	p = plot([t1, t2], Layout(xaxis_title = "Steps to Finish Race", yaxis_title = "Percent of Episodes", xaxis_type = "log"))
	# p1 = plot(histogram(x = ls, showlegend=false), Layout(title = "$policyname", xaxis_title = "Steps to Finish Race", yaxis_title = "Number of Episodes", showlegend = false))
	# p2 = plot(histogram(x = randomls, showlegend=false), Layout(title = "Random Policy", xaxis_title = "Steps to Finish Race", yaxis_title = "Number of Episodes", showlegend = false))

	isempty(randomls) && return md"""Policy Unable to Complete race within 10,000 steps"""

	parsestd(v) = isnan(std(v)) ? NaN : round(Int64, std(v))
	
	md"""
	$(Markdown.parse("Statistics for Steps to Finish Race on $trackname"))
	
	| Statistic | $(Markdown.parse(policyname)) | Random Policy |
	| --- | --- | --- |
	|Mean | $(round(Int64, mean(ls))) | $(round(Int64, mean(randomls))) |
	|Median | $(round(Int64, median(ls))) | $(round(Int64, median(randomls))) |
	|Std| $(parsestd(ls)) | $(parsestd(randomls)) |
	|Minimum| $(round(Int64, minimum(ls))) | $(round(Int64, minimum(randomls))) |
	|Maximum| $(round(Int64, maximum(ls))) | $(round(Int64, maximum(randomls))) |

	Cummulative Distribution Function of Steps to Finish Race
	$p
	"""
endmetadatashow_logsèdisabled®skip_as_script«code_folded$627d5aa3-974f-4949-8b65-9500eba1d7cccell_id$627d5aa3-974f-4949-8b65-9500eba1d7cccoded#recreation of figure 5.2
function figure_5_2(πstar_blackjack, Qstar_blackjack)
	policyplot = plot_blackjack_policy(πstar_blackjack)
	vstar = sum(Qstar_blackjack .* πstar_blackjack, dims = 1)[:]
	# vhit = Qstar_blackjack[1, :][:]
	# vstick = Qstar_blackjack[2, :][:]
	# vdiff = (vhit .- vstick)
	valueplot = plot_blackjack_value(vstar)
	# policyplot = plot_blackjack_value(vdiff)
	vtitle = md"""$v_*$"""
	ptitle = md"""$π_*$"""

	md"""
	| |$\pi_*$ (Black = Stick, White = Hit)|$v_*$|
	|---|:---:|:---:|
	|Usable ace|$(policyplot[1])|$(valueplot[1])|
	|No usable ace|$(policyplot[2])|$(valueplot[2])|
	"""
endmetadatashow_logsèdisabled®skip_as_script«code_folded$02dd1e77-2a7e-4123-94db-d17b31a8b15acell_id$02dd1e77-2a7e-4123-94db-d17b31a8b15acode4const blackjack_state1 = BlackjackState(13, 2, true)metadatashow_logsèdisabled®skip_as_script«code_folded$09b67730-39e7-4209-8117-6bc3adfb342acell_id$09b67730-39e7-4209-8117-6bc3adfb342acodeKmd"""
$\begin{flalign}
	&=0.1 \sum_{N=1}^\infty \left ( \frac{1}{2} \right ) ^N 0.9^{N-1} \left ( \frac{\sum_{i=1}^N 2^i}{N} \right ) ^2 \\
	&=\frac{0.1}{0.9} \sum_{N=1}^\infty 0.45^{N} N^{-2} \left ( \sum_{i=1}^N 2^i \right ) ^2 \\
\end{flalign}$

Consider the term: $\left ( \sum_{i=1}^N 2^i \right ) ^2 = (2 + 2^2 + 2^3 + \cdots + 2^N)^2 \gt 2^{2N}$ since all the other terms in the parentheses are positive.

$\begin{flalign}
	&\gt\frac{0.1}{0.9} \sum_{N=1}^\infty 0.45^{N} N^{-2} 2^{2N} \\
	&= \frac{0.1}{0.9} \sum_{N=1}^\infty 0.45^{N} N^{-2} 4^{N} \\
	&= \frac{0.1}{0.9} \sum_{N=1}^\infty \frac{1.8^{N}}{N^{2}} \\
\end{flalign}$

The question is then reduced to whether the following infinite sum diverges: $\sum_{N=1}^\infty \frac{1.8^{N}}{N^{2}}$.  Consider the logarithm of each term in the series $\log {\frac{1.8^N}{N^2}} = \log{1.8^N} - \log{N^2} = N \log{1.8} - 2 \log{N}$.  As N approaches infinity $N \gt \log{N}$ so the log of each term diverges as do the terms individually as does the series.  Therefore the variance diverges with ever-visit MC as it does with first visit MC.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$b7dfc031-6bf6-44cd-b814-05f693a0a27dcell_id$b7dfc031-6bf6-44cd-b814-05f693a0a27dcode<#ϵ-soft training also produces a policy that can finish the race but results heavily depend on the value of ϵ.  A small ϵ around 2% seems to produce the best results that exceed that of even the exploring starts algorithm
begin
	run3_1
	showrace(track1, create_policy_function(πstar3_racetrack1, track1_mdp))
endmetadatashow_logsèdisabled®skip_as_script«code_folded$2572e35c-e6a3-4562-aa0f-6a5ab32d39eacell_id$2572e35c-e6a3-4562-aa0f-6a5ab32d39eacode	@htl("""
<div style="display: flex; flex-direction: row; align-items: flex-start; justify-content: center; background-color: rgb(100, 100, 100)">
	
	<div class="backup">
		<div>State Value Function</div>
		<div class="circlestate"></div>
		<div class="arrow"></div>
		<div class="circleaction"></div>
		<div class="arrow"></div>
		<div class="circlestate"></div>
		<div class="arrow"></div>
		<div class="circleaction"></div>
		<div style = "color: black; font-size: 30px;">&#8942;</div>
		<div class="circleaction"></div>
		<div class="arrow"></div>
		<div class="term"></div>
	</div>
	<div class="backup">
		<div>State Action Value Function</div>
		<div class="circleaction"></div>
		<div class="arrow"></div>
		<div class="circlestate"></div>
		<div class="arrow"></div>
		<div class="circleaction"></div>
		<div class="arrow"></div>
		<div class="circlestate"></div>
		<div style = "color: black; font-size: 30px;">&#8942;</div>
		<div class="circlestate"></div>
		<div class="arrow"></div>
		<div class="circleaction"></div>
		<div class="arrow"></div>
		<div class="term"></div>
	</div>
	<div>
		<div class="q_backup"></div>
	</div>
</div>

<style>

	.backup {
		margin: 5px;
	}
	.backup, .backup * {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		color: black;
	}
	.circlestate, .circleaction {
		margin: 0;
	}
	.circlestate::before {
		content: '';
		display: inline-block;
		border: 1px solid black;
		border-radius: 50%;
		height: 20px;
		width: 20px;
		background-color: white;
	}
	.circleaction::before {
		content: '';
		display: inline-block;
		border: 1px solid black;
		border-radius: 50%;
		height: 10px;
		width: 10px;
		background-color: black;
	}
	.arrow {
		display: flex;
		justify-content: center;
		align-items: center;
	}
	.arrow::before {
		content: '';
		display: inline-block;
		width: 2px;
		height: 30px;
		background-color: black;
		margin-bottom: 0px;
	}
	.arrow::after {
		content: '';
		display: inline-block;
		width: 4px;
		height: 4px;
		border-bottom: 3px solid black;
		border-right: 3px solid black;
		transform: translateY(-5px) rotate(45deg);
		position: relative;
	}
	.term::before {
		content: '';
		display: inline-block;
		width: 20px;
		height: 20px;
		border: 2px solid black;
		background-color: rgb(50, 50, 50);
	}
</style>
""")metadatashow_logsèdisabled®skip_as_script«code_folded$859354fe-7f40-4658-bf12-b5ee20a815a7cell_id$859354fe-7f40-4658-bf12-b5ee20a815a7code6md"""
## 5.8 Discounting-aware Importance Sampling
"""metadatashow_logsèdisabled®skip_as_script«code_folded$f9f6c182-62f8-4a5a-8b43-8716db468427cell_id$f9f6c182-62f8-4a5a-8b43-8716db468427code)const maxspeed = maximum(racetrackspeeds)metadatashow_logsèdisabled®skip_as_script«code_folded$47daf83b-8fe9-4491-b9ae-84bd269d5546cell_id$47daf83b-8fe9-4491-b9ae-84bd269d5546code$md"""
## 5.3 Monte Carlo Control
"""metadatashow_logsèdisabled®skip_as_script«code_folded$ba8a5804-4be3-43fe-95d7-c957ce02a1d4cell_id$ba8a5804-4be3-43fe-95d7-c957ce02a1d4codefunction make_action_style(dvx, dvy)
	((dvx==0) && (dvy==0)) && return """"""
	"""
	[dvx='$dvx'][dvy='$dvy']::after {
		content: '→';
		color: red;
		transform: rotate($(atand(dvy, dvx))deg);
	}
	"""
endmetadatashow_logsèdisabled®skip_as_script«code_folded$481ad435-cc80-4164-882d-8310b010ca91cell_id$481ad435-cc80-4164-882d-8310b010ca91codeٶfunction make_simple_blackjack_policy(stick_sum::Integer)
	mapreduce(hcat, blackjackstates) do state
		state.sum < stick_sum && return [1.0f0, 0.0f0]
		return [0.0f0, 1.0f0]
	end
endmetadatashow_logsèdisabled®skip_as_script«code_folded$8bcaa31b-8caf-43da-83a0-47e0c04c2a30cell_id$8bcaa31b-8caf-43da-83a0-47e0c04c2a30code@htl("""
<div style="display: flex; justify-content: space-around;">
<div>Track 1</div>
<div>Track 2</div>
</div>
<div style="display: flex; justify-content: space-between; align-items: flex-end; background-color: gray;">
$(rendertrack(track1))
$(rendertrack(track2))
</div>
""")metadatashow_logsèdisabled®skip_as_script«code_folded$7c9486cd-1916-4e13-b415-fb113bd9e04bcell_id$7c9486cd-1916-4e13-b415-fb113bd9e04bcode/md"""
## 5.7 Off-policy Monte Carlo Control
"""metadatashow_logsèdisabled®skip_as_script«code_folded$821ce23a-524b-4203-96d6-4d5b454fe1fdcell_id$821ce23a-524b-4203-96d6-4d5b454fe1fdcodeٓsampleracepolicy(create_policy_function(πstar3_racetrack2, track2_mdp); track = track2, trackname = "Track 2", policyname = "Monte Carlo ϵ-Soft")metadatashow_logsèdisabled®skip_as_script«code_folded$dc57a71f-e44c-4385-ad2a-e6c14d5e5201cell_id$dc57a71f-e44c-4385-ad2a-e6c14d5e5201codemd"""
> ### *Exercise 5.14* 
> Modify the algorithm for off-policy Monte Carlo control (page 111) to use the idea of the truncated weighted-average estimator (5.10).  Note that you will first need to convert this equation to action values.

Equation (5.10)

$V(s) = \frac{\sum_{t \in \mathscr{T}(s)}\left((1-\gamma)\sum_{h=t+1}^{T(t)-1}\gamma^{h-t-1} \rho_{t:h-1} \bar{G}_{t:h} + \gamma^{T(t)-t-1} \rho_{t:T(t)-1} \bar{G}_{t:T(t)} \right)}{\sum_{t \in \mathscr{T}(s)} \left( (1-\gamma) \sum_{h=t+1}^{T(t)-1} \gamma^{h-t-1} \rho_{t:h-1} + \gamma^{T(t)-t-1} \rho_{t:T(t)-1} \right)}$

Converting this to action-value estimates:

$Q(s,a) = \frac{\sum_{t \in \mathscr{T}(s,a)}\left( R_{t+1} + (1-\gamma)\sum_{h=t+2}^{T(t)-1}\gamma^{h-t-1} \rho_{t+1:h-1} \bar{G}_{t+1:h} + \gamma^{T(t)-t-1} \rho_{t+1:T(t)-1} \bar{G}_{t+1:T(t)} \right)}{\sum_{t \in \mathscr{T}(s,a)} \left( 1 + (1-\gamma) \sum_{h=t+2}^{T(t)-1} \gamma^{h-t-1} \rho_{t+1:h-1} + \gamma^{T(t)-t-1} \rho_{t+1:T(t)-1} \right)}$

For the algorithm on page 111, need to add a variable in the loop to keep track of $\bar{G}$ both from the start of the episode forwards.  The inner loop should also start from the beginning of each episode and go forwards rather than starting at the end going backwards.  The term added to the numerator and denominator will be ready including $\bar{G}$ and $\rho$ once the end of the episode is reached.  A $\gamma$ accumulator can be initiazed at 1 and kept track of in the inner loop by repeatedly multiplying by γ each iteration.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$00cd2194-af13-415a-b725-bb34832e5d9acell_id$00cd2194-af13-415a-b725-bb34832e5d9acodefunction figure5_3(;n = 100, vinit = 0.0f0, targetstart = true, episodes = 10_000, title = "", caption = "Figure 5.3")
	#note that with targetstart = true, the episode will always begin with the action selected by the target policy.  Since we only care about the value estimate for this state, we only need the q value for actions taken by the target policy.  This way, every episode will produce relevant sample updates
	runsim(importancemethod) = monte_carlo_pred_V(π_blackjack1, π_rand_blackjack, blackjack_mdp, 1.0f0; num_episodes =  episodes, historystateindex = blackjack_stateindex1, vinit = vinit, override_state_init = true, samplemethod=importancemethod)[1]
	vhists = [[runsim(importancemethod) for _ in 1:n] for importancemethod in [Ordinary(), Weighted()]]
	errors = [[(v .- blackjack_state_value1) .^2 for v in vhists] for vhists in vhists]
	traces1 = [scatter(x = 1:episodes, y = mean(error), name = name) for (error, name) in zip(errors, ["Ordinary importance sampling", "Weighted importance sampling"])]
	p1 = plot(traces1, Layout(xaxis_type = "log", yaxis_range = [-0.1,5], legend_orientation = "h", legend_y = -0.2, xaxis_title = "Episodes", yaxis_title = "Mean square error <br> (average over $n runs)", title = title))
	
	traces2 = [scatter(x = 1:episodes, y = mean(vhist), name = name) for (vhist, name) in zip(vhists, ["Ordinary importance sampling", "Weighted importance sampling"])]
	
	p2 = plot(traces2, Layout(xaxis_type = "log", legend_orientation = "h", xaxis_title = "Episodes", yaxis_title = "State Value Estimate (average over $n runs)"))

	traces3 = [scatter(x = 1:episodes, y = var(vhist), name = name) for (vhist, name) in zip(vhists, ["Ordinary importance sampling", "Weighted importance sampling"])]
	p3 = plot(traces3, Layout(xaxis_type = "log", legend_orientation = "h", xaxis_title = "Episodes", yaxis_title = "State Value Estimate Variance Over $n runs"))
	md"""
	### $caption
	Weighted importance sampling produces lower error estimates of the value of a single blackjack state from off-policy episodes

	$p1
	"""
endmetadatashow_logsèdisabled®skip_as_script«code_folded$da66b3be-1fe2-4edb-9560-71ce7c0bed12cell_id$da66b3be-1fe2-4edb-9560-71ce7c0bed12codeh(πstar1_racetrack2, Qstar1_racetrack2) = off_policy_MC_control(track2_mdp, 1.0f0; num_episodes = opmc2)metadatashow_logsèdisabled®skip_as_script«code_folded$d16ac2a8-1a5a-4ded-9285-d2c6cd550066cell_id$d16ac2a8-1a5a-4ded-9285-d2c6cd550066code#target policy state value estimate and variance, why is the mean squared error after 1 episode for weighted importance sampling less than the variance of the state values?  The reason is after 1 episode of weighted importance sampling, there is a greater than 50% chance of a 0% decision being made resulting in the value estimate not updating from its initial value.  Since that initial value is 0 and episodes are likely to terminate with rewards of -1 or 1, the variance is moved closer to 0 than for truly sampling the target policy rewards
const blackjack_state_value1 = estimate_blackjack_state(blackjack_state1, π_blackjack1, 5_000_000) |> meanmetadatashow_logsèdisabled®skip_as_script«code_folded$830d6d61-7259-43e7-8d6d-09bc81818dd9cell_id$830d6d61-7259-43e7-8d6d-09bc81818dd9codefigure_5_4(6, 10)metadatashow_logsèdisabled®skip_as_script«code_folded$e293e184-5938-40b5-a04b-5306760a06aecell_id$e293e184-5938-40b5-a04b-5306760a06aecodefunction estimate_blackjack_state(blackjackstate, π_blackjack, num_episodes)
	stateindex = blackjack_mdp.statelookup[blackjackstate]
	estimate_mdp_state(blackjack_mdp, π_blackjack, stateindex, num_episodes)
endmetadatashow_logsèdisabled®skip_as_script«code_folded$66645f1a-b591-43e7-b931-8ed0cc7d6898cell_id$66645f1a-b591-43e7-b931-8ed0cc7d6898code]begin
	race_1_2
	showrace(track2, create_policy_function(πstar1_racetrack2, track2_mdp))
endmetadatashow_logsèdisabled®skip_as_script«code_folded$658ceeaa-1b45-47bd-a364-eaa1759d17accell_id$658ceeaa-1b45-47bd-a364-eaa1759d17accode#starting in state s0 and with policy π, complete a single episode on given track returning the trajectory and rewards
function race_track_episode(s0::S, a0::A, π, track; maxsteps = Inf, failchance = 0.1) where {S, A}
    # @assert in(s0.position, track.start)
    # @assert s0.velocity == (0, 0)

    #take a forward step from current state returning new state and whether or not the episode is over
    function step(s, a)
        pnew, vnew, psquare = project_path(s.position, s.velocity, a)
		# setdiff!(psquare, track.body, track.start)
        # fsquares = intersect(psquare, track.finish)
		finish = any(square -> in(square, track.finish), psquare)
        # outsquares = setdiff!(psquare, track.body, track.start)
        # if !isempty(fsquares) #car finished race
		if finish # care finished race
            ((position = first(intersect!(psquare, track.finish)), velocity = (0, 0)), true)
        elseif !isempty(setdiff!(psquare, track.body, track.start)) #car path went outside of track
            ((position = rand(track.start), velocity = (0, 0)), false)
        else
            ((position = pnew, velocity = vnew), false)
        end
    end

	states = [s0]
	actions = [a0]
    rewards = Vector{Float32}()

    function get_traj(s, a, nstep = 1)
        (snew, isdone) = step(s, a)
		push!(rewards, -1.0f0)
		while !isdone && (nstep < maxsteps)
        	anew = π(snew)
			push!(states, snew)
			push!(actions, anew)
			(snew, isdone) = step(snew, rand() > failchance ? anew : (0, 0))
			push!(rewards, -1.0f0)
			nstep += 1
		end
		return isdone
    end

    isdone = get_traj(s0, a0)
	!isdone && length(states) >= maxsteps && return Vector{S}(), Vector{A}(), Vector{Float32}()

    return states, actions, rewards
endmetadatashow_logsèdisabled®skip_as_script«code_folded$04752549-ffca-4e31-869e-714f835d3e85cell_id$04752549-ffca-4e31-869e-714f835d3e85codeIconst blackjack_stateindex1 = blackjack_mdp.statelookup[blackjack_state1]metadatashow_logsèdisabled®skip_as_script«code_folded$e89706f1-0c6a-4da4-82a1-ccf153f2e186cell_id$e89706f1-0c6a-4da4-82a1-ccf153f2e186code;md"""
#### Monte Carlo Exploring Starts Solution Method
"""metadatashow_logsèdisabled®skip_as_script«code_folded$ab10ccd7-75ba-475c-af26-f8b36daaf880cell_id$ab10ccd7-75ba-475c-af26-f8b36daaf880codelmd"""
> ### *Exercise 5.11* 
> In the boxed algorithm for off-policy MC control, you may have been expecting the $W$ update to have involved the importance-sampling ratio $\frac{\pi(A_t|S_t)}{b(A_t|S_T)}$, but instead it involves $\frac{1}{b(A_t|S_t)}$.  Why is this nevertheless correct?

The target policy $\pi(s)$ is always deterministic, only selecting a single action according to $\pi(s)=\text{argmax}_a Q(s,a)$.  Therefore the numerator in importance-sampling ratio will either be 1 when the trajectory action matches the one given by $\pi(s)$ or it will be 0.  The inner loop will exit if such as action is selected as it will result in zero values of W for the rest of the trajectory and thus no further updates to $Q(s,a)$ or $\pi(s)$.  The only value of $\pi(s)$ that would be encountered in the equation is therefore 1 which is why the numerator is a constant.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$4481fa33-1ff3-4778-8486-d4d8a15775cdcell_id$4481fa33-1ff3-4778-8486-d4d8a15775cdcode\begin 
	run2_2
	showrace(track2, create_policy_function(πstar2_racetrack2, track2_mdp))
endmetadatashow_logsèdisabled®skip_as_script«code_folded$1b02e593-d791-424c-b956-62cc480fcf40cell_id$1b02e593-d791-424c-b956-62cc480fcf40codemd"""
##### Results Summary
Unlike the other techniques, Monte Carlo ϵ-Soft requires selecting the parameter ϵ and the performance of each algorithm varies a lot with this parameter and the number of training episodes.  For a short training time of 1,000 episodes, small values of ϵ seem to perform better such as 0.01 or 0.02.  Under those conditions, performance of the policies is far better than random with mean episode lengths of 32 and 24 respectively.  Longer training improves the results but also requires changing ϵ and possibly introducing a decay rate so it can start high and approach 0 after a large number of episodes.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$72e9721f-ee17-4557-b090-71728e6c22cecell_id$72e9721f-ee17-4557-b090-71728e6c22cecode?makelookup(v::Vector) = Dict(x => i for (i, x) in enumerate(v))metadatashow_logsèdisabled®skip_as_script«code_folded$11723075-d1db-4512-abf2-3fe494a71a3bcell_id$11723075-d1db-4512-abf2-3fe494a71a3bcodefunction check_policy(π::Matrix{T}, mdp::MDP_Opaque{S, A, F}) where {T <: AbstractFloat, S, A, F}
#checks to make sure that a policy is defined over the same space as an MDP
	(n, m) = size(π)
	num_actions = length(mdp.actions)
	num_states = length(mdp.states)
	@assert n == num_actions "The policy distribution length $n does not match the number of actions in the mdp of $(num_actions)"
	@assert m == num_states "The policy is defined over $m states which does not match the mdp state count of $num_states"
	return nothing
endmetadatashow_logsèdisabled®skip_as_script«code_folded$059b1c0f-eb21-4a4a-8aed-64e9ac07b541cell_id$059b1c0f-eb21-4a4a-8aed-64e9ac07b541code`md"""
Number of Episodes: $(@bind mces2 confirm(NumberField(1:10_000_000, default = 1_000)))
"""metadatashow_logsèdisabled®skip_as_script«code_folded$b2115f33-f8e2-452e-9b0e-90610f0f09b1cell_id$b2115f33-f8e2-452e-9b0e-90610f0f09b1code٣function make_random_policy(mdp::MDP_Opaque; init::T = 1.0f0) where T <: AbstractFloat
	ones(T, length(mdp.actions), length(mdp.states)) ./ length(mdp.actions)
endmetadatashow_logsèdisabled®skip_as_script«code_folded$82284c63-2306-4469-9b1a-a5ec87037e79cell_id$82284c63-2306-4469-9b1a-a5ec87037e79codeplot_fig5_1()metadatashow_logsèdisabled®skip_as_script«code_folded$5b32bbc7-dc34-4fc3-bacc-92e55f26a98ccell_id$5b32bbc7-dc34-4fc3-bacc-92e55f26a98ccode4[monte_carlo_pred_Q(π_blackjack1, π_rand_blackjack, blackjack_mdp, 1.0f0; num_episodes =  1, historystateindex = blackjack_stateindex1, qinit = 0.0f0, override_state_init = true, samplemethod=Ordinary(), use_target_initial_action = true)[3][1:1] |> sum for i in 1:1000] |> v -> mean(filter(x -> x != 0, v))metadatashow_logsèdisabled®skip_as_script«code_folded$c8be6951-b6ec-4444-8c7f-ca5db6681571cell_id$c8be6951-b6ec-4444-8c7f-ca5db6681571code٠makegridsquare(x, y; class="", xmin=0, ymin=0) = """<div class = "$class" style="grid-column-start: $(x - xmin + 1); grid-row-start: $(y - ymin + 1);"></div>"""metadatashow_logsèdisabled®skip_as_script«code_folded$887de995-04e8-4d84-88d7-ad096a5747dfcell_id$887de995-04e8-4d84-88d7-ad096a5747dfcodeAmd"""
Example trajectories after training for $opmc1 episodes
"""metadatashow_logsèdisabled®skip_as_script«code_folded$3ee31af5-b19c-49dc-8fbf-f07e93d1f0c5cell_id$3ee31af5-b19c-49dc-8fbf-f07e93d1f0c5codegmd"""
### Figure 5.2b:
Recreation of Figure 5.2 using an ϵ-soft MC control with $$\epsilon = 0.1$$
"""metadatashow_logsèdisabled®skip_as_script«code_folded$ffd1e39d-e66b-40a3-8ad1-c9480d371fe8cell_id$ffd1e39d-e66b-40a3-8ad1-c9480d371fe8codemd"""
##### Results Summary
Each environment has 7300 and 12875 states respectively, so Monte Carlo Exploring starts would need to sample at least this many episodes to have a non zero probability of coverage.  Surprisingly, even after just 1000 episodes of training the results are quite an improvement over the random policy with the mean finish time of about 30 steps for both.  Although at the high end, some episodes still take over 100 steps to complete (still much better than the random policy).  If we allow training for 10-100 million episodes, which is necessary to get a reasonable sample size for each state, then the results are much improved with episode step lengths from 11 to 18 for track 1 and 9 to 16 for track2.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$13cc524c-d983-44f4-8731-0595249fb888cell_id$13cc524c-d983-44f4-8731-0595249fb888codefunction monte_carlo_ES(mdp::MDP_Opaque, π_init::Matrix{T}, Q_init::Matrix{T}, γ, num_episodes; override_state_init = false) where T <: Real
	#initialize
	π = copy(π_init)
	Q = copy(Q_init)
	counts = zeros(Int64, length(mdp.actions), length(mdp.states))
	vhold = zeros(T, length(mdp.actions))
	for i in 1:num_episodes
		s0 = override_state_init ? rand(mdp.states) : mdp.state_init()
		a0 = rand(mdp.actions)
		(states, actions, rewards) = mdp.simulator(s0, a0, π)

		#there's no check here so this is equivalent to every-visit estimation
		t = length(states)
		g = zero(T)
		for t in length(states):-1:1
			#accumulate future discounted returns
			g = γ*g + rewards[t]
			i_s = mdp.statelookup[states[t]]
			i_a = mdp.actionlookup[actions[t]]
			#increment count by 1
			counts[i_a, i_s] += 1
			Q[i_a, i_s] += (g - Q[i_a, i_s])/counts[i_a, i_s] #update running average of Q
			vhold .= Q[:, i_s]
			make_greedy_policy!(vhold)
			π[:, i_s] .= vhold
		end
	end
	return π, Q
endmetadatashow_logsèdisabled®skip_as_script«code_folded$8faca500-b80d-4b50-88b6-683d18a1286bcell_id$8faca500-b80d-4b50-88b6-683d18a1286bcodeٕ#behavior policy state value estimate and variance
estimate_blackjack_state(blackjack_state1, π_rand_blackjack, 5_000_000) |> v -> (mean(v), var(v))metadatashow_logsèdisabled®skip_as_script«code_folded$755be8f1-9d9e-4afd-8a70-07fab78e4333cell_id$755be8f1-9d9e-4afd-8a70-07fab78e4333codemd"""
##### Track 2
"""metadatashow_logsèdisabled®skip_as_script«code_folded$01683e11-a368-45bc-abbc-bbd5c94d7b22cell_id$01683e11-a368-45bc-abbc-bbd5c94d7b22code&plot_value(grid; title = "", xtitle = "Dealer showing", ytitle = "Player sum", xticktext = ["A", "10"], yticktext = [12, 21], showscale = false, width = 350, height = 300) = plot(heatmap(x = 1:10, y = 12:21, z = grid, showscale=showscale, colorscale = "Bluered", zmin = -1.0, zmax = 1.0), Layout(title = title, yaxis_title = ytitle, yaxis_tickvals = [12, 21], xaxis_title = xtitle, yaxis_ticktext = yticktext, xaxis_tickvals = [1, 10], xaxis_ticktext = xticktext, width = width, height = height, autosize = false, margin = attr(l = 0, b = 0, r = 0)))metadatashow_logsèdisabled®skip_as_script«code_folded$5e2420fb-b2cc-49fc-91e3-3de80fba698bcell_id$5e2420fb-b2cc-49fc-91e3-3de80fba698bcode&#run a single race episode from a valid starting position with a given policy and track
function runrace(π; track = track1, maxsteps = 10_000)
	s0 = (position = rand(track.start), velocity = (0, 0))
	a0 = π(s0)
	race_track_episode(s0, a0, π, track, maxsteps = maxsteps, failchance = 0.0)
endmetadatashow_logsèdisabled®skip_as_script«code_folded$1e6f7e5e-c5ce-479c-abbb-6c388c254626cell_id$1e6f7e5e-c5ce-479c-abbb-6c388c254626code2#there's no check here so this is equivalent to every-visit estimation
function updateV!(mdp, V::Vector{T}, counts::Vector{T}, π_target::Matrix{T}, π_behavior::Matrix{T}, states, actions, rewards::Vector{T}, γ::T, samplemethod::ImportanceMethod; t = length(states), g_old = zero(T), w = one(T)) where T<:Real		

	#terminate at the end of a trajectory
	(t == 0) && return w

	i_s = mdp.statelookup[states[t]]
	i_a = mdp.actionlookup[actions[t]]

	#since this is the value estimate, every action must update the importance-sampling weight before the update to that state is calculated. In contrast, for the action-value estimate the weight is only the actions made after the current step are relevant to the weight
	w = w * π_target[i_a, i_s] / π_behavior[i_a, i_s]

	counts[i_s] += updatecount(samplemethod, w)

	#terminate when w = 0 if the weighted sample method is being used.  under ordinary sampling, the updates to the count and value will still occur because the denominator will still increment
	if (w == zero(T)) && isa(samplemethod, Weighted) 
		return w
	end
	
	#accumulate future discounted returns
	g = γ*g_old + rewards[t]
	V[i_s] += updatevalue(samplemethod, V[i_s], g, w, counts[i_s])
	updateV!(mdp, V, counts, π_target, π_behavior, states, actions, rewards, γ, samplemethod; t = t-1, g_old = g, w = w)
endmetadatashow_logsèdisabled®skip_as_script«code_folded$5e012ead-b4f9-45a9-979d-88b0b1086263cell_id$5e012ead-b4f9-45a9-979d-88b0b1086263code#weighted importance sampling produces the correct value estimate even after 100 episodes
monte_carlo_pred_Q(onestate_π_target, onestate_π_b, onestate_mdp, 1.0f0; num_episodes =  100, samplemethod = Weighted())metadatashow_logsèdisabled®skip_as_script«code_folded$a0eb6939-11bb-458d-bee3-9ed763819f62cell_id$a0eb6939-11bb-458d-bee3-9ed763819f62code+md"""
#### Racetrack Visualization Code
"""metadatashow_logsèdisabled®skip_as_script«code_folded$21d248f5-edad-4614-8c1c-ae330f9e5a18cell_id$21d248f5-edad-4614-8c1c-ae330f9e5a18codestruct MDP_Opaque{S, A, F<:Function, G<:Function}
	states::Vector{S}
	statelookup::Dict{S, Int64}
	actions::Vector{A}
	actionlookup::Dict{A, Int64}
	state_init::G #function that produces an initial state for an episode
	simulator::F #function that takes as input an initial state action pair as well as the policy to be simulated.  Should return a trajectory as a vector of states, actions and rewards all of equal length
	function MDP_Opaque(states::Vector{S}, actions::Vector{A}, state_init::G, simulator::F) where {S, A, F<:Function, G<:Function}
		statelookup = makelookup(states)
		actionlookup = makelookup(actions)
		new{S, A, F, G}(states, statelookup, actions, actionlookup, state_init, simulator)
	end
endmetadatashow_logsèdisabled®skip_as_script«code_folded$a68b4965-c392-47e5-9b29-93e7ada9990acell_id$a68b4965-c392-47e5-9b29-93e7ada9990acodeofunction plot_fig5_1()
	(uagrid10k, nuagrid10k) = eval_blackjack_policy(π_blackjack1, 10_000)
	(uagrid500k, nuagrid500k) = eval_blackjack_policy(π_blackjack1, 500_000)
	p1 = plot_value(uagrid10k; title = "After 10,000 episodes", width = 320, ytitle = "", xtitle = "") 
	p2 = plot_value(nuagrid10k, width = 320, ytitle = "")
	# p2 = plot(heatmap(z = nuagrid10k, showscale = false, colorscale = "Bluered", zmin = -1.0, zmax = 1.0), Layout(width = 300, height = 300, margin = attr(b = 0, r = 0, t=0, l = 0), autosize = false, yaxis_title = "No usable ace"))
	p3 = plot_value(uagrid500k, title = "After 500,000 episodes", showscale=true, width = 400, xtitle = "")
	# p3 = plot(heatmap(z = uagrid500k, showscale = false, colorscale = "Bluered", zmin = -1.0, zmax = 1.0), Layout(margin = attr(b = 0, r = 0, t=0, l = 0), autosize = false, width = 350, height = 300, title = "After 500,000 episodes"))
	p4 = plot_value(nuagrid500k; showscale = true, width = 400)
	# p4 = plot(heatmap(z = nuagrid500k, colorscale = "Bluered", zmin = -1.0, zmax = 1.0), Layout(width = 300, height = 300, yaxis_ticks = (1:10, 12:21), xaxis_ticks = (1:10, ["A", "", "", "", "", "", "", "", "", "10"]), legend = false, xaxis_title = "Dealer Showing"))

	# plot(p1, p3, p2, p4, layout = (2, 2))
	@htl("""
	<div style = "display: flex; flex-wrap: wrap; flex-direction: row; width: 800px; background-color: white; color: black; align-items: center; justify-content: center;">
		<div style = "width: 50px;">Usable ace</div>
		<div>$p1</div> 
		<div>$p3</div>
		<div style = "width: 50px;">No usable ace</div>
		<div>$p2</div> 
		<div>$p4</div>
	</div>
	""")
	# [p1 p3; p2 p4]
endmetadatashow_logsèdisabled®skip_as_script«code_folded$d766d44e-3684-497c-814e-8f71740cb232cell_id$d766d44e-3684-497c-814e-8f71740cb232code٢md"""
### **Figure 5.1**:  
Approximate state-value functions for the blackjack policy that sticks only on 20 or 21, computed by Monte Carlo policy evaluation
"""metadatashow_logsèdisabled®skip_as_script«code_folded$0dfd7afb-127c-4afd-8374-3c9a20a9ee76cell_id$0dfd7afb-127c-4afd-8374-3c9a20a9ee76code.π_racetrack_rand(s) = rand(racetrack_actions)metadatashow_logsèdisabled®skip_as_script«code_folded$bf33230e-342b-4486-89ac-9667438de503cell_id$bf33230e-342b-4486-89ac-9667438de503codemd"""
> ### *Exercise 5.8* 
> The results with Example 5.5 and shown in Figure 5.4 used a first-visit MC method.  Suppose that instead an every-visit MC method was used on the same problem.  Would the variance of the estimator still be infinite?  Why or why not?

The state value estimate can be computed by summing terms for all of the episode lengths just like for the first visit method.  Each episode has a reward of +1 from the terminal transition and we only need to consider episodes that take the left action.  $\frac{\pi(A_t|S_t)}{b(A_t|S_t)} = 2$ for all cases, so the importance sampling ratio is just $2^T$ where T is the total length of that episode.  The probabilities for each episode length is unchanged from Example 5.5 and is just 0.1 times 0.9 times the number of steps preceeding the terminal step.  Compared to the calculation in Example 5.5, the expected value calculation must also have the importance sampling ratio terms for all of N visits in the length N episode instead of just the first one:

Length 1 episode

$\frac{1}{2} \cdot 0.1 \cdot (2)^2$

Length 2 episode, the term representing X is now an average of every visit along the trajectory.  The probability of the trajectory is unchanged from before.

$\frac{1}{2} \cdot 0.9 \cdot \frac{1}{2} \cdot 0.1 \left ( \frac{2^2 + 2}{2} \right)^2$

Length 3 episode

$\frac{1}{2} \cdot 0.9 \cdot \frac{1}{2} \cdot 0.9 \cdot \frac{1}{2} \cdot 0.1 \left ( \frac{2^3 + 2^2 + 2}{3} \right)^2$

Length N episode

$=0.1 \left ( \frac{1}{2} \right ) ^N 0.9^{N-1} \left ( \frac{\sum_{i=1}^N 2^i}{N} \right ) ^2$

So the expected value is the sum of these terms for every possible episode length:
"""metadatashow_logsèdisabled®skip_as_script«code_folded$826139cc-b52e-11ec-0d47-25ab689851fdcell_id$826139cc-b52e-11ec-0d47-25ab689851fdcodewmd"""
# Chapter 5: Monte Carlo Methods

In this chapter we will use a sampling technique that does not require complete knowledge of the environment, only the ability to interact with it.  We will focus on episodic tasks so that the sampled returns are always well defined.  Unlike the dynamic programming methods from before, these techniques will estimate the value functions rather than computing them directly.  With enough samples, these techniques will also converge to the correct solution.

## 5.1 Monte Carlo Prediction

First we consider using Monte Carlo methods to learn the state-value function for a given policy.  The most obvious way to estimate this is to simply average the returns observed after vising a particular state.  If we save the trajectories of an agent interacting with an MDP, we can keep track of how many times an agent visits a state.  In the technique called *first visit MC* we look at the returns accumulated after the first visit to a state in that episode only making a single update. It is also possible to update the state value for every visit that occurs in an episode, but the theoretical properties for *first visit MC* are more widely studied.  Both techniques, however, can be shown to converge as the number of visits goes to infinity.  Below is code implementing Monte Carlo prediction using *every visit MC* and an in place update of the average
"""metadatashow_logsèdisabled®skip_as_script«code_folded$0bd705cb-ad38-4cbb-b8fc-7e0617635282cell_id$0bd705cb-ad38-4cbb-b8fc-7e0617635282codecmd"""
### Optimal Blackjack Policy Found with Off-policy MC control (behavior policy is random)
"""metadatashow_logsèdisabled®skip_as_script«code_folded$43f9b824-fd56-4d56-84c3-23e2a3a37178cell_id$43f9b824-fd56-4d56-84c3-23e2a3a37178codemonte_carlo_pred_V(π_blackjack1, π_rand_blackjack, blackjack_mdp, 1.0f0; num_episodes =  100000, historystateindex = blackjack_stateindex1, vinit = 0.0f0, override_state_init = true, samplemethod=Ordinary())[3] |> mean #mean weight is 2 and it stays this way as the number of episodes increases so the returns that are seen by the behavior are roughtly doubled and counted with the 0 returnsmetadatashow_logsèdisabled®skip_as_script«code_folded$b39d1ea0-86a2-4215-ae73-e4492f3f2f00cell_id$b39d1ea0-86a2-4215-ae73-e4492f3f2f00codeKmd"""
### Example 5.4: Off-policy Estimation of a Blackjack State Value
"""metadatashow_logsèdisabled®skip_as_script«code_folded$a307e780-996a-485f-af59-b44982dfceb4cell_id$a307e780-996a-485f-af59-b44982dfceb4code/function rendertrack(track; episode = ())
	trajectory = if isempty(episode)
		Dict()
	else
		states, actions, rewards = episode
		Dict(begin
			position, velocity = states[i]
			action = actions[i]
			position => (velocity = velocity, action = action)
		end
		for i in eachindex(first(episode)))
	end
	
	function getvelocities(position)
		!haskey(trajectory, position) && return ()
		(vx, vy) = trajectory[position].velocity
		(dvx, dvy) = trajectory[position].action
		(vx = vx, vy = vy, dvx = dvx, dvy = dvy)
	end
	trackpoints = union(track...)
    xmin, xmax = extrema(p -> p[1], trackpoints)
    ymin, ymax = extrema(p -> p[2], trackpoints)
	function makesquare(a; kwargs...) 
		velocities = getvelocities(a)
		isempty(velocities) && return makegridsquare(first(a), last(a); xmin = xmin, ymin = ymin, kwargs...)
		makegridsquare(first(a), last(a), velocities.vx, velocities.vy, velocities.dvx, velocities.dvy; xmin = xmin, ymin = ymin, kwargs...)
	end
	startsquares = [makesquare(a; class="start") for a in track.start]
	tracksquares = [makesquare(a) for a in track.body]
	finishsquares = [makesquare(a; class = "finish") for a in track.finish]
	squares = reduce(*, vcat(startsquares, tracksquares, finishsquares)) |> HTML

	racemessage = isempty(episode) ? "" : "Race finished in $(length(first(episode))) steps"

	@htl("""
	<div>
	$racemessage
	<div style="background-color: white; color: black;">
		<div style="display:flex; align-items: flex-start">
		<div class = "track">
			$squares
		</div>
		Finish <br> line
		</div>
		<div>Starting line</div>
	</div>
	</div>
	""")
endmetadatashow_logsèdisabled®skip_as_script«code_folded$b040f245-b2d6-4ec6-aa7f-511c54aabd0dcell_id$b040f245-b2d6-4ec6-aa7f-511c54aabd0dcode^#recreation of figure 5.2 using ϵ-soft method
figure_5_2(πstar_blackjack2, Qstar_blackjack2)metadatashow_logsèdisabled®skip_as_script«code_folded$7cdf4142-82fe-4aa6-9665-84a1eef5d038cell_id$7cdf4142-82fe-4aa6-9665-84a1eef5d038code!@bind race_1_2 Button("Run race")metadatashow_logsèdisabled®skip_as_script«code_folded$3d10f89f-876e-4d25-b8d6-34ce5c99eb8ccell_id$3d10f89f-876e-4d25-b8d6-34ce5c99eb8ccode#Given there are 7300 states to the problem with track1, exploring starts would need to sample at least this many times to even explore all of them.  Using 100_000 episodes, it produces a policy that finishes the race between 16 and 100 steps usually, but the technique works with higher variance even as low as 1000 episodes.
begin 
	run2_1
	showrace(track1, create_policy_function(πstar2_racetrack1, track1_mdp))
endmetadatashow_logsèdisabled®skip_as_script«code_folded$772b4dd6-870c-4a16-937c-701d5bb5da44cell_id$772b4dd6-870c-4a16-937c-701d5bb5da44code@bind run3_1 Button("Run Race")metadatashow_logsèdisabled®skip_as_script«code_folded$1aaf3827-5851-4156-a7e6-14f5e4d00238cell_id$1aaf3827-5851-4156-a7e6-14f5e4d00238code*md"""
#### Random Policy Visualization
"""metadatashow_logsèdisabled®skip_as_script«code_folded$d6e7cc6d-f397-4bdf-974e-9a16922393ddcell_id$d6e7cc6d-f397-4bdf-974e-9a16922393ddcodeٍfunction create_policy_function(π, mdp)
	function f(s)
		i_s = mdp.statelookup[s]
		i_a = sample_action(π, i_s)
		mdp.actions[i_a]
	end
endmetadatashow_logsèdisabled®skip_as_script«code_folded$1951fc4c-acc4-49a6-a907-7447ff0f430acell_id$1951fc4c-acc4-49a6-a907-7447ff0f430acodeAmd"""
Example trajectories after training for $opmc2 episodes
"""metadatashow_logsèdisabled®skip_as_script«code_folded$660ef59c-205c-44c2-9c46-5a74e09497abcell_id$660ef59c-205c-44c2-9c46-5a74e09497abcode'struct Weighted <: ImportanceMethod endmetadatashow_logsèdisabled®skip_as_script«code_folded$a47474b0-f262-4453-a116-addc3a09119ecell_id$a47474b0-f262-4453-a116-addc3a09119ecodeoq_offpol = monte_carlo_pred_Q(π_blackjack1, π_rand_blackjack, blackjack_mdp, 1.0f0; num_episodes = 1_000_000)metadatashow_logsèdisabled®skip_as_script«code_folded$acb270a1-e2b9-46bc-9a52-9f66f1cca17ccell_id$acb270a1-e2b9-46bc-9a52-9f66f1cca17ccode@bind mcϵs1 confirm(PlutoUI.combine() do Child
	md"""
	| Number of Episodes | ϵ | Decay ϵ |
	| :-: | :-: | :-: |
	|$(Child(:episodes, NumberField(1:10_000_000, default = 1_000))) | $(Child(:ϵ, NumberField(0.001:0.001:1.0; default = 0.01))) | $(Child(:decay, CheckBox())) |
	"""
end)metadatashow_logsèdisabled®skip_as_script«code_folded$334b4d77-8784-46be-b9e8-80c0a2244694cell_id$334b4d77-8784-46be-b9e8-80c0a2244694codefunction monte_carlo_ϵsoft(mdp::MDP_Opaque, ϵ::T, π_init::Matrix{T}, Q_init::Matrix{T}, γ, num_episodes::Integer, quench_episode::Integer, decay_ϵ::Bool) where T <: Real
	#initialize
	π = copy(π_init)
	Q = copy(Q_init)
	counts = zeros(Int64, length(mdp.actions), length(mdp.states))
	vhold = zeros(T, length(mdp.actions))
	decayrate = decay_ϵ ? ϵ / num_episodes : zero(T)
	for i in 1:num_episodes
		s0 = mdp.state_init()
		i_a0 = sample_action(π, mdp.statelookup[s0])
		a0 = mdp.actions[i_a0]
		(states, actions, rewards) = mdp.simulator(s0, a0, π)

		g = zero(T)
		for t in length(states):-1:1
			#accumulate future discounted returns
			g = γ*g + rewards[t]
			i_s = mdp.statelookup[states[t]]
			i_a = mdp.actionlookup[actions[t]]
			#increment count by 1
			counts[i_a, i_s] += 1
			Q[i_a, i_s] += (g - Q[i_a, i_s])/counts[i_a, i_s] #update running average of Q
			vhold .= Q[:, i_s]
			#if desired at some point prior to the final episode the training can revert to using the greedy policy
			if i > quench_episode
				make_greedy_policy!(vhold)
			else
				make_ϵsoft_policy!(vhold, ϵ)
			end
			π[:, i_s] .= vhold
			ϵ -= decayrate
		end
	end
	return π, Q
endmetadatashow_logsèdisabled®skip_as_script«code_folded$e5384dd0-fad1-4a24-b011-73b062fcfb1bcell_id$e5384dd0-fad1-4a24-b011-73b062fcfb1bcode md"""
> ### *Exercise 5.1* 
> Consider the diagroms on the right in Figure 5.1.  Why does the estimated value function jump for the last two rows in the rear?  Why does it drop off for the whole last row on the left?  Why are the frontmost values higher in the upper diagrams than in the lower?

The last two rows in the rear are for a player sum equal to 20 or 21.  For a sum of 19 and lower, this policy will hit which is suboptimal for these high sums.  For the sums of 20 or 21 though, sticking is optimal so the value jumps compared to the suboptimal hit at 19.

The far left row represents cases where the dealer is showing an Ace.  Since an Ace is a flexible card, the dealer policy will have more options that result in a win including the possibility of having another face card already (dealer natural).  It is always worse for the player if the dealer is known to have an Ace.

The frontmost values represent cases where the player sum is 12.  If there is a usable Ace this means that means that the player has two Aces which results in a sum of 12 when the first Ace is counted as 1 and the second is *usable* and counted as 11.  If there is no usable Ace than a sum of 12 would have to result from some other combination of cards such as 10/2, 9/3, etc...  Since the first case has two Aces, it means that potentially both could count as 1 if needed to avoid a bust.  In the case without a usable Ace, the sum is the same, but there are more opportunities to bust if we draw a card worth 10, so having a sum of 12 with a usable Ace is strictly better.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$35914757-6af1-4056-bba4-a9996f65f7f7cell_id$35914757-6af1-4056-bba4-a9996f65f7f7code#normal importance sampling for one state MDP produces state-action value estimates that fail to converge to [1, 0] even after 1M episodes
monte_carlo_pred_Q(onestate_π_target, onestate_π_b, onestate_mdp, 1.0f0; num_episodes =  1_000_000)metadatashow_logsèdisabled®skip_as_script«code_folded$cde7be85-9344-4526-bcb2-c2c8b3322435cell_id$cde7be85-9344-4526-bcb2-c2c8b3322435codeٍ(πstar3_racetrack2, Qstar3_racetrack2) = monte_carlo_ϵsoft(track2_mdp, Float32(mcϵs2.ϵ), 1.0f0, mcϵs2.episodes; decay_ϵ = mcϵs2.decay)metadatashow_logsèdisabled®skip_as_script«code_folded$881ba6c3-0e6a-4bb8-bc14-2e0face560f2cell_id$881ba6c3-0e6a-4bb8-bc14-2e0face560f2codenmd"""
> ### *Exercise 5.6* 
> What is the equation analogous to (5.6) for *action* values $Q(s,a)$ instead of state values $V(s)$, again given returns generated using $b$?

Equation (5.6):

$V(s) = \frac{\sum_{t \in \mathscr{T}(s)}\rho_{t:T(t)-1}G_t}{\sum_{t \in \mathscr{T}(s)} \rho_{t:T(t)-1}}$

For $Q(s,a)$, there is no need to calculate the sampling ratio for the first action selected.  Here $\mathscr{T}(s, a)$ is the set of all time steps in which the state action pair $(s, a)$ is visited.

$Q(s,a) = \frac{\sum_{t \in \mathscr{T}(s, a)}\rho_{t+1:T(t)-1}G_t}{\sum_{t \in \mathscr{T}(s, a)} \rho_{t+1:T(t)-1}}$
"""metadatashow_logsèdisabled®skip_as_script«code_folded$5c57e4b7-51d6-492d-9fc9-bcdab1dd46f4cell_id$5c57e4b7-51d6-492d-9fc9-bcdab1dd46f4codefunction plot_blackjack_policy(π)
	πstargridua = zeros(Float64, 10, 10)
	πstargridnua = zeros(Float64, 10, 10)
	for state in blackjackstates
		i_s = blackjack_mdp.statelookup[state]
		v = π[1, i_s] - π[2, i_s]
		if state.ua
			πstargridua[state.sum-11, state.upcard] = v
		else
			πstargridnua[state.sum-11, state.upcard] = v
		end
	end

	function plot_policy_grid(grid)
		plot(heatmap(x = 1:10, y = 12:21, z = grid, showscale=false, colorscale = "Greys", zmin = -1, zmax = 1), Layout(xaxis_title = "Dealer showing", yaxis_title = "Player sum", margin = attr(t = 30, b = 0, l = 0, r = 10), width = 300, height = 300, xaxis_tickvals = 1:10, yaxis_tickvals = 12:21, yaxis_ticktext = 12:21, xaxis_ticktext = ["A"; 2:10]))
	end

	p1 = plot_policy_grid(πstargridua)
	p2 = plot_policy_grid(πstargridnua)
	# vstar = eval_blackjack_policy(Dict(s => π[s] == :hit ? [1.0, 0.0] : [0.0, 1.0] for s in blackjackstates), 500_000)
	# p1 = heatmap(πstargridua, xticks = (1:10, ["A", 2, 3, 4, 5, 6, 7, 8, 9, 10]), yticks = (1:10, 12:21), legend = false, title = "Usable Ace Policy, Black=Stick, White = Hit")
	# p2 = heatmap(πstargridnua, xticks = (1:10, ["A", 2, 3, 4, 5, 6, 7, 8, 9, 10]), yticks = (1:10, 12:21), legend = false, title = "No usable Ace Policy", xlabel = "Dealer Showing", ylabel = "Player sum")

	# p3 = heatmap(vstar[1], legend = false, yticks = (1:10, 12:21), title = "V*")
	# p4 = heatmap(vstar[2], yticks = (1:10, 12:21))
	# plot(p1, p3, p2, p4, layout = (2,2))
	(p1, p2)
endmetadatashow_logsèdisabled®skip_as_script«code_folded$e0d3d7d1-203f-42fa-8570-8d1d88bf17c2cell_id$e0d3d7d1-203f-42fa-8570-8d1d88bf17c2codemd"""
##### Track 2
"""metadatashow_logsèdisabled®skip_as_script«code_folded$760c5361-02d4-46b7-a05c-fc2d10d93de6cell_id$760c5361-02d4-46b7-a05c-fc2d10d93de6code}function monte_carlo_pred_V(π::Matrix{T}, mdp::MDP_Opaque{S, A, F, G}, γ::T; num_episodes::Integer = 1000, vinit::T = zero(T), V::Vector{T} = ones(T, length(mdp.states)) .* vinit) where {T <: AbstractFloat, S, A, F, G}
	
	check_policy(π, mdp)
	
	#initialize
	counts = zeros(Integer, length(mdp.states))

	#there's no check here so this is equivalent to every-visit estimation
	function updateV!(states, actions, rewards; t = length(states), g = zero(T))		
		#terminate at the end of a trajectory
		t == 0 && return nothing
		#accumulate future discounted returns
		g = γ*g + rewards[t]
		i_s = mdp.statelookup[states[t]]
		i_a = mdp.actionlookup[actions[t]]
		#increment count by 1
		counts[i_s] += 1
		V[i_s] += (g - V[i_s])/counts[i_s] #update running average of V
		updateV!(states, actions, rewards; t = t-1, g = g)
	end

	
	for i in 1:num_episodes
		s0 = mdp.state_init()
		i_a0 = sample_action(π, mdp.statelookup[s0])
		a0 = mdp.actions[i_a0]
		# (s0, a0) = initialize_episode()
		(states, actions, rewards) = mdp.simulator(s0, a0, π)
	
		#update value function for each trajectory
		updateV!(states, actions, rewards)
	end
	return V
endmetadatashow_logsèdisabled®skip_as_script«code_folded$d55860d1-e4c1-4a79-adbe-b40a6d6283a7cell_id$d55860d1-e4c1-4a79-adbe-b40a6d6283a7codeٓinitialize_state_action_value(mdp::MDP_Opaque; qinit::T = 0.0f0) where T<:AbstractFloat = ones(T, length(mdp.actions), length(mdp.states)) .* qinitmetadatashow_logsèdisabled®skip_as_script«code_folded$06297d75-121a-4178-b45b-83e167efd90dcell_id$06297d75-121a-4178-b45b-83e167efd90dcodejoinlines(x, y) = """
$x
$y
"""metadatashow_logsèdisabled®skip_as_script«code_folded$abe70666-39f8-4f1d-a285-a3a99f696d10cell_id$abe70666-39f8-4f1d-a285-a3a99f696d10codemd"""
> ### *Exercise 5.13* 
> Show the steps to derive (5.14) from (5.12)

Starting at (5.12)

$\rho_{t:T-1}R_{t+1}=\frac{\pi(A_t|S_t)}{b(A_t|S_t)}\frac{\pi(A_{t+1}|S_{t+1})}{b(A_{t+1}|S_{t+1})}\frac{\pi(A_{t+2}|S_{t+2})}{b(A_{t+2}|S_{t+2})}\cdots\frac{\pi(A_{T-1}|S_{T-1})}{b(A_{T-1}|S_{T-1})}R_{t+1}$

For (5.14) we need to turn this into an expected value

$\mathbb{E}[\rho_{t:T-1}R_{t+1}]$

Now we know that the reward at time step t+1 is only dependent on the action and state at time t.  Moreover, the later parts of the trajectory are also independent of each other.  So we can separate some of these terms into a product of expected values rather than an expected value of products:

$\mathbb{E}[\rho_{t:T-1}R_{t+1}]=\mathbb{E} \left [ \frac{\pi(A_t|S_t)}{b(A_t|S_t)}\frac{\pi(A_{t+1}|S_{t+1})}{b(A_{t+1}|S_{t+1})}\frac{\pi(A_{t+2}|S_{t+2})}{b(A_{t+2}|S_{t+2})}\cdots\frac{\pi(A_{T-1}|S_{T-1})}{b(A_{T-1}|S_{T-1})}R_{t+1} \right ]$

$=\mathbb{E} \left [ \frac{\pi(A_t|S_t)}{b(A_t|S_t)}R_{t+1} \right ] \prod_{k=t+1}^{T-1}\mathbb{E} \left [ \frac{\pi(A_k|S_k)}{b(A_k|S_k)} \right ]$

We know from (5.13) that $\mathbb{E} \left [ \frac{\pi(A_k|S_k)}{b(A_k|S_k)} \right ] = 1$ so the above expression simplifies to: $\mathbb{E} \left [ \frac{\pi(A_t|S_t)}{b(A_t|S_t)}R_{t+1} \right ]$.  Using the original shorthand with ρ:

$\mathbb{E}[\rho_{t:T-1}R_{t+1}]=\mathbb{E} \left [ \frac{\pi(A_t|S_t)}{b(A_t|S_t)}R_{t+1} \right ]=\mathbb{E}[\rho_{t:t}R_{t+1}]$
"""metadatashow_logsèdisabled®skip_as_script«code_folded$7ce6e28e-acd7-46d1-87d6-a25f4656d79dcell_id$7ce6e28e-acd7-46d1-87d6-a25f4656d79dcode@bind run2_1 Button("Run race")metadatashow_logsèdisabled®skip_as_script«code_folded$a85e7dd3-ea5e-4c77-a18e-f1e190658ae3cell_id$a85e7dd3-ea5e-4c77-a18e-f1e190658ae3codeكfunction sample_action(π::Matrix{T}, i_s::Integer) where T<:AbstractFloat
	(n, m) = size(π)
	sample(1:n, weights(π[:, i_s]))
endmetadatashow_logsèdisabled®skip_as_script«code_folded$68f9e0d9-5c9d-4e89-b5ae-f24fd7544a09cell_id$68f9e0d9-5c9d-4e89-b5ae-f24fd7544a09coden(πstar2_racetrack1, Qstar2_racetrack1) = monte_carlo_ES(track1_mdp, 1.0f0, mces1; override_state_init = true)metadatashow_logsèdisabled®skip_as_script«code_folded$ec29865f-3ba3-4bb3-84df-c2b472e03ff2cell_id$ec29865f-3ba3-4bb3-84df-c2b472e03ff2coden(πstar_blackjack, Qstar_blackjack) = monte_carlo_ES(blackjack_mdp, 1.0f0, 5_000_000; π_init = π_blackjack1)metadatashow_logsèdisabled®skip_as_script«code_folded$1d6eccf0-2731-47fc-9a41-ea8649e290efcell_id$1d6eccf0-2731-47fc-9a41-ea8649e290efcodeٍ(πstar3_racetrack1, Qstar3_racetrack1) = monte_carlo_ϵsoft(track1_mdp, Float32(mcϵs1.ϵ), 1.0f0, mcϵs1.episodes; decay_ϵ = mcϵs1.decay)metadatashow_logsèdisabled®skip_as_script«code_folded$9ca72278-fff6-4b0f-b72c-e0d3768aff73cell_id$9ca72278-fff6-4b0f-b72c-e0d3768aff73code"figure5_3(;n = 100, vinit = 0.0f0)metadatashow_logsèdisabled®skip_as_script«code_folded$020131a1-c68b-403a-9c5e-944edb6220e9cell_id$020131a1-c68b-403a-9c5e-944edb6220e9codeKupdatevalue(::Weighted, q::T, g::T, w::T, c::T) where T<:Real = (g - q)*w/cmetadatashow_logsèdisabled®skip_as_script«code_folded$c23475f0-c5f0-49ce-a665-f93c8bda0474cell_id$c23475f0-c5f0-49ce-a665-f93c8bda0474codefunction make_blackjack_mdp()
	state_init() = BlackjackState(rand(12:21), rand(unique_cards), rand() > 0.5)

	#starting with an initial state, action, and policy, generate a trajectory for blackjack returning that and the reward
	function blackjackepisode(s0::BlackjackState, a0::BlackjackAction, π::Matrix{Float32})
		#given any valid state, the simulation results will be affected by whether or not the player has a natural.  This can only be the case when the player sum is 21 and the player has a usable ace.  However, even if this is the case, it is not necessarily a natural.  A natural would occur with (A, 10), (A, J), (A, Q), (A, K).  But the player could also have (A, A, 9), (A, A, 7, 2), (A, A, A, 8), (A, A, A, A, 7) and so forth.  Also, if the starting state has a sum less than 21 and a usable ace, then after further dealing the player could arrive at the state with a sum of 21 and a usable ace.  In that situation, the player would never have a natural, but state value will be updated nonetheless.  So the probabilities must match for sampling purposes meaning the reward sampled from the (sum=21, ua=true) player state must reflect the true probabilities.  This would be the case if the simulation is always started with zero cards and dealt, but how to do that when we pass the starting state into it?  Since the game can go on past this point, this starting state should be handled for initial card draws where the sum is less than 12.  All of the situations with a usuable ace, a sum of 21, and not having a player natural require the player having two or more aces without a face/10 card.  If the first two cards dealt are the aces, then this would be a sum of 12 and the player would need to hit for a subsequent state.  If the first two cards result in a sum of less than 12 such as 7,2 then the player would automatically receive an additional card with zero probability of a bust, so no policy is needed.  Once the first ace is dealt, the policy would be required to hit to draw a second ace.  So if we treat s0 as the initial deal, then the remainder of the simulation will cover all of the other cases where we arrive at a sum of 21 with a usable ace
		playernatural = (s0.sum == 21) && s0.ua
		splayer, statehistory, actionhistory = playersim(s0, a0, π)
		rewardbase = zeros(Float32, length(statehistory) - 1)
		finalr = if splayer > 21 
			#if the player goes bust, the game is lost regardless of the dealers actions
			-1.0f0
		else
			#generate hidden dealer card and final state
			(ds, dua) = addsum(0, false, deal())
			(ds, dua) = addsum(ds, dua, s0.upcard)
			dealernatural = ds == 21
			if playernatural
				Float32(!dealernatural)
			elseif dealernatural #not stated in book but used by authors in their code and matches actual blackjack rules
				-1.0f0
			else
				sdealer = dealer_sim(ds, dua)
				scoregame(splayer, sdealer)
			end
		end
		return (statehistory, actionhistory, push!(rewardbase, finalr))
	end

	
	MDP_Opaque(blackjackstates, blackjack_actions, state_init, blackjackepisode)
endmetadatashow_logsèdisabled®skip_as_script«code_folded$15925cc6-9605-4357-9c2a-cdfe54070989cell_id$15925cc6-9605-4357-9c2a-cdfe54070989codemd"""
Consider an implementation or ordinary importance sampling that updates $V(s)$ incrementally every time a $G$ value is observed for that state.  The equations should be similar to the incremental update rule previously derived for $V(s)$ without importance sampling.

Consider a sequence of returns $G_1, G_2, \dots , G_{n-1}$, all starting in the same state and each with a corresponding weight $W_i = \rho_{t_i:T(t_i)-1}$.  We wish to form the estimate

$V_n \dot= \frac{\sum_{k=1}^{n-1}W_k G_k}{n-1}, n \geq 2$

and keep it up-to-date as we obtain a single additional return $G_n$.  Observe that we can increment n by 1 to get an espression for V in terms of itself.

$V_{n+1} = \frac{\sum_{k=1}^n W_k G_k}{n} = \frac{W_n G_n + \sum_{k=1}^{n-1} W_k G_k}{n}$

Using the original formula for $V_n$, we can make the following substitution:

$\sum_{k=1}^{n-1} W_k G_k = (n-1)V_n$

which results in 

$V_{n+1} = \frac{W_n G_n + V_n (n-1)}{n} = V_n + \frac{W_n G_n - V_n}{n}$

So, to calculate the value function, we can simply apply the following update rule after obtaining new values for W and G:

$C \leftarrow C + 1$
$V \leftarrow V + \frac{WG-V}{C}$

which looks very similar to the ordinary average update rule but with the weight multiplied by G.  C just keeps a running total of the times the state was observed.  Note that C needs to be updated even in the case where W is 0 which is not the case for weighted importance sampling.  A similar inremental update rule is derived later for the weighted case as well as an algorithm for updating the action-value estimate using this method.  Below are code examples for calculating the value estimates for both weighted and normal importance sampling using the incremental implementation.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$be7c096c-cc8c-407b-8287-8fb2ee7150a7cell_id$be7c096c-cc8c-407b-8287-8fb2ee7150a7codemd"""
> ### *Exercise 5.3* 
> What is the backup diagram for Monte Carlo estimation of $q_\pi$

Similar to the $v_\pi$ diagram except the root is the s,a pair under consideration followed by the new state and the action taken along the trajectory.  The rewards are still accumulated to the end, just the start of the trajectory is a solid filled in circle that would contain the value for that s,a pair.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$9618a093-cdb7-4589-a783-de8e9021b705cell_id$9618a093-cdb7-4589-a783-de8e9021b705code,md"""
### Example 5.3: Solving Blackjack
"""metadatashow_logsèdisabled®skip_as_script«code_folded$fa49c253-e016-46a7-ba94-0e7448a7e0aecell_id$fa49c253-e016-46a7-ba94-0e7448a7e0aecodeOmd"""
> ### *Exercise 5.10* 
> Derive the weighted-average update rule (5.8) from (5.7).  Follow the pattern of the derivation of the unweighted rule (2.3).

Equation (5.7)

$V_{n} = \frac{\sum_{k=1}^{n-1} W_k G_k}{\sum_{k=1}^{n-1}W_k} \implies \sum_{k=1}^{n-1} W_k G_k = V_n \sum_{k=1}^{n-1} W_k \tag{a}$

or 

$V_{n+1} = \frac{\sum_{k=1}^{n} W_k G_k}{\sum_{k=1}^{n}W_k}$

now we can expand the expresion for $V_{n+1}$ to get an incremental rule

$\begin{flalign}
V_{n+1} &= \frac{W_n G_n + \sum_{k=1}^{n-1} W_k G_k}{\sum_{k=1}^{n}W_k} \\
&= \frac{W_n G_n + V_n \sum_{k=1}^{n-1}W_k}{\sum_{k=1}^{n}W_k} \tag{by (a)} \\
&= \frac{W_n G_n + V_n \sum_{k=1}^{n}W_k - V_n W_n}{\sum_{k=1}^{n}W_k} \\
&= V_n + W_n\frac{G_n - V_n}{\sum_{k=1}^{n}W_k}
\end{flalign}$

For a fully incremental rule we also have to replace the sum over $W_k$ which can simply be a running total.

$C_n = \sum_{k=1}^n W_k$

the following update rule will produce an equivalent $C_n$ assuming we take $C_0=0$

$C_n = C_{n-1} + W_n$

Now we can rewrite our last expression for $V_{n+1}$

$V_{n+1} = V_n + \frac{W_n}{C_n}(G_n - V_n)$
"""metadatashow_logsèdisabled®skip_as_script«code_folded$f41dd3e6-81bf-43e4-afc2-fc549b77f610cell_id$f41dd3e6-81bf-43e4-afc2-fc549b77f610coden(πstar2_racetrack2, Qstar2_racetrack2) = monte_carlo_ES(track2_mdp, 1.0f0, mces2; override_state_init = true)metadatashow_logsèdisabled®skip_as_script«code_folded$6d765229-2816-4abb-a868-6be919a96530cell_id$6d765229-2816-4abb-a868-6be919a96530code*const blackjack_mdp = make_blackjack_mdp()metadatashow_logsèdisabled®skip_as_script«code_folded$e7de31e8-ae95-4616-86a9-a115a5e24330cell_id$e7de31e8-ae95-4616-86a9-a115a5e24330code)const track2_mdp = make_track_mdp(track2)metadatashow_logsèdisabled®skip_as_script«code_folded$fff54c56-5afe-4d89-9dc5-502d08c89de9cell_id$fff54c56-5afe-4d89-9dc5-502d08c89de9code<make_col_set(x, ymin, ymax) = Set((x, y) for y in ymin:ymax)metadatashow_logsèdisabled®skip_as_script«code_folded$9793b5c9-d4ec-492d-a72d-8737bb65c8a5cell_id$9793b5c9-d4ec-492d-a72d-8737bb65c8a5code0md"""
Given a starting state $S_t$, the probability of the subsequent state-action trajectory, $A_t, S_{t+1}, A_{t+1}, \ldots ,S_T$, occuring under any policy $\pi$ is:

$Pr_{\pi}\{\mathcal{traj}\} = \prod_{k=t}^{T-1} \pi(A_k|S_k)p(S_{k+1}|S_k, A_k)$

where $p$ here is the state-transition probability function defined by (3.4).  Thus, the relative probability of the trajectory under the target and behavior policies (the importance-sampling ratio) is

$\rho_{t:T-1} \dot= \prod_{k=t}^{T-1}\frac{\pi(A_k|S_k)}{b(A_k|S_k)}$
To estimate $v_\pi(s)$, we simply scale the returns by the ratios and average the results:

$V(s) \dot= \frac{\sum_{t \in \mathscr{T}(s)} \rho_{t:T(t)-1}G_t}{|\mathscr{T}(s)|}$ 

When importance sampling is done as a simple average in this way it is called *ordinary importance sampling*.

An important alternative is *weighted importance sampling*, which uses a *weighted* average, defined as

$V(s) \dot= \frac{\sum_{t \in \mathscr{T}(s)} \rho_{t:T(t)-1}G_t}{\sum_{t \in \mathscr{T}(s)} \rho_{t:T(t)-1}}$,
or zero is the denominator is zero.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$1117e6c3-2736-46a4-bac2-d3c99c1998b6cell_id$1117e6c3-2736-46a4-bac2-d3c99c1998b6code@bind mcϵs2 confirm(PlutoUI.combine() do Child
	md"""
	| Number of Episodes | ϵ | Decay ϵ |
	| :-: | :-: | :-: |
	|$(Child(:episodes, NumberField(1:10_000_000, default = 1_000))) | $(Child(:ϵ, NumberField(0.001:0.001:1.0; default = 0.01))) | $(Child(:decay, CheckBox())) |
	"""
end)metadatashow_logsèdisabled®skip_as_script«code_folded$5948f670-1203-4b75-8517-f8470f5d01aacell_id$5948f670-1203-4b75-8517-f8470f5d01aacodefunction figure_5_4(expmax, nsims)
	nmax = 10^expmax
	function makeplotinds(expmax)
		plotinds = mapreduce(i -> i:min(i, 1000):i*9, vcat, 10 .^(0:expmax-1))
		vcat(plotinds, 10^(expmax))
	end

	plotinds = makeplotinds(expmax)

	vhistnormal = Vector{Vector{Float32}}(undef, nsims)
	@threads for i in 1:nsims
		vhistnormal[i] = monte_carlo_pred_V(onestate_π_target, onestate_π_b, onestate_mdp, 1.0f0; num_episodes = nmax, sampleinds = plotinds)[1]
	end
	# vhistnormal = [monte_carlo_pred(onestate_π_target, onestate_π_b, onestate_mdp, 1.0f0; num_episodes = nmax)[1][plotinds] for _ in 1:nsims]

	vhistweighted = monte_carlo_pred_V(onestate_π_target, onestate_π_b, onestate_mdp, 1.0f0; num_episodes = nmax, samplemethod = Weighted(), sampleinds = plotinds)[1]

	
	traces1 = [scatter(x = plotinds, y = vhist, showlegend = false) for vhist in vhistnormal]
	trace2 = scatter(x = plotinds, y = vhistweighted, name = "Weighted Importance Sampling", line_dash = "dash", line_width = 4)
	p = plot([traces1; trace2], Layout(yaxis_range = [0, 3], xaxis_type = "log", legend_orientation = "h", xaxis_title = "Episodes (log scale)", yaxis_title = attr(text = "Monte-Carlo estimate of <br> state value with <br> ordinary importance sampling ($nsims runs)", rotation = 90)))
	md"""
	### Figure 5.4
	Ordinary importance sampling produces surprisingly unstable estimates on the one-state MDP shown in Example 5.5.  The correct estimate here is 1 ($\gamma = 1$), and, even through this is the expected value of a sample return (after importance sampling), the variance of the samples is infinite, and the estimates do not converge to this value.  In contrast weighted importance samping produces the correct value of 1 after the first episode that ends with the left action.
	$p
	"""
	
	# p2 = plot(histogram(x = [v[end] for v in vhistnormal], showlegend = false))

	# [p p2]
	# traces2 = [scatter(x = plotinds, y = vhist) for vhist in vhistweighted]
	# p2 = plot(traces2, Layout(showlegend = false))
	# md"""
	# $p1
	# $p2
	# """
endmetadatashow_logsèdisabled®skip_as_script«code_folded$2ed88aa5-fc42-4a57-924d-e918805e2208cell_id$2ed88aa5-fc42-4a57-924d-e918805e2208codemd"""
##### Track 2
"""metadatashow_logsèdisabled®skip_as_script«code_folded$c9bd778c-217a-4664-8cde-841beca10307cell_id$c9bd778c-217a-4664-8cde-841beca10307code&@htl("""
<div>Reward = +1 on All Transitions</div>
<div style="display: flex; align-items: center; background-color: lightgray; color: black; height: 150px; width: 100px;">
<div class="backup" style="transform: scale(130%)">
	<div class="circlestate"></div>
	<div class="arrow"></div>
	<div class="term"></div>
</div>
<div>
	<div class="loop"></div>
	<div style="transform: translateY(-15px)">1-p</div>
</div>
</div>
<style>
	.loop {
		display: flex;
		border-width: 2px 0px 0px 2px;
		border-style: solid;
		border-color: black;
		width: 38px;
		height: 28px;
		border-radius: 50% 50% 50% 15%;
		transform: translateY(-30px) rotate(45deg);
	}
	.loop::before {
		content: '';
		position: relative;
		width: 5px;
		height: 5px;
		border-width: 0px 0px 3px 3px;
		border-style: solid;
		border-color: black;
		transform: translateX(-4px) translateY(17px) rotate(-45deg)
	}
	.loop::after {
		content: 'p';
		border-width: 0px 2px 2px 0px;
		border-style: solid;
		border-color: black;
		width: 38px;
		height: 28px;
		border-radius: 50% 50% 50% 0%;
	}
</style>
""")metadatashow_logsèdisabled®skip_as_script«code_folded$605b045d-fe5c-426b-9f55-b7dd1d037c50cell_id$605b045d-fe5c-426b-9f55-b7dd1d037c50codeAmd"""
Example trajectories after training for $mces1 episodes
"""metadatashow_logsèdisabled®skip_as_script«code_folded$88335fca-fd87-487b-9de2-ea7c779b54cfcell_id$88335fca-fd87-487b-9de2-ea7c779b54cfcode1md"""
## 5.9 Per-decision Importance Sampling
"""metadatashow_logsèdisabled®skip_as_script«code_folded$fd91d00a-f94f-40ff-88a7-9d85f05acc96cell_id$fd91d00a-f94f-40ff-88a7-9d85f05acc96code<make_row_set(xmin, xmax, y) = Set((x, y) for x in xmin:xmax)metadatashow_logsèdisabled®skip_as_script«code_folded$a59d9c84-d35f-4a9b-9fb6-13e30cdd7c3acell_id$a59d9c84-d35f-4a9b-9fb6-13e30cdd7c3acodemonte_carlo_pred_Q(π_blackjack1, π_rand_blackjack, blackjack_mdp, 1.0f0; num_episodes =  100000, historystateindex = blackjack_stateindex1, qinit = 0.0f0, override_state_init = true, samplemethod=Ordinary(), use_target_initial_action = true)[3] |> mean #mean weight is 2 and it stays this way as the number of episodes increases so the returns that are seen by the behavior are roughtly doubled and counted with the 0 returnsmetadatashow_logsèdisabled®skip_as_script«code_folded$df3c4a33-45f1-4cc2-8c06-d500a0eecc8fcell_id$df3c4a33-45f1-4cc2-8c06-d500a0eecc8fcode	#track is defined as a set of points for each of the start, body, and finish
const track1 = (  start = Set((x, 0) for x in 0:5), 
            finish = Set((13, y) for y in 26:31), 
            body = union(   Set((x, y) for x in 0:5 for y in 1:2),
                            Set((x, y) for x in -1:5 for y in 3:9),
                            Set((x, y) for x in -2:5 for y in 10:17),
                            Set((x, y) for x in -3:5 for y in 18:24),
                            Set((x, 25) for x in -3:6),
                            Set((x, y) for x in -3:12 for y in 26:27),
                            Set((x, 28) for x in -2:12),
                            Set((x, y) for x in -1:12 for y in 29:30),
                            Set((x, 31) for x in 0:12)),
        )metadatashow_logsèdisabled®skip_as_script«code_folded$e2fc1d47-2ee9-4844-a6b1-16f76531da86cell_id$e2fc1d47-2ee9-4844-a6b1-16f76531da86code@bind run3_2 Button("Run Race")metadatashow_logsèdisabled®skip_as_script«code_folded$2d36ebe3-1a86-4cad-a235-baec726da926cell_id$2d36ebe3-1a86-4cad-a235-baec726da926codemd"""
#### Example Random Trajectories on Each Track
The black arrows represent the velocity of the car at that position, and the red arrows show the policy action to change the velocity.  Note that only non-negative values are allowed for velocity to some of the actions have no impact.  Also, the car is not allowed by be stopped so if an action were to reduce the velocity to 0, then a random velocity of +1 will be assigned to either the x or y direction.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$dfc2d648-ec08-49cd-a55f-72a766cad728cell_id$dfc2d648-ec08-49cd-a55f-72a766cad728codeh(πstar1_racetrack1, Qstar1_racetrack1) = off_policy_MC_control(track1_mdp, 1.0f0; num_episodes = opmc1)metadatashow_logsèdisabled®skip_as_script«code_folded$7ee4e17e-c1a9-4df0-a014-114bebcb4f52cell_id$7ee4e17e-c1a9-4df0-a014-114bebcb4f52codemakegridsquare(x, y, vx, vy, dvx, dvy; class = "", xmin=0, ymin=0) = """<div class = "$class" vx = "$vx" vy = "$vy" dvx = "$dvx" dvy = "$dvy" style="grid-column-start: $(x - xmin + 1); grid-row-start: $(y - ymin + 1);"></div>"""metadatashow_logsèdisabled®skip_as_script«code_folded$2d10281a-a4af-4ea8-b63b-e11f2d0893edcell_id$2d10281a-a4af-4ea8-b63b-e11f2d0893edcodefunction make_greedy_policy!(v::AbstractVector{T}; c = 1000) where T<:Real
	(vmin, vmax) = extrema(v)
	if vmin == vmax
		v .= one(T) / length(v)
	else
		v .= (v .- vmax) ./ abs(vmin - vmax)
		v .= exp.(c .* v)
		v .= v ./ sum(v)
	end
	return v
endmetadatashow_logsèdisabled®skip_as_script«code_folded$e87932d9-fbc0-4ea5-a8ee-28eac5eed84fcell_id$e87932d9-fbc0-4ea5-a8ee-28eac5eed84fcode	{begin
	abstract type BlackjackAction end
	struct Hit <: BlackjackAction end
	struct Stick <: BlackjackAction end
	struct BlackjackState
		sum::Int64
		upcard::Int64
		ua::Bool
	end
	const cards = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]
	const unique_cards = collect(1:10)
	const blackjack_actions = [Hit(), Stick()]
	const blackjackstates = [BlackjackState(s, c, ua) for s in 12:21 for c in unique_cards for ua in (true, false)]
	const blackjack_statelookup = makelookup(blackjackstates)
	const π_blackjack_random = ones(Float32, 2, length(blackjackstates)) /2
	#deal a card from an infinite deck and return either the value of that card or an ace
	deal() = rand(cards)
	
	#takes a previous sum, usable ace indicator, and a card to be added to the sum.  Returns the updated sum and whether an ace is still usable
	function addsumace(s::Int64, ua::Bool)
		if !ua
			s >= 11 ? (s+1, false) : (s+11, true)
		else
			(s+1, true)
		end
	end

	function addsum(s::Int64, ua::Bool, c::Int64)
		c == 1 && return addsumace(s, ua)
		if !ua
			(s + c, false)
		else
			if (s + c) > 21
				(s + c - 10, false)
			else
				(s + c, true)
			end
		end
	end

	function dealer_sim(dealer_sum::Int64, dua::Bool)
		(dealer_sum >= 17) && return dealer_sum
		(new_sum, ua) = addsum(dealer_sum, dua, deal())
		dealer_sim(new_sum, ua)
	end

	playersim(state, ::Stick, π, statehistory, actionhistory) = (state.sum, statehistory, actionhistory)
	function playersim(state, ::Hit, π, statehistory, actionhistory)
		(s, ua) = addsum(state.sum, state.ua, deal())
		(s > 21) && return (s, statehistory, actionhistory)
		newstate = BlackjackState(s, state.upcard, ua)
		i_s = blackjack_statelookup[newstate]
		i_a = sample_action(π, i_s)
		newaction = blackjack_actions[i_a]
		playersim(newstate, newaction, π, push!(statehistory, newstate), push!(actionhistory, newaction))
	end
	playersim(state::BlackjackState, action::BlackjackAction, π::Matrix{Float32}) = playersim(state, action, π, [state], Vector{BlackjackAction}([action]))

	#score a game in which the player didn't go bust
	function scoregame(playersum, dealersum)
		#if the dealer goes bust, the player wins
		dealersum > 21 && return 1.0f0

		#if the player is closer to 21 the player wins
		playersum > dealersum && return 1.0f0

		#if the dealer sum is closer to 21 the player loses
		playersum < dealersum && return -1.0f0

		#otherwise the outcome is a draw
		return 0.0f0
	end
endmetadatashow_logsèdisabled®skip_as_script«code_folded$1cc46e33-6885-4d6f-805e-9ff928f1cf23cell_id$1cc46e33-6885-4d6f-805e-9ff928f1cf23code;const racetrackspeeds = unique(norm.(racetrack_velocities))metadatashow_logsèdisabled®skip_as_script«code_folded$f79d97bb-341a-46ad-bdfc-d080af13e2dfcell_id$f79d97bb-341a-46ad-bdfc-d080af13e2dfcode2md"""
#### Monte Carlo ϵ-Soft Solution Method
"""metadatashow_logsèdisabled®skip_as_script«code_folded$6a11daf7-2859-41fa-9c3d-d1f3580dbb5fcell_id$6a11daf7-2859-41fa-9c3d-d1f3580dbb5fcode$md"""
### Example 5.1: Blackjack
"""metadatashow_logsèdisabled®skip_as_script«code_folded$985f0537-2bbe-4dbb-a113-8ac98d2e0a5fcell_id$985f0537-2bbe-4dbb-a113-8ac98d2e0a5fcodelsampleracepolicy(create_policy_function(πstar3_racetrack1, track1_mdp); policyname = "Monte Carlo ϵ-Soft")metadatashow_logsèdisabled®skip_as_script«code_folded$217ecc59-d6e3-48fa-9d6d-700a3947b805cell_id$217ecc59-d6e3-48fa-9d6d-700a3947b805code[monte_carlo_pred_Q(π_blackjack1, π_rand_blackjack, blackjack_mdp, 1.0f0; num_episodes =  1, historystateindex = blackjack_stateindex1, qinit = 0.0f0, override_state_init = true, samplemethod=Ordinary(), use_target_initial_action = true)[3][1:1] |> sum for i in 1:1000] |> v -> mean(v)metadatashow_logsèdisabled®skip_as_script«code_folded$a35de859-4046-4f6d-9ea9-b523d21cee5dcell_id$a35de859-4046-4f6d-9ea9-b523d21cee5dcode function make_value_grid(v_π)
	vgridua = zeros(Float32, 10, 10)
	vgridnua = zeros(Float32, 10, 10)
	for (i_s, s) in enumerate(blackjackstates)
		if s.ua
			vgridua[s.sum-11, s.upcard] = v_π[i_s]
		else
			vgridnua[s.sum-11, s.upcard] = v_π[i_s]
		end
	end
	return vgridua, vgridnua
endmetadatashow_logsèdisabled®skip_as_script«code_folded$12c0cd0b-eb4f-45a0-836b-53b3c5cdafd9cell_id$12c0cd0b-eb4f-45a0-836b-53b3c5cdafd9code>md"""
## 5.5 Off-policy Prediction via Importance Sampling
"""metadatashow_logsèdisabled®skip_as_script«code_folded$aaa9647c-afb6-44d1-ae1e-a2e957064080cell_id$aaa9647c-afb6-44d1-ae1e-a2e957064080code#updates the denominator used in the value update.  For ordinary sampling, this is just the count of visits to that state.  For weighted sampling, this is the sum of all importance-sampling ratios at that state
updatecount(::Ordinary, w::T) where T<:Real = one(T)metadatashow_logsèdisabled®skip_as_script«code_folded$b57462b6-8f9c-4553-9c05-134ff043b00dcell_id$b57462b6-8f9c-4553-9c05-134ff043b00dcodemd"""
> ### *Exercise 5.9* 
> Modify the algorithm for first-visit MC policy evaluation (section 5.1) to use the incremental implementation for sample averages described in Section 2.4

Returns(s) will not maintain a list but instead be a list of single values for each state.  Additionally, another list Counts(s) should be initialized at 0 for each state.  When new G values are obtained for state, the Count(s) value should be incremented by 1.  Then Returns(s) can be updated with the following formula: 

$\begin{flalign}
	\text{Returns}(s) &= \left [ \text{Returns}(s) \times (\text{Counts}(s) - 1) + G \right ] / \text{Counts}(s) \\ 
	&= \text{Returns}(s) + \frac{G - \text{Returns}(s)}{\text{Counts}(s)}
\end{flalign}$
"""metadatashow_logsèdisabled®skip_as_script«code_folded$f506e8ba-b073-4f59-91b4-3fe99822d2a4cell_id$f506e8ba-b073-4f59-91b4-3fe99822d2a4codeXconst scalelookup = Dict(s => round(Int64, 150*(s / maxspeed)) for s in racetrackspeeds)metadatashow_logsèdisabled®skip_as_script«code_folded$bf19e6cf-1fb5-49c9-974e-1613d90ef4cfcell_id$bf19e6cf-1fb5-49c9-974e-1613d90ef4cfcodeb(πstar_blackjack2, Qstar_blackjack2) = monte_carlo_ϵsoft(blackjack_mdp, 0.1f0, 1.0f0, 1_000_000)metadatashow_logsèdisabled®skip_as_script«code_folded$77cf7fee-0ad8-4d22-b376-75833307db93cell_id$77cf7fee-0ad8-4d22-b376-75833307db93codeٌbegin
	using StatsBase, Statistics, PlutoUI, HypertextLiteral, LaTeXStrings, PlutoPlotly, Base.Threads, LinearAlgebra
	TableOfContents()
endmetadatashow_logsèdisabled®skip_as_script«code_folded$d11bfcf9-b964-4c67-afdc-53d81f051fd5cell_id$d11bfcf9-b964-4c67-afdc-53d81f051fd5code_function monte_carlo_pred_V(π_target::Matrix{T}, π_behavior::Matrix{T}, mdp::MDP_Opaque{S, A, F, G}, γ::T; num_episodes::Integer = 1000, vinit::T = zero(T), V::Vector{T} = ones(T, length(mdp.states)) .* vinit, historystateindex::Integer = 1, samplemethod::ImportanceMethod = Ordinary(), override_state_init::Bool = false, sampleinds = 1:num_episodes) where {T <: AbstractFloat, S, A, F, G}
	check_policy(π_target, mdp)
	check_policy(π_behavior, mdp)
	@assert all(x -> x != 0, π_behavior) #behavior policy must have full coverage
	
	#initialize
	counts = zeros(T, length(mdp.states))
	valuehistory = zeros(T, length(sampleinds))
	weighthistory = ones(T, length(sampleinds))
	sampleind = 1

	for i in 1:num_episodes
		#if only interested in one state then always initialize there
		s0 = override_state_init ? mdp.states[historystateindex] : mdp.state_init()
		i_a0 = sample_action(π_behavior, mdp.statelookup[s0])
		a0 = mdp.actions[i_a0]
		(states, actions, rewards) = mdp.simulator(s0, a0, π_behavior)
		#update value function for each trajectory
		w = updateV!(mdp, V, counts, π_target, π_behavior, states, actions, rewards, γ, samplemethod)

		#for selected state check value
		if i == sampleinds[sampleind]
			valuehistory[sampleind] = V[historystateindex]
			weighthistory[sampleind] = w
			sampleind += 1
		end
	end
	return valuehistory, V, weighthistory 
endmetadatashow_logsèdisabled®skip_as_script«code_folded$19e42f50-5301-41b9-becb-2368c26b6236cell_id$19e42f50-5301-41b9-becb-2368c26b6236code[monte_carlo_pred_Q(π_blackjack1, π_rand_blackjack, blackjack_mdp, 1.0f0; num_episodes =  10, historystateindex = blackjack_stateindex1, qinit = 0.0f0, override_state_init = true, samplemethod=Ordinary(), use_target_initial_action = true)[3] |> mean for i in 1:1000] |> v -> mean(v)metadatashow_logsèdisabled®skip_as_script«code_folded$924f4e74-e3a0-42eb-89da-1f9836275588cell_id$924f4e74-e3a0-42eb-89da-1f9836275588codefunction off_policy_MC_control(mdp::MDP_Opaque, γ::T; π_b::Matrix{T} = make_random_policy(mdp), num_episodes::Integer = 1000, qinit::T = zero(T)) where T<: AbstractFloat
	Q = initialize_state_action_value(mdp; qinit = qinit)
	counts = initialize_state_action_value(mdp; qinit = zero(T))
	π_star = create_greedy_policy(Q)
	vhold = zeros(T, length(mdp.actions))
	for i in 1:num_episodes
		s0 = mdp.state_init()
		i_a0 = sample_action(π_b, mdp.statelookup[s0])
		a0 = mdp.actions[i_a0]
		(states, actions, rewards) = mdp.simulator(s0, a0, π_b)

		g = zero(T)
		w = one(T)
		t = length(states)
		for t = length(states):-1:1
			g = γ*g + rewards[t]
			i_s = mdp.statelookup[states[t]]
			i_a = mdp.actionlookup[actions[t]]
			counts[i_a, i_s] += w
			Q[i_a, i_s] += (w/counts[i_a, i_s])*(g - Q[i_a, i_s])
			
			#update the target policy to be greedy at state s
			vhold .= Q[:, i_s]
			make_greedy_policy!(vhold)
			π_star[:, i_s] .= vhold
			
			#end episode if trajectory is no longer possible under target policy
			π_star[i_a, i_s] == 0 && break
			#note that here I replace the numerator with the probability under the target policy instead of 1.  That is because π_star here may be stochastic in the case of a tie
			w *= (π_star[i_a, i_s] / π_b[i_a, i_s])
		end
		# #there's no check here so this is equivalent to every-visit estimation
		# function update!(t = length(states); g = zero(T), w = one(T))
		# 	t == 0 && return nothing
		# 	g = γ*g + rewards[t]
		# 	i_s = mdp.statelookup[states[t]]
		# 	i_a = mdp.actionlookup[actions[t]]
		# 	counts[i_a, i_s] += w
		# 	Q[i_a, i_s] += (w/counts[i_a, i_s])*(g - Q[i_a, i_s])
			
		# 	#update the target policy to be greedy at state s
		# 	vhold .= Q[:, i_s]
		# 	make_greedy_policy!(vhold)
		# 	π_star[:, i_s] .= vhold
			
		# 	#end episode if trajectory is no longer possible under target policy
		# 	π_star[i_a, i_s] == 0 && return nothing
		# 	w /= π_b[i_a, i_s]
		# 	update!(t-1, g=g, w=w)
		# end
		# update!()
	end
	return π_star, Q
endmetadatashow_logsèdisabled®skip_as_script«code_folded$6dc0de46-2164-4580-b186-a73cb5b5167dcell_id$6dc0de46-2164-4580-b186-a73cb5b5167dcodew#given a position, velocity, and action takes a forward step in time and returns the new position, new velocity, and a set of points that represent the space covered in between
function project_path(p, v, a)
	(vx, vy) = v
    (dx, dy) = a

    vxnew = clamp(vx + dx, 0, 4)
    vynew = clamp(vy + dy, 0, 4)

    #both velocity components cannot be zero except when the race starts
    if (vxnew + vynew) == 0
        if rand() < 0.5
            vxnew += 1
        else
            vynew += 1
        end
    end

    #position the car ends up at
    pnew = (p[1] + vxnew, p[2] + vynew)

    #how to check if the path intersects the finish line or the boundary?  Form a square from vxnew and vynew and see if the off-track area or finish line is contained in that square
    pathsquares = Set((x, y) for x in p[1]:pnew[1] for y in p[2]:pnew[2])

    (pnew, (vxnew, vynew), pathsquares)
endmetadatashow_logsèdisabled®skip_as_script«code_folded$63814164-f305-49b3-ab51-675c822d7b18cell_id$63814164-f305-49b3-ab51-675c822d7b18codeCconst racetrack_velocities = [(vx, vy) for vx in 0:4 for vy in 0:4]metadatashow_logsèdisabled®skip_as_script«code_folded$4337b83f-b648-4b55-9d2a-4fffcf701111cell_id$4337b83f-b648-4b55-9d2a-4fffcf701111codehtml"""
	<style>
		main {
			margin: 0 auto;
			max-width: min(2000px, 90%);
	    	padding-left: max(10px, 5%);
	    	padding-right: max(10px, 5%);
			font-size: max(10px, min(18px, 2vw));
		}
	</style>
	"""metadatashow_logsèdisabled®skip_as_script«code_folded$1b78b25d-3942-4a6b-a2bd-7d97242da9fecell_id$1b78b25d-3942-4a6b-a2bd-7d97242da9fecodeLmonte_carlo_ES(mdp::MDP_Opaque, γ::T, num_episodes; Q_init::Matrix{T} = initialize_state_action_value(mdp; qinit = zero(T)), π_init::Matrix{T} = make_random_policy(mdp; init = one(T)), override_state_init = false) where T <: Real = monte_carlo_ES(mdp, π_init, Q_init, γ, num_episodes; override_state_init = override_state_init) metadatashow_logsèdisabled®skip_as_script«code_folded$9524a3f5-fca3-4ce9-b04d-0cb6c0cd0c90cell_id$9524a3f5-fca3-4ce9-b04d-0cb6c0cd0c90code#off policy control learns very slowly because each episode from the random policy takes thousands of steps to even finish the race.  Even after 1_000 episodes almost no learning has occured. 
begin
	run1_1
	showrace(track1, create_policy_function(πstar1_racetrack1, track1_mdp))
endmetadatashow_logsèdisabled®skip_as_script«code_folded$2ed0d4bb-bb6e-4adf-ad7c-8ddeb8c20b84cell_id$2ed0d4bb-bb6e-4adf-ad7c-8ddeb8c20b84codeq_offpol[2][:, blackjack_stateindex1] #the second value should converge to -0.27726 same as the value function for the policy that hits on this state.  The first value is the value of sticking on this state which should be lower since it is a worse actionmetadatashow_logsèdisabled®skip_as_script«code_folded$a0d61852-9942-42de-b554-572c4526a3a8cell_id$a0d61852-9942-42de-b554-572c4526a3a8code function make_track_mdp(track; maxsteps = Inf)
	states = [(position = p, velocity = v) for p in union(track.start, track.body) for v in racetrack_velocities]
	state_init() = (position = rand(track.start), velocity = (0, 0))

	statelookup = makelookup(states)
	function take_action(π, s)
		i_s = statelookup[s]
		i_a = sample_action(π, i_s)
		racetrack_actions[i_a]
	end
	
	simulator(s0, a0, π) = race_track_episode(s0, a0, s -> take_action(π, s), track, maxsteps = maxsteps)
	MDP_Opaque(states, racetrack_actions, state_init, simulator)
endmetadatashow_logsèdisabled®skip_as_script«code_folded$bb617e58-2700-4f0d-b8c8-3a266142fb70cell_id$bb617e58-2700-4f0d-b8c8-3a266142fb70codeBconst racetrack_actions = [(dx, dy) for dx in -1:1 for dy in -1:1]metadatashow_logsèdisabled®skip_as_script«code_folded$0d9c5d60-878a-45bb-8707-275cf10be41fcell_id$0d9c5d60-878a-45bb-8707-275cf10be41fcode@bind run2_2 Button("Run race")metadatashow_logsèdisabled®skip_as_script«code_folded$b6eac49e-6742-4594-87a5-821437846b0dcell_id$b6eac49e-6742-4594-87a5-821437846b0dcode.#using ordinary importance sampling calculates statistics on weights observed after n episodes of training including what percentage of weights are 0, 1, 2 etc...
function test(n)
	[monte_carlo_pred_Q(π_blackjack1, π_rand_blackjack, blackjack_mdp, 1.0f0; num_episodes =  n, historystateindex = blackjack_stateindex1, qinit = 0.0f0, override_state_init = true, samplemethod=Ordinary(), use_target_initial_action = true)[3][1:n] |> v -> n - sum(v .== 0) for _ in 1:10000] |> v -> (mean(v), median(v), mode(v), mean(v .== 0), mean(v .== 1), mean(v .== 2))
endmetadatashow_logsèdisabled®skip_as_script«code_folded$61d8cfc6-a50c-4546-9e1f-dc73d4764bb9cell_id$61d8cfc6-a50c-4546-9e1f-dc73d4764bb9code\#there's no check here so this is equivalent to every-visit estimation
function updateQ!(mdp, Q, counts, π_target::Matrix{T}, π_behavior::Matrix{T}, states, actions, rewards::Vector{T}, γ::T, samplemethod::ImportanceMethod; t = length(states), g_old = zero(T), w = one(T)) where T<:Real		

	#terminate at the end of a trajectory
	(t == 0) && return w
	
	if (w == zero(T)) && isa(samplemethod, Weighted) 
		return w
	end
	
	#accumulate future discounted returns
	g = γ*g_old + rewards[t]
	i_s = mdp.statelookup[states[t]]
	i_a = mdp.actionlookup[actions[t]]
	counts[i_a, i_s] += updatecount(samplemethod, w)
	Q[i_a, i_s] += updatevalue(samplemethod, Q[i_a, i_s], g, w, counts[i_a, i_s])
	updateQ!(mdp, Q, counts, π_target, π_behavior, states, actions, rewards, γ, samplemethod; t = t-1, g_old = g, w = w * π_target[i_a, i_s] / π_behavior[i_a, i_s])
endmetadatashow_logsèdisabled®skip_as_script«code_folded$847a074c-1d23-4de3-a039-322aeb9f7613cell_id$847a074c-1d23-4de3-a039-322aeb9f7613codetest(2)metadatashow_logsèdisabled®skip_as_script«code_folded$d2625507-4787-4b1c-9a91-108012e42cc7cell_id$d2625507-4787-4b1c-9a91-108012e42cc7codefunction make_rotation_style(vx, vy)
	((vx==0) && (vy==0)) && return """"""
	"""
	[vx='$vx'][vy='$vy']::before {
		content: '→';
		transform: rotate($(atand(vy, vx))deg) scale($(scalelookup[norm([vx, vy])])%);
	}
	"""
endmetadatashow_logsèdisabled®skip_as_script«code_folded$94be5289-bba7-4490-bdcd-0d217a31c665cell_id$94be5289-bba7-4490-bdcd-0d217a31c665code#calculate value function for blackjack policy π and save results in plot-ready grid form
function eval_blackjack_policy(π, episodes; γ=1f0)
	v_π = monte_carlo_pred_V(π, blackjack_mdp, γ; num_episodes = episodes)
	make_value_grid(v_π)
endmetadatashow_logsèdisabled®skip_as_script«code_folded$f7616806-97ab-4b09-accc-4e047691f879cell_id$f7616806-97ab-4b09-accc-4e047691f879code\#track is defined as a set of points for each of the start, body, and finish
const track2 = (  start = make_row_set(0, 22, 0), 
            finish = make_col_set(31, 21, 29), 
            body = union(   union((make_row_set(0, 22, y) for y in 1:2)...),
                            union((make_row_set(i, 22, y) for (i, y) in zip(1:14, 3:16))...),
							make_row_set(14, 23, 17),
							make_row_set(14, 25, 18),
							make_row_set(14, 26, 19),
							make_row_set(14, 29, 20),
							union((make_row_set(xstart, 31, y) for (xstart, y) in zip([13, 12, 11, 11, 11, 11, 12, 13, 16], 21:29))...))
        )metadatashow_logsèdisabled®skip_as_script«code_folded$70d9d39f-020d-4f25-810c-82a143a3335bcell_id$70d9d39f-020d-4f25-810c-82a143a3335bcode;const π_rand_blackjack = make_random_policy(blackjack_mdp)metadatashow_logsèdisabled®skip_as_script«code_folded$780f2fd9-49c3-48bc-b790-dde5be1dc81bcell_id$780f2fd9-49c3-48bc-b790-dde5be1dc81bcodetrack1_mdp.statesmetadatashow_logsèdisabled®skip_as_script«code_folded$833bb53c-bc2b-47fb-9429-d0f6d92efb42cell_id$833bb53c-bc2b-47fb-9429-d0f6d92efb42code@bind run1_1 Button("Run race")metadatashow_logsèdisabled®skip_as_script«code_folded$e370dbb3-3bd9-4dc8-b8ca-8aad8711905ccell_id$e370dbb3-3bd9-4dc8-b8ca-8aad8711905ccodeD@htl("""
<style>
	.track {
		display: grid;
		grid-gap: 0px;
		background-color: white;
		transform: rotateX(180deg);
	}

	.track * {
		width: 15px;
		height: 15px;
		border: 1px solid black;
		box-sizing: content-box;
		display: flex;
		justify-content: center;
		align-items: center;
	}

	[vx][vy][dvx][dvy]::before {
		display: flex;
		align-items: center;
		justify-content: center;
		position: absolute;
	}

	[vx][vy][dvx][dvy]::after {
		display: flex;
		align-items: center;
		justify-content: center;
		position: absolute;
	}

	.start {
		background-color: orange;
	}
	.finish {
		background-color: green;
	}

	[vx='0'][vy='0']::before {
		content: '•';
	}

	$(mapreduce(a -> make_rotation_style(a...), joinlines, racetrack_velocities)))
	$(mapreduce(a -> make_action_style(a...), joinlines, racetrack_actions)))
</style>
""")metadatashow_logsèdisabled®skip_as_script«code_folded$2646c9a2-46b1-4700-9290-ddc7dc9a59afcell_id$2646c9a2-46b1-4700-9290-ddc7dc9a59afcodeupdatecount(::Weighted, w) = wmetadatashow_logsèdisabled®skip_as_script«code_folded$892b5d8e-ac51-48f1-8288-65e9f68acd2dcell_id$892b5d8e-ac51-48f1-8288-65e9f68acd2dcode[monte_carlo_pred_V(π_blackjack1, π_rand_blackjack, blackjack_mdp, 1.0f0; num_episodes =  10, historystateindex = blackjack_stateindex1, vinit = 0.0f0, override_state_init = true, samplemethod=Ordinary())[3][1:10] |> sum for i in 1:1000] |> v -> (mean(v), count(v .== 0)/1000)
#for the target vs behavior policy, after one episode the mean weight including hte 0 values is about 2, let's say that all of these terminate in either 1 or -1.  Then we'd have a mean reward value of 2 or -2 which has a squared error of ~5 and 3 respectively depending on whether a win or loss is more likely since the denominator will be 1.  This is with ordinary importance sampling.  In contrast with weighted importance sampling the divisor will be 2 on average too and each estimate will be an actual return value experienced by the behavior policy or 0 for impossible trajectories.  Each of these will be worse than the 0 estimate.  About 72% of the episodes will have a 0 weight after the first episode but only 3.5% will not have any update after 10 episodes.  So for weighted importance sampling we have 72% 0 values and 28% the normal values.  The key difference is that for ordinary importance sampling the 28% of values that aren't zero have a weight of about 7 whereas for weighted sampling all the weights are 1 for the value estimate after normalization.  With an initial value estimate of 0, the squared error would be about 0.077.  Seeing the error for the weighted results after 1 episode on average, it is about 0.25 which is consistent with about 28% of the runs having error values of 0.52 or 1.63 instead of 0.77.  One thing I'm wondering though is why doesn't the error go up for Ordinary importance sampling after more of the episodes have non zero weighting.  Key point is that the initial value of V doesn't matter.  Some of the values are 0 just because the weighting is 0 and the corresponding denominator is still 1.  Remember that as the second episode is added it is likely that most of those values will get cut in half due to a 0 weight trajectory and the count going up.  Whereas for weighted sampling, all the 0's that get replaced will get worse while the others that have a new estimate won't be changed at all if they get a 0 weight trajectory.  This behavior policy seems to on average product a trajectory that is possible with the target policy only 28% of the time so the most likely thing is just replacing existing 0's and not changing the other estimates.  With normal importance sampling though, all those existing estimates will get cut in half and then some new ones will come in.  Also it is likely that each run would need 4 non zero samples before that estimate is better than the initial 0 value, so that explains why the weighted sampling error doesn't drop until after 10 episodes where the average number of non zero samples is higher than that. After 7 episodes the average number of non zero weight trajectories is 2.  At 10 episodes the median and mode non zero weights is 3metadatashow_logsèdisabled®skip_as_script«code_folded$acb08e38-fc87-43f4-ac2d-6c6bf0f2e9e6cell_id$acb08e38-fc87-43f4-ac2d-6c6bf0f2e9e6codevfunction estimate_mdp_state(mdp, π::Matrix{T}, stateindex, num_episodes) where T<:AbstractFloat
	staterewards = zeros(T, num_episodes)
	s0 = mdp.states[stateindex]
	for i in 1:num_episodes
		i_a0 = sample_action(π, stateindex)
		a0 = mdp.actions[i_a0]
		(states, actions, rewards) = mdp.simulator(s0, a0, π)
		staterewards[i] = last(rewards)
	end
	return staterewards
endmetadatashow_logsèdisabled®skip_as_script«code_folded$fca388bd-eb8b-41e2-8da0-87b9386629c1cell_id$fca388bd-eb8b-41e2-8da0-87b9386629c1code+md"""
## 5.6 Incremental Implementation
"""metadatashow_logsèdisabled®skip_as_script«code_foldedënotebook_id$c6e0de0c-3901-11f0-234e-bd09c571f662in_temp_dir¨metadata