<commit_before>(function (env) {
    "use strict";
    env.ddg_spice_color_picker = function(){

        //Acts as a cache of this instant answer's DOM. Because the DOM isn't necessarily ready at
        //  this point, this all gets initialized later.
        var local_dom = {
            initialized: false
        };

        //Maintains currently selected palette type so that it doesn't have to be read from
        //  $palette_select on every update.
        var palette_type = 'analogous';

        //Maintains the current color in all supported formats.
        var current_color = get_initial_color(DDG.get_query());

        //Holds coordinate positions for the selection markers in the hue and saturation/value
        //  pickers.
        var markers = get_marker_positions(current_color.hsv);

        //Indicates whether the user is currently dragging the mouse in the hue and saturation/value
        //  pickers.
        var saturation_value_mousedown = false,
            hue_mousedown = false;

        //Prevent duplicate touch/mouse events
        var mouse_and_touch_locked = false;

        //TODO: use the real image paths
        Spice.add({
            id: "color_picker",
            name: "Color Picker",
            data: {
                saturation_value_path: DDG.get_asset_path('color_picker', 'saturation_value_gradient.png'),
                hue_path: DDG.get_asset_path('color_picker', 'hue_gradient.png')
            },
            meta: {},
            templates: {
                detail: Spice.color_picker.content,
                // item: Spice.color_picker.content,
                // item_detail: false,
                wrap_detail: 'base_detail'
            },
            onShow: function() {
                //The DOM cache was not initialized when it was created. The DOM should be ready
                // here, so we can initialize now.
                if (!local_dom.initialized)
                    initialize_local_dom();
                update_all();
            }
        });

        /* UTILITY FUNCTIONS */

        //Converts a given string value to an integer, which is forced between the given bounds. If
        //  the input string is not a valid number, it is treated as 0.
        function to_bounded_integer(value, lower_bound, upper_bound) {
            var num = Math.round(Number(value));
            if (isNaN(num))
                num = 0;

            if (num < lower_bound)
                num = Math.ceil(lower_bound);
            if (num > upper_bound)
                num = Math.floor(upper_bound);

            return num;
        }

        //Converts a given string value to a number, which is forced between the given bounds. If
        //  the input string is not a valid number, it is treated as 0.
        function to_bounded_number(value, lower_bound, upper_bound) {
            var num = Number(value);
            if (isNaN(num))
                num = 0;

            if (num < lower_bound)
                num = lower_bound;
            if (num > upper_bound)
                num = upper_bound;

            return num;
        }

        //Finds the coordinates of a mouse or touch event relative to an element.
        function get_real_coordinates(event, $element) {
            var offset = $element.offset(),
                coordinates = {
                    x: event.pageX - offset.left,
                    y: event.pageY - offset.top
                };
            return coordinates;
        }

        //Creates a single handler that can be user for both mouse and touch events.
        function mouse_and_touch_handler(callback) {
            return function(e) {
                if (!mouse_and_touch_locked) {
                    //Certain actions will result in both a mouse and touch event being fired.
                    //  In these cases, the combination of the lock and timeout below will keep
                    //  both events from being processed.
                    mouse_and_touch_locked = true;
                    setTimeout(function() {mouse_and_touch_locked = false;}, 0);

                    if (e.changedTouches && e.changedTouches.length > 0) {
                        callback(e.changedTouches[0]);
                    } else if (e.targetTouches && e.targetTouches.length > 0) {
                        callback(e.targetTouches[0]);
                    } else {
                        callback(e);
                    }
                }
            };
        }

        /* EVENT HANDLERS */

        function saturation_value_clicked(event) {
            var coordinates = get_real_coordinates(event, local_dom.$saturation_value_picker);

            //Use the coordinates of the mouse/touch event to calculate the new saturation/value
            var saturation = Math.floor((coordinates.x / 256) * 100),
                value = Math.floor(((256 - coordinates.y) / 256) * 100),
                hue = current_color.hsv.hue;

            saturation = to_bounded_integer(saturation, 0, 100);
            value = to_bounded_integer(value, 0, 100);

            update_all_from_hsv(hue, saturation, value);
        }

        function hue_clicked(event) {
            var coordinates = get_real_coordinates(event, local_dom.$hue_picker);

            //Use the coordinates of the mouse/touch event to calculate the new hue
            var hue = Math.floor((coordinates.y / 256) * 360),
                saturation = current_color.hsv.saturation,
                value = current_color.hsv.value;

            hue = to_bounded_integer(hue, 0, 359);

            update_all_from_hsv(hue, saturation, value);
        }

        function rgb_change() {
            var red = local_dom.$red_input.val(),
                green = local_dom.$green_input.val(),
                blue = local_dom.$blue_input.val();

            red = to_bounded_integer(red, 0, 255);
            green = to_bounded_integer(green, 0, 255);
            blue = to_bounded_integer(blue, 0, 255);

            update_all_from_rgb(red, green, blue);
        }

        function hsv_change() {
            var hue = local_dom.$hue_input.val(),
                saturation = local_dom.$saturation_input.val(),
                value = local_dom.$value_input.val();

            hue = to_bounded_integer(hue, 0, 359);
            saturation = to_bounded_integer(saturation, 0, 100);
            value = to_bounded_integer(value, 0, 100);

            update_all_from_hsv(hue, saturation, value);
        }

        function cmyk_change() {
            var cyan = local_dom.$cyan_input.val(),
                magenta = local_dom.$magenta_input.val(),
                yellow = local_dom.$yellow_input.val(),
                black = local_dom.$black_input.val();

            cyan = to_bounded_number(cyan, 0, 100);
            magenta = to_bounded_number(magenta, 0, 100);
            yellow = to_bounded_number(yellow, 0, 100);
            black = to_bounded_number(black, 0, 100);
            
            update_all_from_cmyk(cyan, magenta, yellow, black);
        }

        function hex_change() {
            var hex = local_dom.$hex_input.val();

            //There are a few ways a new hex string could look and still be valid. It may more may
            //  not start with a '#' character, and it may contain some combination of uppercase and
            //  lowercase letters. It can also contain either three or six hex numerals. Any other
            //  number and the string is either too long, or ambiguous (e.g. #abc -> #0a0b0c, but
            //  #abcd -> #0a0bcd or #a0bcd and so on).
            if (hex.charAt(0) === '#') hex = hex.substring(1);
            if (/^[0-9a-f]+$/i.test(hex)) {
                if (hex.length === 3)
                    hex = hex.charAt(0) + hex.charAt(0) + hex.charAt(1) + hex.charAt(1) + hex.charAt(2) + hex.charAt(2);
                if (hex.length === 6)
                    update_all_from_hex(hex);
                else
                    update_all_from_hex(current_color.hex.substring(1));
            } else
                update_all_from_hex(current_color.hex.substring(1));
        }

        function palette_change() {
            palette_type = local_dom.$palette_select.val();
            update_palette();
        }

        //Calculates the correct positions for the draggable markers in the hue and saturation/value
        //  pickers, relative to the picker.
        function get_marker_positions(hsv) {
            var markers = {
                hue: {
                    y: Math.round((hsv.hue / 360) * 256) - 3
                },
                saturation_value: {
                    x: Math.round((hsv.saturation / 100) * 256) - 3,
                    y: 256 - Math.round((hsv.value / 100) * 256) - 3
                }
            };

            return markers;
        }

        function update_all_from_hsv(hue, saturation, value) {
            current_color = get_all_colors_from_hsv(hue, saturation, value);
            markers = get_marker_positions(current_color.hsv);
            update_all();
        }

        function update_all_from_rgb(red, green, blue) {
            current_color = get_all_colors_from_rgb(red, green, blue);
            markers = get_marker_positions(current_color.hsv);
            update_all();
        }

        function update_all_from_cmyk(cyan, magenta, yellow, black) {
            current_color = get_all_colors_from_cmyk(cyan, magenta, yellow, black);
            markers = get_marker_positions(current_color.hsv);
            update_all();
        }

        function update_all_from_hex(hex) {
            var rgb = convert_hex_to_rgb(hex);
            current_color = get_all_colors_from_rgb(rgb.red, rgb.green, rgb.blue);
            markers = get_marker_positions(current_color.hsv);
            update_all();
        }

        function get_all_colors_from_hsv(hue, saturation, value) {
            var hsv = {
                    hue: hue,
                    saturation: saturation,
                    value: value
                },
                rgb = convert_hsv_to_rgb(hue, saturation, value),
                cmyk = convert_rgb_to_cmyk(rgb.red, rgb.green, rgb.blue),
                hex = convert_rgb_to_hex(rgb.red, rgb.green, rgb.blue),
                hex_hue = convert_hsv_to_hex(hue, 100, 100),
                palette = generate_palette(hsv, palette_type),
                colors = {
                    rgb: rgb,
                    hsv: hsv,
                    cmyk: cmyk,
                    hex: hex,
                    hex_hue: hex_hue,
                    palette: palette
                };

            return colors;
        }

        function get_all_colors_from_rgb(red, green, blue) {
            var rgb = {
                    red: red,
                    green: green,
                    blue: blue
                },
                hsv = convert_rgb_to_hsv(red, green, blue),
                cmyk = convert_rgb_to_cmyk(red, green, blue),
                hex = convert_rgb_to_hex(red, green, blue),
                hex_hue = convert_hsv_to_hex(hsv.hue, 100, 100),
                palette = generate_palette(hsv, palette_type),
                colors = {
                    rgb: rgb,
                    hsv: hsv,
                    cmyk: cmyk,
                    hex: hex,
                    hex_hue: hex_hue,
                    palette: palette
                };

            return colors;
        }

        function get_all_colors_from_cmyk(cyan, magenta, yellow, black) {
            var cmyk = {
                    cyan: cyan,
                    magenta: magenta,
                    yellow: yellow,
                    black: black
                },
                rgb = convert_cmyk_to_rgb(cyan, magenta, yellow, black),
                hsv = convert_rgb_to_hsv(rgb.red, rgb.green, rgb.blue),
                hex = convert_rgb_to_hex(rgb.red, rgb.green, rgb.blue),
                hex_hue = convert_hsv_to_hex(hsv.hue, 100, 100),
                palette = generate_palette(hsv, palette_type),
                colors = {
                    rgb: rgb,
                    hsv: hsv,
                    cmyk: cmyk,
                    hex: hex,
                    hex_hue: hex_hue,
                    palette: palette
                };

            return colors;
        }

        function generate_palette(hsv, type) {
            var hue = [],
                saturation = [],
                value = [],
                palette = [];

            switch (type) {
                case 'triad':
                    hue = [(hsv.hue + 210) % 360, (hsv.hue + 150) % 360, (hsv.hue + 180) % 360];
                    saturation = [hsv.saturation, hsv.saturation, hsv.saturation];
                    value = [hsv.value, hsv.value, hsv.value];
                    break;
                case 'tetrad':
                    hue = [(hsv.hue + 30) % 360, (hsv.hue + 180) % 360, (hsv.hue + 210) % 360];
                    saturation = [hsv.saturation, hsv.saturation, hsv.saturation];
                    value = [hsv.value, hsv.value, hsv.value];
                    break;
                case 'analogous': //fall through
                default:
                    hue = [(hsv.hue + 30) % 360, (hsv.hue + 330) % 360, (hsv.hue + 180) % 360];
                    saturation = [hsv.saturation, hsv.saturation, hsv.saturation];
                    value = [hsv.value, hsv.value, hsv.value];
                    break;
            }

            for (var i = 0; i < hue.length; i++)
                palette.push(convert_hsv_to_hex(hue[i], saturation[i], value[i]));

            return palette;
        }

        function update_palette() {
            current_color.palette = generate_palette(current_color.hsv, palette_type);
            update_all();
        }

        function update_all() {
            local_dom.$red_input.val(current_color.rgb.red);
            local_dom.$green_input.val(current_color.rgb.green);
            local_dom.$blue_input.val(current_color.rgb.blue);
            local_dom.$hue_input.val(current_color.hsv.hue);
            local_dom.$saturation_input.val(current_color.hsv.saturation);
            local_dom.$value_input.val(current_color.hsv.value);
            local_dom.$cyan_input.val(current_color.cmyk.cyan);
            local_dom.$magenta_input.val(current_color.cmyk.magenta);
            local_dom.$yellow_input.val(current_color.cmyk.yellow);
            local_dom.$black_input.val(current_color.cmyk.black);
            local_dom.$hex_input.val(current_color.hex.substring(1));

            local_dom.$saturation_value_picker.css('background-color', current_color.hex_hue);<commit_msg>Fix and refine color harmonies<commit_after>(function (env) {
    "use strict";
    env.ddg_spice_color_picker = function(){

        //Acts as a cache of this instant answer's DOM. Because the DOM isn't necessarily ready at
        //  this point, this all gets initialized later.
        var local_dom = {
            initialized: false
        };

        //Maintains currently selected palette type so that it doesn't have to be read from
        //  $palette_select on every update.
        var palette_type = 'analogous';

        //Maintains the current color in all supported formats.
        var current_color = get_initial_color(DDG.get_query());

        //Holds coordinate positions for the selection markers in the hue and saturation/value
        //  pickers.
        var markers = get_marker_positions(current_color.hsv);

        //Indicates whether the user is currently dragging the mouse in the hue and saturation/value
        //  pickers.
        var saturation_value_mousedown = false,
            hue_mousedown = false;

        //Prevent duplicate touch/mouse events
        var mouse_and_touch_locked = false;

        //TODO: use the real image paths
        Spice.add({
            id: "color_picker",
            name: "Color Picker",
            data: {
                saturation_value_path: DDG.get_asset_path('color_picker', 'saturation_value_gradient.png'),
                hue_path: DDG.get_asset_path('color_picker', 'hue_gradient.png')
            },
            meta: {},
            templates: {
                detail: Spice.color_picker.content,
                // item: Spice.color_picker.content,
                // item_detail: false,
                wrap_detail: 'base_detail'
            },
            onShow: function() {
                //The DOM cache was not initialized when it was created. The DOM should be ready
                // here, so we can initialize now.
                if (!local_dom.initialized)
                    initialize_local_dom();
                update_all();
            }
        });

        /* UTILITY FUNCTIONS */

        //Converts a given string value to an integer, which is forced between the given bounds. If
        //  the input string is not a valid number, it is treated as 0.
        function to_bounded_integer(value, lower_bound, upper_bound) {
            var num = Math.round(Number(value));
            if (isNaN(num))
                num = 0;

            if (num < lower_bound)
                num = Math.ceil(lower_bound);
            if (num > upper_bound)
                num = Math.floor(upper_bound);

            return num;
        }

        //Converts a given string value to a number, which is forced between the given bounds. If
        //  the input string is not a valid number, it is treated as 0.
        function to_bounded_number(value, lower_bound, upper_bound) {
            var num = Number(value);
            if (isNaN(num))
                num = 0;

            if (num < lower_bound)
                num = lower_bound;
            if (num > upper_bound)
                num = upper_bound;

            return num;
        }

        //Finds the coordinates of a mouse or touch event relative to an element.
        function get_real_coordinates(event, $element) {
            var offset = $element.offset(),
                coordinates = {
                    x: event.pageX - offset.left,
                    y: event.pageY - offset.top
                };
            return coordinates;
        }

        //Creates a single handler that can be user for both mouse and touch events.
        function mouse_and_touch_handler(callback) {
            return function(e) {
                if (!mouse_and_touch_locked) {
                    //Certain actions will result in both a mouse and touch event being fired.
                    //  In these cases, the combination of the lock and timeout below will keep
                    //  both events from being processed.
                    mouse_and_touch_locked = true;
                    setTimeout(function() {mouse_and_touch_locked = false;}, 0);

                    if (e.changedTouches && e.changedTouches.length > 0) {
                        callback(e.changedTouches[0]);
                    } else if (e.targetTouches && e.targetTouches.length > 0) {
                        callback(e.targetTouches[0]);
                    } else {
                        callback(e);
                    }
                }
            };
        }

        /* EVENT HANDLERS */

        function saturation_value_clicked(event) {
            var coordinates = get_real_coordinates(event, local_dom.$saturation_value_picker);

            //Use the coordinates of the mouse/touch event to calculate the new saturation/value
            var saturation = Math.floor((coordinates.x / 256) * 100),
                value = Math.floor(((256 - coordinates.y) / 256) * 100),
                hue = current_color.hsv.hue;

            saturation = to_bounded_integer(saturation, 0, 100);
            value = to_bounded_integer(value, 0, 100);

            update_all_from_hsv(hue, saturation, value);
        }

        function hue_clicked(event) {
            var coordinates = get_real_coordinates(event, local_dom.$hue_picker);

            //Use the coordinates of the mouse/touch event to calculate the new hue
            var hue = Math.floor((coordinates.y / 256) * 360),
                saturation = current_color.hsv.saturation,
                value = current_color.hsv.value;

            hue = to_bounded_integer(hue, 0, 359);

            update_all_from_hsv(hue, saturation, value);
        }

        function rgb_change() {
            var red = local_dom.$red_input.val(),
                green = local_dom.$green_input.val(),
                blue = local_dom.$blue_input.val();

            red = to_bounded_integer(red, 0, 255);
            green = to_bounded_integer(green, 0, 255);
            blue = to_bounded_integer(blue, 0, 255);

            update_all_from_rgb(red, green, blue);
        }

        function hsv_change() {
            var hue = local_dom.$hue_input.val(),
                saturation = local_dom.$saturation_input.val(),
                value = local_dom.$value_input.val();

            hue = to_bounded_integer(hue, 0, 359);
            saturation = to_bounded_integer(saturation, 0, 100);
            value = to_bounded_integer(value, 0, 100);

            update_all_from_hsv(hue, saturation, value);
        }

        function cmyk_change() {
            var cyan = local_dom.$cyan_input.val(),
                magenta = local_dom.$magenta_input.val(),
                yellow = local_dom.$yellow_input.val(),
                black = local_dom.$black_input.val();

            cyan = to_bounded_number(cyan, 0, 100);
            magenta = to_bounded_number(magenta, 0, 100);
            yellow = to_bounded_number(yellow, 0, 100);
            black = to_bounded_number(black, 0, 100);
            
            update_all_from_cmyk(cyan, magenta, yellow, black);
        }

        function hex_change() {
            var hex = local_dom.$hex_input.val();

            //There are a few ways a new hex string could look and still be valid. It may more may
            //  not start with a '#' character, and it may contain some combination of uppercase and
            //  lowercase letters. It can also contain either three or six hex numerals. Any other
            //  number and the string is either too long, or ambiguous (e.g. #abc -> #0a0b0c, but
            //  #abcd -> #0a0bcd or #a0bcd and so on).
            if (hex.charAt(0) === '#') hex = hex.substring(1);
            if (/^[0-9a-f]+$/i.test(hex)) {
                if (hex.length === 3)
                    hex = hex.charAt(0) + hex.charAt(0) + hex.charAt(1) + hex.charAt(1) + hex.charAt(2) + hex.charAt(2);
                if (hex.length === 6)
                    update_all_from_hex(hex);
                else
                    update_all_from_hex(current_color.hex.substring(1));
            } else
                update_all_from_hex(current_color.hex.substring(1));
        }

        function palette_change() {
            palette_type = local_dom.$palette_select.val();
            update_palette();
        }

        //Calculates the correct positions for the draggable markers in the hue and saturation/value
        //  pickers, relative to the picker.
        function get_marker_positions(hsv) {
            var markers = {
                hue: {
                    y: Math.round((hsv.hue / 360) * 256) - 3
                },
                saturation_value: {
                    x: Math.round((hsv.saturation / 100) * 256) - 3,
                    y: 256 - Math.round((hsv.value / 100) * 256) - 3
                }
            };

            return markers;
        }

        function update_all_from_hsv(hue, saturation, value) {
            current_color = get_all_colors_from_hsv(hue, saturation, value);
            markers = get_marker_positions(current_color.hsv);
            update_all();
        }

        function update_all_from_rgb(red, green, blue) {
            current_color = get_all_colors_from_rgb(red, green, blue);
            markers = get_marker_positions(current_color.hsv);
            update_all();
        }

        function update_all_from_cmyk(cyan, magenta, yellow, black) {
            current_color = get_all_colors_from_cmyk(cyan, magenta, yellow, black);
            markers = get_marker_positions(current_color.hsv);
            update_all();
        }

        function update_all_from_hex(hex) {
            var rgb = convert_hex_to_rgb(hex);
            current_color = get_all_colors_from_rgb(rgb.red, rgb.green, rgb.blue);
            markers = get_marker_positions(current_color.hsv);
            update_all();
        }

        function get_all_colors_from_hsv(hue, saturation, value) {
            var hsv = {
                    hue: hue,
                    saturation: saturation,
                    value: value
                },
                rgb = convert_hsv_to_rgb(hue, saturation, value),
                cmyk = convert_rgb_to_cmyk(rgb.red, rgb.green, rgb.blue),
                hex = convert_rgb_to_hex(rgb.red, rgb.green, rgb.blue),
                hex_hue = convert_hsv_to_hex(hue, 100, 100),
                palette = generate_palette(hsv, palette_type),
                colors = {
                    rgb: rgb,
                    hsv: hsv,
                    cmyk: cmyk,
                    hex: hex,
                    hex_hue: hex_hue,
                    palette: palette
                };

            return colors;
        }

        function get_all_colors_from_rgb(red, green, blue) {
            var rgb = {
                    red: red,
                    green: green,
                    blue: blue
                },
                hsv = convert_rgb_to_hsv(red, green, blue),
                cmyk = convert_rgb_to_cmyk(red, green, blue),
                hex = convert_rgb_to_hex(red, green, blue),
                hex_hue = convert_hsv_to_hex(hsv.hue, 100, 100),
                palette = generate_palette(hsv, palette_type),
                colors = {
                    rgb: rgb,
                    hsv: hsv,
                    cmyk: cmyk,
                    hex: hex,
                    hex_hue: hex_hue,
                    palette: palette
                };

            return colors;
        }

        function get_all_colors_from_cmyk(cyan, magenta, yellow, black) {
            var cmyk = {
                    cyan: cyan,
                    magenta: magenta,
                    yellow: yellow,
                    black: black
                },
                rgb = convert_cmyk_to_rgb(cyan, magenta, yellow, black),
                hsv = convert_rgb_to_hsv(rgb.red, rgb.green, rgb.blue),
                hex = convert_rgb_to_hex(rgb.red, rgb.green, rgb.blue),
                hex_hue = convert_hsv_to_hex(hsv.hue, 100, 100),
                palette = generate_palette(hsv, palette_type),
                colors = {
                    rgb: rgb,
                    hsv: hsv,
                    cmyk: cmyk,
                    hex: hex,
                    hex_hue: hex_hue,
                    palette: palette
                };

            return colors;
        }

        function generate_palette(hsv, type) {
            var hue = [],
                saturation = [],
                value = [],
                palette = [];

            switch (type) {
                case 'triad':
                    hue = [hsv.hue, (hsv.hue + 120) % 360, (hsv.hue + 240) % 360];
                    saturation = [hsv.saturation, hsv.saturation, hsv.saturation];
                    value = [hsv.value, hsv.value, hsv.value];
                    break;
                case 'tetrad':
                    hue = [(hsv.hue + 60) % 360, (hsv.hue + 180) % 360, (hsv.hue + 240) % 360];
                    saturation = [hsv.saturation, hsv.saturation, hsv.saturation];
                    value = [hsv.value, hsv.value, hsv.value];
                    break;
                case 'analogous': //fall through
                default:
                    hue = [hsv.hue, (hsv.hue + 30) % 360, (hsv.hue + 330) % 360];
                    saturation = [hsv.saturation, hsv.saturation, hsv.saturation];
                    value = [hsv.value, hsv.value, hsv.value];
                    break;
            }

            for (var i = 0; i < hue.length; i++)
                palette.push(convert_hsv_to_hex(hue[i], saturation[i], value[i]));

            return palette;
        }

        function update_palette() {
            current_color.palette = generate_palette(current_color.hsv, palette_type);
            update_all();
        }

        function update_all() {
            local_dom.$red_input.val(current_color.rgb.red);
            local_dom.$green_input.val(current_color.rgb.green);
            local_dom.$blue_input.val(current_color.rgb.blue);
            local_dom.$hue_input.val(current_color.hsv.hue);
            local_dom.$saturation_input.val(current_color.hsv.saturation);
            local_dom.$value_input.val(current_color.hsv.value);
            local_dom.$cyan_input.val(current_color.cmyk.cyan);
            local_dom.$magenta_input.val(current_color.cmyk.magenta);
            local_dom.$yellow_input.val(current_color.cmyk.yellow);
            local_dom.$black_input.val(current_color.cmyk.black);
            local_dom.$hex_input.val(current_color.hex.substring(1));

            local_dom.$saturation_value_picker.css('background-color', current_color.hex_hue);
{'fraction_non_alphanumeric': 0.09498519048105403, 'fraction_numerical': 0.01307323051782249, 'mean_word_length': 1.517699494300163, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5513268', 'n_tokens_mistral': 9009, 'n_tokens_neox': 8093, 'n_words': 1931}