• Home
  • Research
  • Experiments
  • CV
    • Work
    • Personal

Decomposer

  • Show All Code
  • Hide All Code

  • View Source

For information on this decomposition see: Jessie and Saari (2016)

Code
viewof page_orientation = Inputs.select(
    ["Portrait", "Landscape"],
    {value: "Portrait",
    label: html`<div class="orientation">Layout<span class="orientationtooltip">Specify layout of payoff tables</span></div>`,
    width: 120,
    }
)

set_page_orientation = {
    page_orientation;   
    var flex_container = document.getElementById("flex_container");
    var flex_container_parameters = document.getElementById("flex_container_parameters");
    var flex_container_options = document.getElementById("flex_container_options");
    var flex_container_payoffs = document.getElementById("flex_container_payoffs");
    var parameter_set_box = document.getElementById("parameter_set_box");
    var payoff_tables_box = document.getElementById("payoff_tables_box");
    var actions_set_box = document.getElementById("actions_set_box");
    var flex_container_action_set = document.getElementById("flex_container_action_set");
    var payoff_inputs_x = document.querySelector('[data-id="payoff_inputs_x"]');
    var payoff_inputs_y = document.querySelector('[data-id="payoff_inputs_y"]');
    if (page_orientation === "Portrait") {
        var page_layout = ["20%", "65%", "15%"];
        var flex_direction = "row";
        var flex_direction_alt = "column";
    } else if (page_orientation === "Landscape") {
        var page_layout = ["100%", "100%", "100%"];
        var flex_direction = "column";
        var flex_direction_alt = "row";
    }
    parameter_set_box.style.flexBasis = page_layout[0]; 
    payoff_tables_box.style.flexBasis = page_layout[1]; 
    actions_set_box.style.flexBasis = page_layout[2];
    flex_container_action_set.style.flexDirection = flex_direction_alt;
    flex_container.style.flexDirection = flex_direction;
    flex_container_parameters.style.flexDirection = flex_direction_alt;
    flex_container_options.style.flexDirection = flex_direction;
    // flex_container_payoffs.style.flexDirection = flex_direction;
}
Code
viewof dimensions = Inputs.select(
    ["---", "2x2", "2x3", "2x4", "3x2", "3x3", "3x4", "4x2", "4x3", "4x4"],
    {value: "---",
    label: html`<div class="dimensions">Dimensions<span class="dimensionstooltip">Specify dimensions of the payoff table: Number of Rows by Number of Columns</span></div>`,
    width: 70,
    }
)

viewof decimal_places = Inputs.number(
    [0, Infinity],
    {step: 1, 
    label: html`<div class="decimal">Decimal Places<span class="decimaltooltip">Specify max number of decimal places</span></div>`, 
    value: 3, 
    width: 70
    }
)
Code
viewof symmetrical = html`<form class="symmetric">${Object.assign(html`<span class="symmetrictooltip">Copy column player's payoffs to row player's payoffs</span><button type=button>Symmetrical Payoffs`, {onclick: event => event.currentTarget.dispatchEvent(new CustomEvent("input", {bubbles: true}))})}`
Code
viewof x_1_1 = Inputs.number(
    {step: 1, label: tex `x_{1,1}`, value: 0, width: 70
})

viewof x_1_2 = Inputs.number(
    {step: 1, label: tex `x_{1,2}`, value: 0, width: 70
})

viewof x_1_3 = Inputs.number(
    {step: 1, label: tex `x_{1,3}`, value: 0, width: 70
})

viewof x_1_4 = Inputs.number(
    {step: 1, label: tex `x_{1,4}`, value: 0, width: 70
})

viewof x_2_1 = Inputs.number(
    {step: 1, label: tex `x_{2,1}`, value: 0, width: 70
})

viewof x_2_2 = Inputs.number(
    {step: 1, label: tex `x_{2,2}`, value: 0, width: 70
})

viewof x_2_3 = Inputs.number(
    {step: 1, label: tex `x_{2,3}`, value: 0, width: 70
})

viewof x_2_4 = Inputs.number(
    {step: 1, label: tex `x_{2,4}`, value: 0, width: 70
})

viewof x_3_1 = Inputs.number(
    {step: 1, label: tex `x_{3,1}`, value: 0, width: 70
})

viewof x_3_2 = Inputs.number(
    {step: 1, label: tex `x_{3,2}`, value: 0, width: 70
})

viewof x_3_3 = Inputs.number(
    {step: 1, label: tex `x_{3,3}`, value: 0, width: 70
})

viewof x_3_4 = Inputs.number(
    {step: 1, label: tex `x_{3,4}`, value: 0, width: 70
})

viewof x_4_1 = Inputs.number(
    {step: 1, label: tex `x_{4,1}`, value: 0, width: 70
})

viewof x_4_2 = Inputs.number(
    {step: 1, label: tex `x_{4,2}`, value: 0, width: 70
})

viewof x_4_3 = Inputs.number(
    {step: 1, label: tex `x_{4,3}`, value: 0, width: 70
})

viewof x_4_4 = Inputs.number(
    {step: 1, label: tex `x_{4,4}`, value: 0, width: 70
})
Code
viewof y_1_1 = Inputs.number(
    {step: 1, label: tex `y_{1,1}`, value: 0, width: 70
})

viewof y_1_2 = Inputs.number(
    {step: 1, label: tex `y_{1,2}`, value: 0, width: 70
})

viewof y_1_3 = Inputs.number(
    {step: 1, label: tex `y_{1,3}`, value: 0, width: 70
})

viewof y_1_4 = Inputs.number(
    {step: 1, label: tex `y_{1,4}`, value: 0, width: 70
})

viewof y_2_1 = Inputs.number(
    {step: 1, label: tex `y_{2,1}`, value: 0, width: 70
})

viewof y_2_2 = Inputs.number(
    {step: 1, label: tex `y_{2,2}`, value: 0, width: 70
})

viewof y_2_3 = Inputs.number(
    {step: 1, label: tex `y_{2,3}`, value: 0, width: 70
})

viewof y_2_4 = Inputs.number(
    {step: 1, label: tex `y_{2,4}`, value: 0, width: 70
})

viewof y_3_1 = Inputs.number(
    {step: 1, label: tex `y_{3,1}`, value: 0, width: 70
})

viewof y_3_2 = Inputs.number(
    {step: 1, label: tex `y_{3,2}`, value: 0, width: 70
})

viewof y_3_3 = Inputs.number(
    {step: 1, label: tex `y_{3,3}`, value: 0, width: 70
})

viewof y_3_4 = Inputs.number(
    {step: 1, label: tex `y_{3,4}`, value: 0, width: 70
})

viewof y_4_1 = Inputs.number(
    {step: 1, label: tex `y_{4,1}`, value: 0, width: 70
})

viewof y_4_2 = Inputs.number(
    {step: 1, label: tex `y_{4,2}`, value: 0, width: 70
})

viewof y_4_3 = Inputs.number(
    {step: 1, label: tex `y_{4,3}`, value: 0, width: 70
})

viewof y_4_4 = Inputs.number(
    {step: 1, label: tex `y_{4,4}`, value: 0, width: 70
})

set_y_equal_x = {
    symmetrical;
    for (let i =  1; i <= 16; i++) {
        var y = document.getElementById(`oi-ec050e-${i}`); 
        var x = document.getElementById(`oi-ec050e-${i+16}`);
        if ((y.disabled == false) && (x.disabled == false)) {
            y.value = x.value;
        };
        y.dispatchEvent(new CustomEvent("input", {bubbles: true}))
    };
    
};
Code
{
    const rows = parseInt(dimensions[0]);
    const columns = parseInt(dimensions[2]);
    if (dimensions != "---") {
        var payoffs_x = [
        [x_1_1, x_1_2, x_1_3, x_1_4],
        [x_2_1, x_2_2, x_2_3, x_2_4],
        [x_3_1, x_3_2, x_3_3, x_3_4],
        [x_4_1, x_4_2, x_4_3, x_4_4]
        ];
        var payoffs_y = [
        [y_1_1, y_1_2, y_1_3, y_1_4],
        [y_2_1, y_2_2, y_2_3, y_2_4],
        [y_3_1, y_3_2, y_3_3, y_3_4],
        [y_4_1, y_4_2, y_4_3, y_4_4]
        ];
        var actions_x = [Action_1_row, Action_2_row, Action_3_row, Action_4_row];
        var actions_y = [Action_1_col, Action_2_col, Action_3_col, Action_4_col];
    };
    let payoff_table = `<table class="payoff_table">`;
    if (page_orientation === "Landscape") {
        payoff_table += "<tr></tr>";
    }
    payoff_table += "<tr>";
    if (page_orientation === "Portrait") {
        payoff_table += `<th class="component_title" rowspan="${rows+1}"></th>`;
    }
    payoff_table += `<th class="payoff_table_head"></th>`;
    for (let c = 1; c < (columns+1); c++) {
        payoff_table += `<th class="payoff_table_head_column" style="color: ${Column_Color}">${actions_y[c-1]}</th>`;
    }
    payoff_table += `<th class="component_title" rowspan="${rows+1}"></th>`;
    payoff_table += "</tr>";
    for (let r = 0; r < rows; r++) {
        payoff_table += "<tr>";
        payoff_table += `<th class="payoff_table_head_row" style="color: ${Row_Color}">${actions_x[r]}</th>`;
        for (let c = 1; c < (columns+1); c++) {
            payoff_table +=`<td class="payoff_table_data"><span style="color: ${Row_Color}">${payoffs_x[r][(c-1)]}</span>, <span style="color: ${Column_Color}">${payoffs_y[(c-1)][r]}</span></td>`;
        };
    };
    payoff_table += "</tr>";
    payoff_table += "</table>";
    for (let i = 1; i <= 16; i++) {
        var y_payoffs = document.getElementById(`oi-ec050e-${i}`)
        var x_payoffs = document.getElementById(`oi-ec050e-${16+i}`)
        if (rows == 2) {
            document.getElementById("column_action_1").disabled = false;
            document.getElementById("column_action_2").disabled = false;
            document.getElementById("row_action_1").disabled = false;
            document.getElementById("row_action_2").disabled = false;
            document.getElementById("row_action_3").disabled = true;
            document.getElementById("row_action_4").disabled = true;
            if (columns == 2) {
                document.getElementById("column_action_3").disabled = true;
                document.getElementById("column_action_4").disabled = true;
                if ((i == 11) || (i == 12) || (i == 15) || (i == 16)) {
                    x_payoffs.disabled = false;
                    y_payoffs.disabled = false;
                } else {
                    x_payoffs.disabled = true;
                    y_payoffs.disabled = true;
                };
            } else if (columns == 3) {
                document.getElementById("column_action_3").disabled = false;
                document.getElementById("column_action_4").disabled = true;
                if ((i == 11) || (i == 12) || (i == 15) || (i == 16)) {
                    x_payoffs.disabled = false;
                    y_payoffs.disabled = false;
                } else if ((i == 10) || (i == 14)) {
                    x_payoffs.disabled = false;
                    y_payoffs.disabled = true;
                } else if ((i == 7) || (i == 8)) {
                    y_payoffs.disabled = false;
                    x_payoffs.disabled = true;
                } else {
                    x_payoffs.disabled = true;
                    y_payoffs.disabled = true;
                };
            } else if (columns == 4) {
                document.getElementById("column_action_3").disabled = false;
                document.getElementById("column_action_4").disabled = false;
                if ((i == 11) || (i == 12) || (i == 15) || (i == 16)) {
                    x_payoffs.disabled = false;
                } else if ((i == 9) || (i == 10) || (i == 13) || (i == 14)) {
                    x_payoffs.disabled = false;
                    y_payoffs.disabled = true;
                } else if ((i == 3) || (i == 4) || (i == 7) || (i == 8)) {
                    y_payoffs.disabled = false;
                    x_payoffs.disabled = true;
                } else {
                    x_payoffs.disabled = true;
                    y_payoffs.disabled = true;
                };
            };

        } else if (rows == 3) {
            document.getElementById("column_action_1").disabled = false;
            document.getElementById("column_action_2").disabled = false;
            document.getElementById("row_action_1").disabled = false;
            document.getElementById("row_action_2").disabled = false;
            document.getElementById("row_action_3").disabled = false;
            document.getElementById("row_action_4").disabled = true;
            if (columns == 2) {
                document.getElementById("column_action_3").disabled = true;
                document.getElementById("column_action_4").disabled = true;
                if ((i == 11) || (i == 12) || (i == 15) || (i == 16)) {
                    x_payoffs.disabled = false;
                    y_payoffs.disabled = false;
                } else if ((i == 7) || (i == 8)) {
                    x_payoffs.disabled = false;
                    y_payoffs.disabled = true;
                } else if ((i == 10) || (i == 14)) {
                    y_payoffs.disabled = false;
                    x_payoffs.disabled = true;
                } else {
                    x_payoffs.disabled = true;
                    y_payoffs.disabled = true;
                };
            } else if (columns == 3) {
                document.getElementById("column_action_3").disabled = false;
                document.getElementById("column_action_4").disabled = true;
                if ((i == 6) || (i == 7) || (i == 8) || (i == 10) || (i == 11) || (i == 12) || (i == 14) || (i == 15) || (i == 16)) {
                    x_payoffs.disabled = false;
                    y_payoffs.disabled = false;
                }  else {
                    x_payoffs.disabled = true;
                    y_payoffs.disabled = true;
                };
            } else if (columns == 4) {
                document.getElementById("column_action_3").disabled = false;
                document.getElementById("column_action_4").disabled = false;
                if ((i == 6) || (i == 7) || (i == 8) ||(i == 10) || (i == 11) || (i == 12) ||(i == 14) || (i == 15) || (i == 16)) {
                    x_payoffs.disabled = false;
                    y_payoffs.disabled = false;
                } else if ((i == 5) || (i == 9) || (i == 13)) {
                    x_payoffs.disabled = false;
                    y_payoffs.disabled = true;
                } else if ((i == 2) || (i == 3) || (i == 4)) {
                    y_payoffs.disabled = false;
                    x_payoffs.disabled = true;
                } else {
                    x_payoffs.disabled = true;
                    y_payoffs.disabled = true;
                };
            };

        } else if (rows == 4) {
            document.getElementById("column_action_1").disabled = false;
            document.getElementById("column_action_2").disabled = false;
            document.getElementById("row_action_1").disabled = false;
            document.getElementById("row_action_2").disabled = false;
            document.getElementById("row_action_3").disabled = false;
            document.getElementById("row_action_4").disabled = false;
            if (columns == 2) {
                document.getElementById("column_action_3").disabled = true;
                document.getElementById("column_action_4").disabled = true;
                if ((i == 11) || (i == 12) || (i == 15) || (i == 16)) {
                    x_payoffs.disabled = false;
                    y_payoffs.disabled = false;
                } else if ((i == 3) || (i == 4) || (i == 7) || (i == 8)) {
                    x_payoffs.disabled = false;
                    y_payoffs.disabled = true;
                } else if ((i == 9) || (i == 10) || (i == 13) || (i == 14)) {
                    y_payoffs.disabled = false;
                    x_payoffs.disabled = true;
                } else {
                    x_payoffs.disabled = true;
                    y_payoffs.disabled = true;
                };
            } else if (columns == 3) {
                document.getElementById("column_action_3").disabled = false;
                document.getElementById("column_action_4").disabled = true;
                if ((i == 6) || (i == 7) || (i == 8) || (i == 10) || (i == 11) || (i == 12) || (i == 14) || (i == 15) || (i == 16)) {
                    x_payoffs.disabled = false;
                    y_payoffs.disabled = false;
                } else if ((i == 2) || (i == 3) || (i == 4)) {
                    x_payoffs.disabled = false;
                    y_payoffs.disabled = true;
                } else if ((i == 5) || (i == 9) || (i == 13)) {
                    y_payoffs.disabled = false;
                    x_payoffs.disabled = true;
                } else {
                    x_payoffs.disabled = true;
                    y_payoffs.disabled = true;
                };
            } else if (columns == 4) {
                document.getElementById("column_action_3").disabled = false;
                document.getElementById("column_action_4").disabled = false;
                x_payoffs.disabled = false;
                y_payoffs.disabled = false;
            };
        } else if (dimensions == "---") {
            x_payoffs.disabled = true;
            y_payoffs.disabled = true;
            document.getElementById("column_action_1").disabled = true;
            document.getElementById("column_action_2").disabled = true;
            document.getElementById("column_action_3").disabled = true;
            document.getElementById("column_action_4").disabled = true;
            document.getElementById("row_action_1").disabled = true;
            document.getElementById("row_action_2").disabled = true;
            document.getElementById("row_action_3").disabled = true;
            document.getElementById("row_action_4").disabled = true;
        };
    };

    if (dimensions != "---") {
        var payoffs_x = [
            [x_1_1, x_1_2, x_1_3, x_1_4],
            [x_2_1, x_2_2, x_2_3, x_2_4],
            [x_3_1, x_3_2, x_3_3, x_3_4],
            [x_4_1, x_4_2, x_4_3, x_4_4]
        ];

        var payoffs_y = [
            [y_1_1, y_1_2, y_1_3, y_1_4],
            [y_2_1, y_2_2, y_2_3, y_2_4],
            [y_3_1, y_3_2, y_3_3, y_3_4],
            [y_4_1, y_4_2, y_4_3, y_4_4]
        ];

        var actions_x = [Action_1_row, Action_2_row, Action_3_row, Action_4_row];
        var actions_y = [Action_1_col, Action_2_col, Action_3_col, Action_4_col];

        var payoffs_x_subset = [];
        var payoffs_y_subset = [];
        for (let r = 0; r < rows; r++) {
            payoffs_x_subset=payoffs_x_subset.concat([payoffs_x[r].slice(0, columns)]);
        };

        for (let c = 0; c < columns; c++) {
            payoffs_y_subset=payoffs_y_subset.concat([payoffs_y[c].slice(0, rows)]);
        };

        var x_strat_mean = [];
        for (let c = 0; c < columns; c++) {
            var x_strat_c = 0;
            for (let r = 0; r < rows; r++) {
                x_strat_c += payoffs_x_subset[r][c];
            };
            var x_strats = [];
            var x_strats_mean = x_strat_c/rows;
            x_strat_mean=x_strat_mean.concat(x_strats_mean);
        };

        var y_strat_mean = [];
        for (let r = 0; r < rows; r++) {
            var y_strat_c = 0;
            for (let c = 0; c < columns; c++) {
                y_strat_c += payoffs_y_subset[c][r];
            }
            var y_strats = [];
            var y_strats_mean = y_strat_c/columns;
            y_strat_mean=y_strat_mean.concat(y_strats_mean);
        };

        var strat_x = [];
        var strat_y = [];
        var kappa_x = [];
        var kappa_y = [];
        var x_mean = x_strat_mean.reduce((partialSum, a) => partialSum + a, 0) / columns;
        var x_mean_str = String(x_mean);
        if (x_mean_str.includes('.')) {
            x_mean = parseFloat(x_mean.toFixed(decimal_places));
        };

        var y_mean = y_strat_mean.reduce((partialSum, a) => partialSum + a, 0) / rows;
        var y_mean_str = String(y_mean);
        if (y_mean_str.includes('.')) {
            y_mean = parseFloat(y_mean.toFixed(decimal_places));
        };

        for (let r = 0; r < rows; r++) {
            var strats_x = [];
            var kappas_x = [];
            for (let c = 0; c < columns; c++) {
                var strat_x_r_c = payoffs_x_subset[r][c]-x_strat_mean[c];
                var strat_x_r_c_str = String(strat_x_r_c);
                if (strat_x_r_c_str.includes('.')) {
                    strat_x_r_c = parseFloat(strat_x_r_c.toFixed(decimal_places))
                }
                strats_x = strats_x.concat(strat_x_r_c);
                kappas_x = kappas_x.concat(x_mean);
            }
            strat_x = strat_x.concat([strats_x]);
            kappa_x = kappa_x.concat([kappas_x]);
        };
        
        for (let c = 0; c < columns; c++) {
            var strats_y = [];
            var kappas_y = [];
            for (let r = 0; r < rows; r++) {
                var strat_y_r_c = payoffs_y_subset[c][r]-y_strat_mean[r];
                var strat_y_r_c_str = String(strat_y_r_c);
                if (strat_y_r_c_str.includes('.')) {
                    strat_y_r_c = parseFloat(strat_y_r_c.toFixed(decimal_places))
                }
                strats_y = strats_y.concat(strat_y_r_c);
                kappas_y = kappas_y.concat(y_mean);
            }
            strat_y = strat_y.concat([strats_y]);
            kappa_y = kappa_y.concat([kappas_y]);
        };

        var behav_x = [];
        var x_behav_means= [];
        for (let c = 0; c < columns; c++) {
            var x_behav_sum_c = 0;
            for (let r = 0; r < rows; r++) {
                x_behav_sum_c += payoffs_x_subset[r][c];
            };
            var x_behav_mean_c = x_behav_sum_c/rows;
            x_behav_means = x_behav_means.concat(x_behav_mean_c);
        };

        var behav_y = [];
        var y_behav_means= [];
        for (let r = 0; r < rows; r++) {
            var y_behav_sum_c = 0;
            for (let c = 0; c < columns; c++) {
                y_behav_sum_c += payoffs_y_subset[c][r];
            };
            var y_behav_mean_c = y_behav_sum_c/columns;
            y_behav_means = y_behav_means.concat(y_behav_mean_c);
        };

        var x_behav_means_mean = x_behav_means.reduce((partialSum, a) => partialSum + a, 0) / (columns);
        var x_behav = [];
        for (let c = 0; c < columns; c++) {
            var x_behav_c = x_behav_means[c]-x_behav_means_mean;
            var x_behav_c_str = String(x_behav_c);
                if (x_behav_c_str.includes('.')) {
                    x_behav_c = parseFloat(x_behav_c.toFixed(decimal_places))
                };
            x_behav = x_behav.concat(x_behav_c);
        };
        
        var y_behav_means_mean = y_behav_means.reduce((partialSum, a) => partialSum + a, 0) / (rows);
        var y_behav = [];
        for (let r = 0; r < rows; r++) {
            var y_behav_c = y_behav_means[r]-y_behav_means_mean;
            var y_behav_c_str = String(y_behav_c);
                if (y_behav_c_str.includes('.')) {
                    y_behav_c = parseFloat(y_behav_c.toFixed(decimal_places))
                };
            y_behav = y_behav.concat(y_behav_c);
        };

        for (let r = 0; r < rows; r++) {
            behav_x = behav_x.concat([x_behav]);
        };

        for (let c = 0; c < columns; c++) {
            behav_y = behav_y.concat([y_behav]);
        };

        var comp_names = ["Strategic", "Behavioural", "Kernel"];
    } else {
        var comp_names = ["", "", ""];
    }
    let strategic = `<table class="payoff_table">`;
    if (page_orientation === "Landscape") {
        strategic += "<tr>";
        strategic += `<th colspan="${columns+1}" style="text-align:center">${comp_names[0]}</th>`;
        strategic += "</tr>";
    }
    strategic += "<tr>";
    if (page_orientation === "Portrait") {
        strategic += `<th class="component_title" rowspan="${rows+1}">${comp_names[0]}</th>`;
    }
    strategic += `<th class="payoff_table_head"></th>`;
    for (let c = 1; c < (columns+1); c++) {
        strategic += `<th class="payoff_table_head_column" style="color: ${Column_Color}">${actions_y[c-1]}</th>`;
    }
    strategic += `<th class="component_title" rowspan="${rows+1}"></th>`;
    strategic += "</tr>";
    for (let r = 0; r < rows; r++) {
        strategic += "<tr>";
        strategic += `<th class="payoff_table_head_row" style="color: ${Row_Color}">${actions_x[r]}</th>`;
        for (let c = 1; c < (columns+1); c++) {
            strategic +=`<td class="payoff_table_data"><span style="color: ${Row_Color}">${strat_x[r][(c-1)]}</span>, <span style="color: ${Column_Color}">${strat_y[(c-1)][r]}</span></td>`;
        }
    }
    
    strategic += "</tr>";
    strategic += "</table>";

    let behavioural = `<table class="payoff_table">`;
    if (page_orientation === "Landscape") {
        behavioural += "<tr>";
        behavioural += `<th colspan="${columns+1}" style="text-align:center">${comp_names[1]}</th>`;
        behavioural += "</tr>";
    }
    behavioural += "<tr>";
    if (page_orientation === "Portrait") {
        behavioural += `<th class="component_title" rowspan="${rows+1}">${comp_names[1]}</th>`;
    }
    behavioural += `<th class="payoff_table_head"></th>`;
    for (let c = 1; c < (columns+1); c++) {
        behavioural += `<th class="payoff_table_head_column" style="color: ${Column_Color}">${actions_y[c-1]}</th>`;
    }
    behavioural += `<th class="component_title" rowspan="${rows+1}"></th>`;
    behavioural += "</tr>";
    for (let r = 0; r < rows; r++) {
        behavioural += "<tr>";
        behavioural += `<th class="payoff_table_head_row" style="color: ${Row_Color}">${actions_x[r]}</th>`;
        for (let c = 1; c < (columns+1); c++) {
            behavioural +=`<td class="payoff_table_data"><span style="color: ${Row_Color}">${behav_x[r][(c-1)]}</span>, <span style="color: ${Column_Color}">${behav_y[(c-1)][r]}</span></td>`;
        }
    }
    behavioural += "</tr>";
    behavioural += "</table>";
    
    let kernel = `<table class="payoff_table">`;
    if (page_orientation === "Landscape") {
        kernel += "<tr>";
        kernel += `<th colspan="${columns+1}" style="text-align:center">${comp_names[2]}</th>`;
        kernel += "</tr>";
    }
    kernel += "<tr>";
    if (page_orientation === "Portrait") {
        kernel += `<th class="component_title" rowspan="${rows+1}">${comp_names[2]}</th>`;
    }
    kernel += `<th class="payoff_table_head"></th>`;
    for (let c = 1; c < (columns+1); c++) {
        kernel += `<th class="payoff_table_head_column" style="color: ${Column_Color}">${actions_y[c-1]}</th>`;
    }
    if (page_orientation === "Portrait") {
        kernel += `<th class="component_title" rowspan="${rows+1}"></th>`;
    }
    kernel += "</tr>";
    for (let r = 0; r < rows; r++) {
        kernel += "<tr>";
        kernel += `<th class="payoff_table_head_row" style="color: ${Row_Color}">${actions_x[r]}</th>`;
        for (let c = 1; c < (columns+1); c++) {
                kernel +=`<td class="payoff_table_data"><span style="color: ${Row_Color}">${kappa_x[r][(c-1)]}</span>, <span style="color: ${Column_Color}">${kappa_y[(c-1)][r]}</span></td>`;
        }
    }
    kernel += "</tr>";
    kernel += "</table>";
    if (page_orientation === "Portrait") {
        return html`${payoff_table}<div style="height: 50px"></div>${strategic}<div style="height: 15px"></div>${behavioural}<div style="height: 15px"></div>${kernel}`;
    } else if (page_orientation === "Landscape") {
        return html`${payoff_table}${strategic}${behavioural}${kernel}`
    }
}
Code
html`<span class="sidebar_title">Row Actions</span><br>`
Code
viewof Action_1_row = html`<input type="text" name="text" id="row_action_1" value="Action 1" style="width:100%; height:30px; margin-bottom: 5px">`

viewof Action_2_row = html`<input type="text" name="text" id="row_action_2" value="Action 2" style="width:100%; height:30px; margin-bottom: 5px">`

viewof Action_3_row = html`<input type="text" name="text" id="row_action_3" value="Action 3" style="width:100%; height:30px; margin-bottom: 5px">`

viewof Action_4_row = html`<input type="text" name="text" id="row_action_4" value="Action 4" style="width:100%; height:30px; margin-bottom: 5px">`

viewof Row_Color = html`<input type="color" id="column_color" value="#00008b" class="color_input">`
Code
html`<span class="sidebar_title">Column Actions</span>`
Code
viewof Action_1_col = html`<input type="text" name="text" id="column_action_1" value="Action 1" style="width:100%; height:30px; margin-bottom: 5px">`

viewof Action_2_col = html`<input type="text" name="text" id="column_action_2" value="Action 2" style="width:100%; height:30px; margin-bottom: 5px">`

viewof Action_3_col = html`<input type="text" name="text" id="column_action_3" value="Action 3" style="width:100%; height:30px; margin-bottom: 5px">`

viewof Action_4_col = html`<input type="text" name="text" id="column_action_4" value="Action 4" style="width:100%; height:30px; margin-bottom: 5px">`

viewof Column_Color = html`<input type="color" id="column_color" value="#8b0000" class="color_input">`
Code
viewof save_to_pdf = html`<form class="save_to_pdf">${Object.assign(html`<button type=button>Save to PDF`, {onclick: event => event.currentTarget.dispatchEvent(new CustomEvent("input", {bubbles: true}))})}`

viewof save_to_png = html`<form class="save_to_png">${Object.assign(html`<button type=button>Save to PNG`, {onclick: event => event.currentTarget.dispatchEvent(new CustomEvent("input", {bubbles: true}))})}`

viewof save_to_jpeg = html`<form class="save_to_jpeg">${Object.assign(html`<button type=button>Save to JPEG`, {onclick: event => event.currentTarget.dispatchEvent(new CustomEvent("input", {bubbles: true}))})}`

viewof save_to_html = html`<form class="save_to_jpeg">${Object.assign(html`<button type=button>Save to HTML`, {onclick: event => event.currentTarget.dispatchEvent(new CustomEvent("input", {bubbles: true}))})}`

viewof copy_to_clipboard = html`<form class="copy_to_clipboard">${Object.assign(html`<button type=button>Copy to Clipboard`, {onclick: event => event.currentTarget.dispatchEvent(new CustomEvent("input", {bubbles: true}))})}`
Code
html2canvas = require("html2canvas")
save_to_pdf_function = {
    save_to_pdf;
    var element = document.getElementById('ojs-cell-6');
    var opt = {
        margin: 1,
        filename: "decomp.pdf",
        image: { type: 'jpeg', quality: 0.98 },
        html2canvas: { scale: 2 },
        jsPDF: { unit: 'in', format: 'letter', orientation: 'portrait' }
    };
    html2pdf().set(opt).from(element).save();
}

save_to_png_function = {
    save_to_png;
    var element = document.getElementById('ojs-cell-6');
    html2canvas(element).then(canvas => {
        canvas.toBlob(function(blob) {
            window.saveAs(blob, "decomposition.png")
        });
    });
    
}

save_to_jpeg_function = {
    save_to_jpeg;
    var element = document.getElementById('ojs-cell-6');
    html2canvas(element).then(canvas => {
        canvas.toBlob(function(blob) {
            window.saveAs(blob, "decomposition.jpeg")
        });
    });
    
}

save_to_html_function = {
    save_to_html;
    var element = document.getElementById('ojs-cell-6');
    html2canvas(element).then(canvas => {
        canvas.toBlob(function(blob) {
            window.saveAs(blob, "decomposition.html")
        });
    });
}

copy_to_clipboard_function = {
    copy_to_clipboard;
    var element = document.getElementById('ojs-cell-6');
    var range = document.createRange();
    range.selectNode(element);
    window.getSelection().removeAllRanges();
    window.getSelection().addRange(range);
    document.execCommand("copy"); //note: execCommand is depreciated, but no good alternative yet
    window.getSelection().removeAllRanges();

    // navigator.clipboard.writeText(element);
}
Source Code
---
title: "Decomposer"
bibliography: references.bib
link-citations: true
link-bibliography: true
format: 
    html:
        code-tools: true
        code-fold: true
        hmtl-math-method: mathjax
        smooth-scroll: true
        self-contained: true
        page-layout: custom
jupyter: python3
editor_options: 
  chunk_output_type: inline
execute:
    echo: false
---
<head>
<!-- Remote Stylesheet -->

<link rel="stylesheet" href="decomposer-styles.css"> <!-- embedded Stylesheet -->

```{=html}
<style>
    #content {
      display: block;
    }

    .internal {
       display: block;
    }
</style>
<!-- jsPDF library -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.9.3/html2pdf.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.0/FileSaver.min.js"></script>

```

<div style="width: 100%; overflow: hidden">

<div style="float: left">

For information on this decomposition see: @Jessie_Saari_2016

</div>

<div style="float: right">

```{ojs}
//| echo: false

viewof page_orientation = Inputs.select(
    ["Portrait", "Landscape"],
    {value: "Portrait",
    label: html`<div class="orientation">Layout<span class="orientationtooltip">Specify layout of payoff tables</span></div>`,
    width: 120,
    }
)

set_page_orientation = {
    page_orientation;   
    var flex_container = document.getElementById("flex_container");
    var flex_container_parameters = document.getElementById("flex_container_parameters");
    var flex_container_options = document.getElementById("flex_container_options");
    var flex_container_payoffs = document.getElementById("flex_container_payoffs");
    var parameter_set_box = document.getElementById("parameter_set_box");
    var payoff_tables_box = document.getElementById("payoff_tables_box");
    var actions_set_box = document.getElementById("actions_set_box");
    var flex_container_action_set = document.getElementById("flex_container_action_set");
    var payoff_inputs_x = document.querySelector('[data-id="payoff_inputs_x"]');
    var payoff_inputs_y = document.querySelector('[data-id="payoff_inputs_y"]');
    if (page_orientation === "Portrait") {
        var page_layout = ["20%", "65%", "15%"];
        var flex_direction = "row";
        var flex_direction_alt = "column";
    } else if (page_orientation === "Landscape") {
        var page_layout = ["100%", "100%", "100%"];
        var flex_direction = "column";
        var flex_direction_alt = "row";
    }
    parameter_set_box.style.flexBasis = page_layout[0]; 
    payoff_tables_box.style.flexBasis = page_layout[1]; 
    actions_set_box.style.flexBasis = page_layout[2];
    flex_container_action_set.style.flexDirection = flex_direction_alt;
    flex_container.style.flexDirection = flex_direction;
    flex_container_parameters.style.flexDirection = flex_direction_alt;
    flex_container_options.style.flexDirection = flex_direction;
    // flex_container_payoffs.style.flexDirection = flex_direction;
}

```

</div>

</div>

</head>

<body>

<div class="quarto-layout-row quarto-layout-valign-top" id="flex_container" style="flexDirection: row">

<div class="quarto-layout-panel quarto-layout-cell" style="justify-content: center; flexBasis: 20%" id="parameter_set_box">

<div class="quarto-layout-row quarto-layout-valign-top" id="flex_container_parameters" style="flexDirection: column">

<div class="quarto-layout-panel quarto-layout-cell" style="justify-content: center; flex-basis: 10%; margin: 0px">

<div class="quarto-layout-row quarto-layout-valign-top" id="flex_container_options" style="flexDirection: row">

<div class="quarto-layout-cell" style="margin-bottom: 20px">

```{ojs}
//| panel: sidebar
viewof dimensions = Inputs.select(
    ["---", "2x2", "2x3", "2x4", "3x2", "3x3", "3x4", "4x2", "4x3", "4x4"],
    {value: "---",
    label: html`<div class="dimensions">Dimensions<span class="dimensionstooltip">Specify dimensions of the payoff table: Number of Rows by Number of Columns</span></div>`,
    width: 70,
    }
)

viewof decimal_places = Inputs.number(
    [0, Infinity],
    {step: 1, 
    label: html`<div class="decimal">Decimal Places<span class="decimaltooltip">Specify max number of decimal places</span></div>`, 
    value: 3, 
    width: 70
    }
)
```

</div>

<div class="quarto-layout-cell">

```{ojs}
//| panel: sidebar
viewof symmetrical = html`<form class="symmetric">${Object.assign(html`<span class="symmetrictooltip">Copy column player's payoffs to row player's payoffs</span><button type=button>Symmetrical Payoffs`, {onclick: event => event.currentTarget.dispatchEvent(new CustomEvent("input", {bubbles: true}))})}`
```

</div>

</div>

</div>

<div class="quarto-layout-panel quarto-layout-cell" style="justify-content: center; flex-basis: 90%">

<div class="quarto-layout-row quarto-layout-valign-top" id="flex_container_payoffs">

<div class="quarto-layout-cell" style="margin-bottom: 20px">


```{ojs}
//| panel: sidebar
//| id: payoff_inputs_x
//| style: 'flex-direction:row; flex-wrap: wrap'
viewof x_1_1 = Inputs.number(
    {step: 1, label: tex `x_{1,1}`, value: 0, width: 70
})

viewof x_1_2 = Inputs.number(
    {step: 1, label: tex `x_{1,2}`, value: 0, width: 70
})

viewof x_1_3 = Inputs.number(
    {step: 1, label: tex `x_{1,3}`, value: 0, width: 70
})

viewof x_1_4 = Inputs.number(
    {step: 1, label: tex `x_{1,4}`, value: 0, width: 70
})

viewof x_2_1 = Inputs.number(
    {step: 1, label: tex `x_{2,1}`, value: 0, width: 70
})

viewof x_2_2 = Inputs.number(
    {step: 1, label: tex `x_{2,2}`, value: 0, width: 70
})

viewof x_2_3 = Inputs.number(
    {step: 1, label: tex `x_{2,3}`, value: 0, width: 70
})

viewof x_2_4 = Inputs.number(
    {step: 1, label: tex `x_{2,4}`, value: 0, width: 70
})

viewof x_3_1 = Inputs.number(
    {step: 1, label: tex `x_{3,1}`, value: 0, width: 70
})

viewof x_3_2 = Inputs.number(
    {step: 1, label: tex `x_{3,2}`, value: 0, width: 70
})

viewof x_3_3 = Inputs.number(
    {step: 1, label: tex `x_{3,3}`, value: 0, width: 70
})

viewof x_3_4 = Inputs.number(
    {step: 1, label: tex `x_{3,4}`, value: 0, width: 70
})

viewof x_4_1 = Inputs.number(
    {step: 1, label: tex `x_{4,1}`, value: 0, width: 70
})

viewof x_4_2 = Inputs.number(
    {step: 1, label: tex `x_{4,2}`, value: 0, width: 70
})

viewof x_4_3 = Inputs.number(
    {step: 1, label: tex `x_{4,3}`, value: 0, width: 70
})

viewof x_4_4 = Inputs.number(
    {step: 1, label: tex `x_{4,4}`, value: 0, width: 70
})

```

</div>

<div class="quarto-layout-cell">

```{ojs}
//| panel: sidebar
//| id: payoff_inputs_y
//| style: 'flex-direction:row; flex-wrap: wrap'
viewof y_1_1 = Inputs.number(
    {step: 1, label: tex `y_{1,1}`, value: 0, width: 70
})

viewof y_1_2 = Inputs.number(
    {step: 1, label: tex `y_{1,2}`, value: 0, width: 70
})

viewof y_1_3 = Inputs.number(
    {step: 1, label: tex `y_{1,3}`, value: 0, width: 70
})

viewof y_1_4 = Inputs.number(
    {step: 1, label: tex `y_{1,4}`, value: 0, width: 70
})

viewof y_2_1 = Inputs.number(
    {step: 1, label: tex `y_{2,1}`, value: 0, width: 70
})

viewof y_2_2 = Inputs.number(
    {step: 1, label: tex `y_{2,2}`, value: 0, width: 70
})

viewof y_2_3 = Inputs.number(
    {step: 1, label: tex `y_{2,3}`, value: 0, width: 70
})

viewof y_2_4 = Inputs.number(
    {step: 1, label: tex `y_{2,4}`, value: 0, width: 70
})

viewof y_3_1 = Inputs.number(
    {step: 1, label: tex `y_{3,1}`, value: 0, width: 70
})

viewof y_3_2 = Inputs.number(
    {step: 1, label: tex `y_{3,2}`, value: 0, width: 70
})

viewof y_3_3 = Inputs.number(
    {step: 1, label: tex `y_{3,3}`, value: 0, width: 70
})

viewof y_3_4 = Inputs.number(
    {step: 1, label: tex `y_{3,4}`, value: 0, width: 70
})

viewof y_4_1 = Inputs.number(
    {step: 1, label: tex `y_{4,1}`, value: 0, width: 70
})

viewof y_4_2 = Inputs.number(
    {step: 1, label: tex `y_{4,2}`, value: 0, width: 70
})

viewof y_4_3 = Inputs.number(
    {step: 1, label: tex `y_{4,3}`, value: 0, width: 70
})

viewof y_4_4 = Inputs.number(
    {step: 1, label: tex `y_{4,4}`, value: 0, width: 70
})

set_y_equal_x = {
    symmetrical;
    for (let i =  1; i <= 16; i++) {
        var y = document.getElementById(`oi-ec050e-${i}`); 
        var x = document.getElementById(`oi-ec050e-${i+16}`);
        if ((y.disabled == false) && (x.disabled == false)) {
            y.value = x.value;
        };
        y.dispatchEvent(new CustomEvent("input", {bubbles: true}))
    };
    
};
```

</div>

</div>

</div>

</div>

</div>

<div class="quarto-layout-panel quarto-layout-cell" style="justify-content: center; min-height: 350px; margin: auto; flexBasis: 65%" id="payoff_tables_box">

```{ojs}
{
    const rows = parseInt(dimensions[0]);
    const columns = parseInt(dimensions[2]);
    if (dimensions != "---") {
        var payoffs_x = [
        [x_1_1, x_1_2, x_1_3, x_1_4],
        [x_2_1, x_2_2, x_2_3, x_2_4],
        [x_3_1, x_3_2, x_3_3, x_3_4],
        [x_4_1, x_4_2, x_4_3, x_4_4]
        ];
        var payoffs_y = [
        [y_1_1, y_1_2, y_1_3, y_1_4],
        [y_2_1, y_2_2, y_2_3, y_2_4],
        [y_3_1, y_3_2, y_3_3, y_3_4],
        [y_4_1, y_4_2, y_4_3, y_4_4]
        ];
        var actions_x = [Action_1_row, Action_2_row, Action_3_row, Action_4_row];
        var actions_y = [Action_1_col, Action_2_col, Action_3_col, Action_4_col];
    };
    let payoff_table = `<table class="payoff_table">`;
    if (page_orientation === "Landscape") {
        payoff_table += "<tr></tr>";
    }
    payoff_table += "<tr>";
    if (page_orientation === "Portrait") {
        payoff_table += `<th class="component_title" rowspan="${rows+1}"></th>`;
    }
    payoff_table += `<th class="payoff_table_head"></th>`;
    for (let c = 1; c < (columns+1); c++) {
        payoff_table += `<th class="payoff_table_head_column" style="color: ${Column_Color}">${actions_y[c-1]}</th>`;
    }
    payoff_table += `<th class="component_title" rowspan="${rows+1}"></th>`;
    payoff_table += "</tr>";
    for (let r = 0; r < rows; r++) {
        payoff_table += "<tr>";
        payoff_table += `<th class="payoff_table_head_row" style="color: ${Row_Color}">${actions_x[r]}</th>`;
        for (let c = 1; c < (columns+1); c++) {
            payoff_table +=`<td class="payoff_table_data"><span style="color: ${Row_Color}">${payoffs_x[r][(c-1)]}</span>, <span style="color: ${Column_Color}">${payoffs_y[(c-1)][r]}</span></td>`;
        };
    };
    payoff_table += "</tr>";
    payoff_table += "</table>";
    for (let i = 1; i <= 16; i++) {
        var y_payoffs = document.getElementById(`oi-ec050e-${i}`)
        var x_payoffs = document.getElementById(`oi-ec050e-${16+i}`)
        if (rows == 2) {
            document.getElementById("column_action_1").disabled = false;
            document.getElementById("column_action_2").disabled = false;
            document.getElementById("row_action_1").disabled = false;
            document.getElementById("row_action_2").disabled = false;
            document.getElementById("row_action_3").disabled = true;
            document.getElementById("row_action_4").disabled = true;
            if (columns == 2) {
                document.getElementById("column_action_3").disabled = true;
                document.getElementById("column_action_4").disabled = true;
                if ((i == 11) || (i == 12) || (i == 15) || (i == 16)) {
                    x_payoffs.disabled = false;
                    y_payoffs.disabled = false;
                } else {
                    x_payoffs.disabled = true;
                    y_payoffs.disabled = true;
                };
            } else if (columns == 3) {
                document.getElementById("column_action_3").disabled = false;
                document.getElementById("column_action_4").disabled = true;
                if ((i == 11) || (i == 12) || (i == 15) || (i == 16)) {
                    x_payoffs.disabled = false;
                    y_payoffs.disabled = false;
                } else if ((i == 10) || (i == 14)) {
                    x_payoffs.disabled = false;
                    y_payoffs.disabled = true;
                } else if ((i == 7) || (i == 8)) {
                    y_payoffs.disabled = false;
                    x_payoffs.disabled = true;
                } else {
                    x_payoffs.disabled = true;
                    y_payoffs.disabled = true;
                };
            } else if (columns == 4) {
                document.getElementById("column_action_3").disabled = false;
                document.getElementById("column_action_4").disabled = false;
                if ((i == 11) || (i == 12) || (i == 15) || (i == 16)) {
                    x_payoffs.disabled = false;
                } else if ((i == 9) || (i == 10) || (i == 13) || (i == 14)) {
                    x_payoffs.disabled = false;
                    y_payoffs.disabled = true;
                } else if ((i == 3) || (i == 4) || (i == 7) || (i == 8)) {
                    y_payoffs.disabled = false;
                    x_payoffs.disabled = true;
                } else {
                    x_payoffs.disabled = true;
                    y_payoffs.disabled = true;
                };
            };

        } else if (rows == 3) {
            document.getElementById("column_action_1").disabled = false;
            document.getElementById("column_action_2").disabled = false;
            document.getElementById("row_action_1").disabled = false;
            document.getElementById("row_action_2").disabled = false;
            document.getElementById("row_action_3").disabled = false;
            document.getElementById("row_action_4").disabled = true;
            if (columns == 2) {
                document.getElementById("column_action_3").disabled = true;
                document.getElementById("column_action_4").disabled = true;
                if ((i == 11) || (i == 12) || (i == 15) || (i == 16)) {
                    x_payoffs.disabled = false;
                    y_payoffs.disabled = false;
                } else if ((i == 7) || (i == 8)) {
                    x_payoffs.disabled = false;
                    y_payoffs.disabled = true;
                } else if ((i == 10) || (i == 14)) {
                    y_payoffs.disabled = false;
                    x_payoffs.disabled = true;
                } else {
                    x_payoffs.disabled = true;
                    y_payoffs.disabled = true;
                };
            } else if (columns == 3) {
                document.getElementById("column_action_3").disabled = false;
                document.getElementById("column_action_4").disabled = true;
                if ((i == 6) || (i == 7) || (i == 8) || (i == 10) || (i == 11) || (i == 12) || (i == 14) || (i == 15) || (i == 16)) {
                    x_payoffs.disabled = false;
                    y_payoffs.disabled = false;
                }  else {
                    x_payoffs.disabled = true;
                    y_payoffs.disabled = true;
                };
            } else if (columns == 4) {
                document.getElementById("column_action_3").disabled = false;
                document.getElementById("column_action_4").disabled = false;
                if ((i == 6) || (i == 7) || (i == 8) ||(i == 10) || (i == 11) || (i == 12) ||(i == 14) || (i == 15) || (i == 16)) {
                    x_payoffs.disabled = false;
                    y_payoffs.disabled = false;
                } else if ((i == 5) || (i == 9) || (i == 13)) {
                    x_payoffs.disabled = false;
                    y_payoffs.disabled = true;
                } else if ((i == 2) || (i == 3) || (i == 4)) {
                    y_payoffs.disabled = false;
                    x_payoffs.disabled = true;
                } else {
                    x_payoffs.disabled = true;
                    y_payoffs.disabled = true;
                };
            };

        } else if (rows == 4) {
            document.getElementById("column_action_1").disabled = false;
            document.getElementById("column_action_2").disabled = false;
            document.getElementById("row_action_1").disabled = false;
            document.getElementById("row_action_2").disabled = false;
            document.getElementById("row_action_3").disabled = false;
            document.getElementById("row_action_4").disabled = false;
            if (columns == 2) {
                document.getElementById("column_action_3").disabled = true;
                document.getElementById("column_action_4").disabled = true;
                if ((i == 11) || (i == 12) || (i == 15) || (i == 16)) {
                    x_payoffs.disabled = false;
                    y_payoffs.disabled = false;
                } else if ((i == 3) || (i == 4) || (i == 7) || (i == 8)) {
                    x_payoffs.disabled = false;
                    y_payoffs.disabled = true;
                } else if ((i == 9) || (i == 10) || (i == 13) || (i == 14)) {
                    y_payoffs.disabled = false;
                    x_payoffs.disabled = true;
                } else {
                    x_payoffs.disabled = true;
                    y_payoffs.disabled = true;
                };
            } else if (columns == 3) {
                document.getElementById("column_action_3").disabled = false;
                document.getElementById("column_action_4").disabled = true;
                if ((i == 6) || (i == 7) || (i == 8) || (i == 10) || (i == 11) || (i == 12) || (i == 14) || (i == 15) || (i == 16)) {
                    x_payoffs.disabled = false;
                    y_payoffs.disabled = false;
                } else if ((i == 2) || (i == 3) || (i == 4)) {
                    x_payoffs.disabled = false;
                    y_payoffs.disabled = true;
                } else if ((i == 5) || (i == 9) || (i == 13)) {
                    y_payoffs.disabled = false;
                    x_payoffs.disabled = true;
                } else {
                    x_payoffs.disabled = true;
                    y_payoffs.disabled = true;
                };
            } else if (columns == 4) {
                document.getElementById("column_action_3").disabled = false;
                document.getElementById("column_action_4").disabled = false;
                x_payoffs.disabled = false;
                y_payoffs.disabled = false;
            };
        } else if (dimensions == "---") {
            x_payoffs.disabled = true;
            y_payoffs.disabled = true;
            document.getElementById("column_action_1").disabled = true;
            document.getElementById("column_action_2").disabled = true;
            document.getElementById("column_action_3").disabled = true;
            document.getElementById("column_action_4").disabled = true;
            document.getElementById("row_action_1").disabled = true;
            document.getElementById("row_action_2").disabled = true;
            document.getElementById("row_action_3").disabled = true;
            document.getElementById("row_action_4").disabled = true;
        };
    };

    if (dimensions != "---") {
        var payoffs_x = [
            [x_1_1, x_1_2, x_1_3, x_1_4],
            [x_2_1, x_2_2, x_2_3, x_2_4],
            [x_3_1, x_3_2, x_3_3, x_3_4],
            [x_4_1, x_4_2, x_4_3, x_4_4]
        ];

        var payoffs_y = [
            [y_1_1, y_1_2, y_1_3, y_1_4],
            [y_2_1, y_2_2, y_2_3, y_2_4],
            [y_3_1, y_3_2, y_3_3, y_3_4],
            [y_4_1, y_4_2, y_4_3, y_4_4]
        ];

        var actions_x = [Action_1_row, Action_2_row, Action_3_row, Action_4_row];
        var actions_y = [Action_1_col, Action_2_col, Action_3_col, Action_4_col];

        var payoffs_x_subset = [];
        var payoffs_y_subset = [];
        for (let r = 0; r < rows; r++) {
            payoffs_x_subset=payoffs_x_subset.concat([payoffs_x[r].slice(0, columns)]);
        };

        for (let c = 0; c < columns; c++) {
            payoffs_y_subset=payoffs_y_subset.concat([payoffs_y[c].slice(0, rows)]);
        };

        var x_strat_mean = [];
        for (let c = 0; c < columns; c++) {
            var x_strat_c = 0;
            for (let r = 0; r < rows; r++) {
                x_strat_c += payoffs_x_subset[r][c];
            };
            var x_strats = [];
            var x_strats_mean = x_strat_c/rows;
            x_strat_mean=x_strat_mean.concat(x_strats_mean);
        };

        var y_strat_mean = [];
        for (let r = 0; r < rows; r++) {
            var y_strat_c = 0;
            for (let c = 0; c < columns; c++) {
                y_strat_c += payoffs_y_subset[c][r];
            }
            var y_strats = [];
            var y_strats_mean = y_strat_c/columns;
            y_strat_mean=y_strat_mean.concat(y_strats_mean);
        };

        var strat_x = [];
        var strat_y = [];
        var kappa_x = [];
        var kappa_y = [];
        var x_mean = x_strat_mean.reduce((partialSum, a) => partialSum + a, 0) / columns;
        var x_mean_str = String(x_mean);
        if (x_mean_str.includes('.')) {
            x_mean = parseFloat(x_mean.toFixed(decimal_places));
        };

        var y_mean = y_strat_mean.reduce((partialSum, a) => partialSum + a, 0) / rows;
        var y_mean_str = String(y_mean);
        if (y_mean_str.includes('.')) {
            y_mean = parseFloat(y_mean.toFixed(decimal_places));
        };

        for (let r = 0; r < rows; r++) {
            var strats_x = [];
            var kappas_x = [];
            for (let c = 0; c < columns; c++) {
                var strat_x_r_c = payoffs_x_subset[r][c]-x_strat_mean[c];
                var strat_x_r_c_str = String(strat_x_r_c);
                if (strat_x_r_c_str.includes('.')) {
                    strat_x_r_c = parseFloat(strat_x_r_c.toFixed(decimal_places))
                }
                strats_x = strats_x.concat(strat_x_r_c);
                kappas_x = kappas_x.concat(x_mean);
            }
            strat_x = strat_x.concat([strats_x]);
            kappa_x = kappa_x.concat([kappas_x]);
        };
        
        for (let c = 0; c < columns; c++) {
            var strats_y = [];
            var kappas_y = [];
            for (let r = 0; r < rows; r++) {
                var strat_y_r_c = payoffs_y_subset[c][r]-y_strat_mean[r];
                var strat_y_r_c_str = String(strat_y_r_c);
                if (strat_y_r_c_str.includes('.')) {
                    strat_y_r_c = parseFloat(strat_y_r_c.toFixed(decimal_places))
                }
                strats_y = strats_y.concat(strat_y_r_c);
                kappas_y = kappas_y.concat(y_mean);
            }
            strat_y = strat_y.concat([strats_y]);
            kappa_y = kappa_y.concat([kappas_y]);
        };

        var behav_x = [];
        var x_behav_means= [];
        for (let c = 0; c < columns; c++) {
            var x_behav_sum_c = 0;
            for (let r = 0; r < rows; r++) {
                x_behav_sum_c += payoffs_x_subset[r][c];
            };
            var x_behav_mean_c = x_behav_sum_c/rows;
            x_behav_means = x_behav_means.concat(x_behav_mean_c);
        };

        var behav_y = [];
        var y_behav_means= [];
        for (let r = 0; r < rows; r++) {
            var y_behav_sum_c = 0;
            for (let c = 0; c < columns; c++) {
                y_behav_sum_c += payoffs_y_subset[c][r];
            };
            var y_behav_mean_c = y_behav_sum_c/columns;
            y_behav_means = y_behav_means.concat(y_behav_mean_c);
        };

        var x_behav_means_mean = x_behav_means.reduce((partialSum, a) => partialSum + a, 0) / (columns);
        var x_behav = [];
        for (let c = 0; c < columns; c++) {
            var x_behav_c = x_behav_means[c]-x_behav_means_mean;
            var x_behav_c_str = String(x_behav_c);
                if (x_behav_c_str.includes('.')) {
                    x_behav_c = parseFloat(x_behav_c.toFixed(decimal_places))
                };
            x_behav = x_behav.concat(x_behav_c);
        };
        
        var y_behav_means_mean = y_behav_means.reduce((partialSum, a) => partialSum + a, 0) / (rows);
        var y_behav = [];
        for (let r = 0; r < rows; r++) {
            var y_behav_c = y_behav_means[r]-y_behav_means_mean;
            var y_behav_c_str = String(y_behav_c);
                if (y_behav_c_str.includes('.')) {
                    y_behav_c = parseFloat(y_behav_c.toFixed(decimal_places))
                };
            y_behav = y_behav.concat(y_behav_c);
        };

        for (let r = 0; r < rows; r++) {
            behav_x = behav_x.concat([x_behav]);
        };

        for (let c = 0; c < columns; c++) {
            behav_y = behav_y.concat([y_behav]);
        };

        var comp_names = ["Strategic", "Behavioural", "Kernel"];
    } else {
        var comp_names = ["", "", ""];
    }
    let strategic = `<table class="payoff_table">`;
    if (page_orientation === "Landscape") {
        strategic += "<tr>";
        strategic += `<th colspan="${columns+1}" style="text-align:center">${comp_names[0]}</th>`;
        strategic += "</tr>";
    }
    strategic += "<tr>";
    if (page_orientation === "Portrait") {
        strategic += `<th class="component_title" rowspan="${rows+1}">${comp_names[0]}</th>`;
    }
    strategic += `<th class="payoff_table_head"></th>`;
    for (let c = 1; c < (columns+1); c++) {
        strategic += `<th class="payoff_table_head_column" style="color: ${Column_Color}">${actions_y[c-1]}</th>`;
    }
    strategic += `<th class="component_title" rowspan="${rows+1}"></th>`;
    strategic += "</tr>";
    for (let r = 0; r < rows; r++) {
        strategic += "<tr>";
        strategic += `<th class="payoff_table_head_row" style="color: ${Row_Color}">${actions_x[r]}</th>`;
        for (let c = 1; c < (columns+1); c++) {
            strategic +=`<td class="payoff_table_data"><span style="color: ${Row_Color}">${strat_x[r][(c-1)]}</span>, <span style="color: ${Column_Color}">${strat_y[(c-1)][r]}</span></td>`;
        }
    }
    
    strategic += "</tr>";
    strategic += "</table>";

    let behavioural = `<table class="payoff_table">`;
    if (page_orientation === "Landscape") {
        behavioural += "<tr>";
        behavioural += `<th colspan="${columns+1}" style="text-align:center">${comp_names[1]}</th>`;
        behavioural += "</tr>";
    }
    behavioural += "<tr>";
    if (page_orientation === "Portrait") {
        behavioural += `<th class="component_title" rowspan="${rows+1}">${comp_names[1]}</th>`;
    }
    behavioural += `<th class="payoff_table_head"></th>`;
    for (let c = 1; c < (columns+1); c++) {
        behavioural += `<th class="payoff_table_head_column" style="color: ${Column_Color}">${actions_y[c-1]}</th>`;
    }
    behavioural += `<th class="component_title" rowspan="${rows+1}"></th>`;
    behavioural += "</tr>";
    for (let r = 0; r < rows; r++) {
        behavioural += "<tr>";
        behavioural += `<th class="payoff_table_head_row" style="color: ${Row_Color}">${actions_x[r]}</th>`;
        for (let c = 1; c < (columns+1); c++) {
            behavioural +=`<td class="payoff_table_data"><span style="color: ${Row_Color}">${behav_x[r][(c-1)]}</span>, <span style="color: ${Column_Color}">${behav_y[(c-1)][r]}</span></td>`;
        }
    }
    behavioural += "</tr>";
    behavioural += "</table>";
    
    let kernel = `<table class="payoff_table">`;
    if (page_orientation === "Landscape") {
        kernel += "<tr>";
        kernel += `<th colspan="${columns+1}" style="text-align:center">${comp_names[2]}</th>`;
        kernel += "</tr>";
    }
    kernel += "<tr>";
    if (page_orientation === "Portrait") {
        kernel += `<th class="component_title" rowspan="${rows+1}">${comp_names[2]}</th>`;
    }
    kernel += `<th class="payoff_table_head"></th>`;
    for (let c = 1; c < (columns+1); c++) {
        kernel += `<th class="payoff_table_head_column" style="color: ${Column_Color}">${actions_y[c-1]}</th>`;
    }
    if (page_orientation === "Portrait") {
        kernel += `<th class="component_title" rowspan="${rows+1}"></th>`;
    }
    kernel += "</tr>";
    for (let r = 0; r < rows; r++) {
        kernel += "<tr>";
        kernel += `<th class="payoff_table_head_row" style="color: ${Row_Color}">${actions_x[r]}</th>`;
        for (let c = 1; c < (columns+1); c++) {
                kernel +=`<td class="payoff_table_data"><span style="color: ${Row_Color}">${kappa_x[r][(c-1)]}</span>, <span style="color: ${Column_Color}">${kappa_y[(c-1)][r]}</span></td>`;
        }
    }
    kernel += "</tr>";
    kernel += "</table>";
    if (page_orientation === "Portrait") {
        return html`${payoff_table}<div style="height: 50px"></div>${strategic}<div style="height: 15px"></div>${behavioural}<div style="height: 15px"></div>${kernel}`;
    } else if (page_orientation === "Landscape") {
        return html`${payoff_table}${strategic}${behavioural}${kernel}`
    }
}

```

</div>

<div class="quarto-layout-panel quarto-layout-cell" style="justify-content: center; margin-bottom: 0px; margin-left: auto; flexBasis: 15%" id="actions_set_box">

<div class="quarto-layout-row quarto-layout-valign-bottom" id="flex_container_action_set" style="flexDirection: column">

<div class="quarto-layout-cell" style="margin-bottom: 20px">

```{ojs}
//| panel: sidebar
//| echo: false
html`<span class="sidebar_title">Row Actions</span><br>`

viewof Action_1_row = html`<input type="text" name="text" id="row_action_1" value="Action 1" style="width:100%; height:30px; margin-bottom: 5px">`

viewof Action_2_row = html`<input type="text" name="text" id="row_action_2" value="Action 2" style="width:100%; height:30px; margin-bottom: 5px">`

viewof Action_3_row = html`<input type="text" name="text" id="row_action_3" value="Action 3" style="width:100%; height:30px; margin-bottom: 5px">`

viewof Action_4_row = html`<input type="text" name="text" id="row_action_4" value="Action 4" style="width:100%; height:30px; margin-bottom: 5px">`

viewof Row_Color = html`<input type="color" id="column_color" value="#00008b" class="color_input">`

```

</div>

<div class="quarto-layout-cell" style="margin-bottom: 20px">

```{ojs}
//| panel: sidebar
//| echo: false

html`<span class="sidebar_title">Column Actions</span>`

viewof Action_1_col = html`<input type="text" name="text" id="column_action_1" value="Action 1" style="width:100%; height:30px; margin-bottom: 5px">`

viewof Action_2_col = html`<input type="text" name="text" id="column_action_2" value="Action 2" style="width:100%; height:30px; margin-bottom: 5px">`

viewof Action_3_col = html`<input type="text" name="text" id="column_action_3" value="Action 3" style="width:100%; height:30px; margin-bottom: 5px">`

viewof Action_4_col = html`<input type="text" name="text" id="column_action_4" value="Action 4" style="width:100%; height:30px; margin-bottom: 5px">`

viewof Column_Color = html`<input type="color" id="column_color" value="#8b0000" class="color_input">`
```

</div>

<div class="quarto-layout-cell" style="margin-bottom: 20px; margin-right: 20px">

```{ojs}
//| panel: sidebar
//| echo: false
viewof save_to_pdf = html`<form class="save_to_pdf">${Object.assign(html`<button type=button>Save to PDF`, {onclick: event => event.currentTarget.dispatchEvent(new CustomEvent("input", {bubbles: true}))})}`

viewof save_to_png = html`<form class="save_to_png">${Object.assign(html`<button type=button>Save to PNG`, {onclick: event => event.currentTarget.dispatchEvent(new CustomEvent("input", {bubbles: true}))})}`

viewof save_to_jpeg = html`<form class="save_to_jpeg">${Object.assign(html`<button type=button>Save to JPEG`, {onclick: event => event.currentTarget.dispatchEvent(new CustomEvent("input", {bubbles: true}))})}`

viewof save_to_html = html`<form class="save_to_jpeg">${Object.assign(html`<button type=button>Save to HTML`, {onclick: event => event.currentTarget.dispatchEvent(new CustomEvent("input", {bubbles: true}))})}`

viewof copy_to_clipboard = html`<form class="copy_to_clipboard">${Object.assign(html`<button type=button>Copy to Clipboard`, {onclick: event => event.currentTarget.dispatchEvent(new CustomEvent("input", {bubbles: true}))})}`

```

</div>

</div>

</div>

</div>


```{ojs}
//| echo: false
html2canvas = require("html2canvas")
save_to_pdf_function = {
    save_to_pdf;
    var element = document.getElementById('ojs-cell-6');
    var opt = {
        margin: 1,
        filename: "decomp.pdf",
        image: { type: 'jpeg', quality: 0.98 },
        html2canvas: { scale: 2 },
        jsPDF: { unit: 'in', format: 'letter', orientation: 'portrait' }
    };
    html2pdf().set(opt).from(element).save();
}

save_to_png_function = {
    save_to_png;
    var element = document.getElementById('ojs-cell-6');
    html2canvas(element).then(canvas => {
        canvas.toBlob(function(blob) {
            window.saveAs(blob, "decomposition.png")
        });
    });
    
}

save_to_jpeg_function = {
    save_to_jpeg;
    var element = document.getElementById('ojs-cell-6');
    html2canvas(element).then(canvas => {
        canvas.toBlob(function(blob) {
            window.saveAs(blob, "decomposition.jpeg")
        });
    });
    
}

save_to_html_function = {
    save_to_html;
    var element = document.getElementById('ojs-cell-6');
    html2canvas(element).then(canvas => {
        canvas.toBlob(function(blob) {
            window.saveAs(blob, "decomposition.html")
        });
    });
}

copy_to_clipboard_function = {
    copy_to_clipboard;
    var element = document.getElementById('ojs-cell-6');
    var range = document.createRange();
    range.selectNode(element);
    window.getSelection().removeAllRanges();
    window.getSelection().addRange(range);
    document.execCommand("copy"); //note: execCommand is depreciated, but no good alternative yet
    window.getSelection().removeAllRanges();

    // navigator.clipboard.writeText(element);
}

```

</body>

References

Jessie, D., and D. G. Saari. 2016. “From the Luce Choice Axiom to the Quantal Response Equilibrium.” Journal of Mathematical Psychology 75: 3–9. https://doi.org/10.1016/j.jmp.2015.10.001.
 
 

This website was made with Quarto and disrupted by