<commit_before>﻿using UnityEngine;
using System.Collections.Generic;
using Assets.Scripts.Content;
using ValkyrieTools;
using System.IO;

// Class to manage all data for the current quest
public class Quest
{
    // QuestData
    public QuestData qd;

    // Original Quest Path
    public string questPath = "";

    // components on the board (tiles, tokens, doors)
    public Dictionary<string, BoardComponent> boardItems;

    // vars for the quest
    public VarManager vars;

    // A list of items that have been given to the investigators
    public HashSet<string> items;

    // A dictionary of heros that have been selected in events
    public Dictionary<string, List<Quest.Hero>> heroSelection;

    // A dictionary of puzzle state
    public Dictionary<string, Puzzle> puzzle;

    // A count of successes from events
    public Dictionary<string, int> eventQuota;

    // Event manager handles the events
    public EventManager eManager;

    // List of heros and their status
    public List<Hero> heroes;

    // List of active monsters and their status
    public List<Monster> monsters;

    // Stack of saved game state for undo
    public Stack<string> undo;

    // Event Log
    public List<LogEntry> log;

    // Dictionary of picked monster types
    public Dictionary<string, string> monsterSelect;

    // game state variables
    public MoMPhase phase = MoMPhase.investigator;

    // This is true once heros are selected and the quest is started
    public bool heroesSelected = false;

    // Reference back to the game object
    public Game game;

    // Construct a new quest from quest data
    public Quest(QuestData.Quest q)
    {
        game = Game.Get();

        // This happens anyway but we need it to be here before the following code is executed
        game.quest = this;

        // Static data from the quest file
        qd = new QuestData(q);
        questPath = Path.GetDirectoryName(qd.questPath);

        // Initialise data
        boardItems = new Dictionary<string, BoardComponent>();
        vars = new VarManager();
        items = new HashSet<string>();
        monsters = new List<Monster>();
        heroSelection = new Dictionary<string, List<Quest.Hero>>();
        puzzle = new Dictionary<string, Puzzle>();
        eventQuota = new Dictionary<string, int>();
        undo = new Stack<string>();
        log = new List<LogEntry>();
        monsterSelect = new Dictionary<string, string>();

        GenerateMonsterSelection();
        eManager = new EventManager();

        // Populate null hero list, these can then be selected as hero types
        heroes = new List<Hero>();
        for (int i = 1; i <= game.gameType.MaxHeroes(); i++)
        {
            heroes.Add(new Hero(null, i));
        }

        // Set quest vars for selected expansions
        foreach (string s in game.cd.GetLoadedPackIDs())
        {
            if (s.Length > 0)
            {
                vars.SetValue("#" + s, 1);
            }
        }
        vars.SetValue("#round", 1);
    }


    public void GenerateMonsterSelection()
    {
        // Determine monster types
        bool progress = false;
        bool force = false;
        bool done = false;
        while (!done)
        {
            progress = false;
            foreach (KeyValuePair<string, QuestData.QuestComponent> kv in qd.components)
            {
                QuestData.Spawn qs = kv.Value as QuestData.Spawn;
                if (qs != null)
                {
                    progress |= AttemptMonsterMatch(qs, force);
                    if (progress && force) force = false;
                }
            }
            if (!progress && !force)
            {
                force = true;
            }
            else if (!progress && force)
            {
                done = true;
            }
        }
    }

    public bool AttemptMonsterMatch(QuestData.Spawn spawn, bool force = true)
    {
        if (monsterSelect.ContainsKey(spawn.sectionName))
        {
            return false;
        }
        if ((spawn.mTraitsPool.Length + spawn.mTraitsRequired.Length) == 0)
        {
            foreach (string t in spawn.mTypes)
            {
                if (monsterSelect.ContainsKey(t))
                {
                    monsterSelect.Add(spawn.sectionName, monsterSelect[t]);
                    return true;
                }
                if (t.IndexOf("Spawn") == 0)
                {
                    return false;
                }
                string monster = t;
                if (monster.IndexOf("Monster") != 0 && monster.IndexOf("CustomMonster") != 0)
                {
                    monster = "Monster" + monster;
                }
                // Monster type might be a unique for this quest
                if (game.quest.qd.components.ContainsKey(monster))
                {
                    monsterSelect.Add(spawn.sectionName, monster);
                    return true;
                }
                // Monster type might exist in content packs, 'Monster' is optional
                else if (game.cd.monsters.ContainsKey(monster))
                {
                    monsterSelect.Add(spawn.sectionName, monster);
                    return true;
                }
            }
        }
        else
        {
            // List of exclusions
            List<string> exclude = new List<string>();
            foreach (string t in spawn.mTypes)
            {
                if (monsterSelect.ContainsKey(t))
                {
                    exclude.Add(monsterSelect[t]);
                }
                else if (t.IndexOf("Spawn") == 0 && !force)
                {
                    return false;
                }
                else
                {
                    exclude.Add(t);
                }
            }

            // Start a list of matches
            List<string> list = new List<string>();
            foreach (KeyValuePair<string, MonsterData> kv in game.cd.monsters)
            {
                bool allFound = true;
                foreach (string t in spawn.mTraitsRequired)
                {
                    // Does the monster have this trait?
                    if (!kv.Value.ContainsTrait(t))
                    {
                        // Trait missing, exclude monster
                        allFound = false;
                    }
                }

                // Must have one of these traits
                bool oneFound = (spawn.mTraitsPool.Length == 0);
                foreach (string t in spawn.mTraitsPool)
                {
                    // Does the monster have this trait?
                    if (kv.Value.ContainsTrait(t))
                    {
                        oneFound = true;
                    }
                }

                bool excludeBool = false;
                foreach (string t in exclude)
                {
                    if (t.Equals(kv.Key)) excludeBool = true;
                }

                // Monster has all traits
                if (allFound && oneFound && !excludeBool)
                {
                    list.Add(kv.Key);
                }
            }

            if (list.Count == 0)
            {
                ValkyrieDebug.Log("Error: Unable to find monster of traits specified in event: " + spawn.sectionName);
                Destroyer.MainMenu();
                return false;
            }

            // Pick monster at random from candidates
            monsterSelect.Add(spawn.sectionName, list[Random.Range(0, list.Count)]);
            return true;
        }
        return false;
    }

    // Construct a quest from save data string
    // Used for undo
    public Quest(string save)
    {
        LoadQuest(IniRead.ReadFromString(save));
    }

    // Construct a quest from save iniData
    public Quest(IniData saveData)
    {
        LoadQuest(saveData);
    }

    public void ChangeQuest(string path)
    {
        Game game = Game.Get();

        // Clean up everything marked as 'board'
        foreach (GameObject go in GameObject.FindGameObjectsWithTag("board"))
            Object.Destroy(go);
        game.tokenBoard.tc.Clear();

        phase = MoMPhase.investigator;
        game.cc.gameObject.transform.position = new Vector3(0, 0, -8);

        game.cc.minLimit = false;
        game.cc.maxLimit = false;

        // Set static quest data
        qd = new QuestData(questPath + "/" + path);
        questPath = Path.GetDirectoryName(qd.questPath);

        vars.TrimQuest();

        undo = new Stack<string>();

        // Initialise data
        boardItems = new Dictionary<string, BoardComponent>();
        monsters = new List<Monster>();
        heroSelection = new Dictionary<string, List<Quest.Hero>>();
        puzzle = new Dictionary<string, Puzzle>();
        eventQuota = new Dictionary<string, int>();
        undo = new Stack<string>();
        monsterSelect = new Dictionary<string, string>();

        GenerateMonsterSelection();
        eManager = new EventManager();

        // Set quest vars for selected expansions
        foreach (string s in game.cd.GetLoadedPackIDs())
        {
            if (s.Length > 0)
            {
                vars.SetValue("#" + s, 1);
            }
        }
        vars.SetValue("#round", 1);

        // Set quest flag based on hero count
        int heroCount = 0;
        foreach (Quest.Hero h in heroes)
        {
            h.activated = false;
            h.defeated = false;
            h.selected = false;
        }
        game.quest.vars.SetValue("#heroes", heroCount);

        List<string> music = new List<string>();
        foreach (AudioData ad in game.cd.audio.Values)
        {
            if (ad.ContainsTrait("quest")) music.Add(ad.file);
        }
        game.audioControl.Music(music);

        // Update the screen
        game.monsterCanvas.UpdateList();
        game.heroCanvas.UpdateStatus();

        if (game.gameType is D2EGameType)
        {
            // Start round events
            eManager.EventTriggerType("StartRound", false);
            // Start the quest (top of stack)
            eManager.EventTriggerType("EventStart", false);
            eManager.TriggerEvent();
        }
        else
        {
            new InvestigatorItems();
        }
    }

    // Read save data
    public void LoadQuest(IniData saveData)
    {
        game = Game.Get();

        // This happens anyway but we need it to be here before the following code is executed (also needed for loading saves)
        game.quest = this;

        // Get state
        bool.TryParse(saveData.Get("Quest", "heroesSelected"), out heroesSelected);
        bool horror;
        bool.TryParse(saveData.Get("Quest", "horror"), out horror);
        if (horror)
        {
            phase = MoMPhase.horror;
        }

        // Set camera
        float camx, camy, camz;
        float.TryParse(saveData.Get("Quest", "camx"), out camx);
        float.TryParse(saveData.Get("Quest", "camy"), out camy);
        float.TryParse(saveData.Get("Quest", "camz"), out camz);
        game.cc.gameObject.transform.position = new Vector3(camx, camy, camz);

        game.cc.minLimit = false;
        if (saveData.Get("Quest", "camxmin").Length > 0)
        {
            game.cc.minLimit = true;
            int.TryParse(saveData.Get("Quest", "camxmin"), out game.cc.minPanX);
            int.TryParse(saveData.Get("Quest", "camymin"), out game.cc.minPanY);
        }

        game.cc.maxLimit = false;
        if (saveData.Get("Quest", "camxmax").Length > 0)
        {
            game.cc.maxLimit = true;
            int.TryParse(saveData.Get("Quest", "camxmax"), out game.cc.maxPanX);
            int.TryParse(saveData.Get("Quest", "camymax"), out game.cc.maxPanY);
        }

        // Set static quest data
        qd = new QuestData(saveData.Get("Quest", "path"));

        questPath = saveData.Get("Quest", "originalpath");

        monsterSelect = saveData.Get("SelectMonster");
        if (monsterSelect == null)
        {
            // Support old saves
            monsterSelect = new Dictionary<string, string>();
            GenerateMonsterSelection();
        }

        // Clear all tokens
        game.tokenBoard.Clear();
        // Clean up everything marked as 'board'
        foreach (GameObject go in GameObject.FindGameObjectsWithTag("board"))
            Object.Destroy(go);

        // Repopulate items on the baord
        boardItems = new Dictionary<string, BoardComponent>();
        Dictionary<string, string> saveBoard = saveData.Get("Board");
        foreach (KeyValuePair<string, string> kv in saveBoard)
        {
            if (kv.Key.IndexOf("Door") == 0)
            {
                boardItems.Add(kv.Key, new Door(qd.components[kv.Key] as QuestData.Door, game));
            }
            if (kv.Key.IndexOf("Token") == 0)
            {
                boardItems.Add(kv.Key, new Token(qd.components[kv.Key] as QuestData.Token, game));
            }
            if (kv.Key.IndexOf("Tile") == 0)
            {
                boardItems.Add(kv.Key, new Tile(qd.components[kv.Key] as QuestData.Tile, game));
            }
        }

        // Restore event log
        log = new List<LogEntry>();
        foreach (KeyValuePair<string, string> kv in saveData.Get("Log"))
        {
            log.Add(new LogEntry(kv.Key, kv.Value));
        }

        Dictionary<string, string> saveVars = saveData.Get("Vars");
        vars = new VarManager(saveVars);

        // Set items
        items = new HashSet<string>();
        Dictionary<string, string> saveItems = saveData.Get("Items");
        foreach (KeyValuePair<string, string> kv in saveItems)
        {
            items.Add(kv.Key);
        }

        // Clean undo stack (we don't save undo stack)
        // When performing undo this is replaced later
        undo = new Stack<string>();

        // Fetch hero state
        heroes = new List<Hero>();
        monsters = new List<Monster>();
        foreach (KeyValuePair<string, Dictionary<string, string>> kv in saveData.data)
        {<commit_msg>Fixing quest load with UI present.<commit_after>﻿using UnityEngine;
using System.Collections.Generic;
using Assets.Scripts.Content;
using ValkyrieTools;
using System.IO;

// Class to manage all data for the current quest
public class Quest
{
    // QuestData
    public QuestData qd;

    // Original Quest Path
    public string questPath = "";

    // components on the board (tiles, tokens, doors)
    public Dictionary<string, BoardComponent> boardItems;

    // vars for the quest
    public VarManager vars;

    // A list of items that have been given to the investigators
    public HashSet<string> items;

    // A dictionary of heros that have been selected in events
    public Dictionary<string, List<Quest.Hero>> heroSelection;

    // A dictionary of puzzle state
    public Dictionary<string, Puzzle> puzzle;

    // A count of successes from events
    public Dictionary<string, int> eventQuota;

    // Event manager handles the events
    public EventManager eManager;

    // List of heros and their status
    public List<Hero> heroes;

    // List of active monsters and their status
    public List<Monster> monsters;

    // Stack of saved game state for undo
    public Stack<string> undo;

    // Event Log
    public List<LogEntry> log;

    // Dictionary of picked monster types
    public Dictionary<string, string> monsterSelect;

    // game state variables
    public MoMPhase phase = MoMPhase.investigator;

    // This is true once heros are selected and the quest is started
    public bool heroesSelected = false;

    // Reference back to the game object
    public Game game;

    // Construct a new quest from quest data
    public Quest(QuestData.Quest q)
    {
        game = Game.Get();

        // This happens anyway but we need it to be here before the following code is executed
        game.quest = this;

        // Static data from the quest file
        qd = new QuestData(q);
        questPath = Path.GetDirectoryName(qd.questPath);

        // Initialise data
        boardItems = new Dictionary<string, BoardComponent>();
        vars = new VarManager();
        items = new HashSet<string>();
        monsters = new List<Monster>();
        heroSelection = new Dictionary<string, List<Quest.Hero>>();
        puzzle = new Dictionary<string, Puzzle>();
        eventQuota = new Dictionary<string, int>();
        undo = new Stack<string>();
        log = new List<LogEntry>();
        monsterSelect = new Dictionary<string, string>();

        GenerateMonsterSelection();
        eManager = new EventManager();

        // Populate null hero list, these can then be selected as hero types
        heroes = new List<Hero>();
        for (int i = 1; i <= game.gameType.MaxHeroes(); i++)
        {
            heroes.Add(new Hero(null, i));
        }

        // Set quest vars for selected expansions
        foreach (string s in game.cd.GetLoadedPackIDs())
        {
            if (s.Length > 0)
            {
                vars.SetValue("#" + s, 1);
            }
        }
        vars.SetValue("#round", 1);
    }


    public void GenerateMonsterSelection()
    {
        // Determine monster types
        bool progress = false;
        bool force = false;
        bool done = false;
        while (!done)
        {
            progress = false;
            foreach (KeyValuePair<string, QuestData.QuestComponent> kv in qd.components)
            {
                QuestData.Spawn qs = kv.Value as QuestData.Spawn;
                if (qs != null)
                {
                    progress |= AttemptMonsterMatch(qs, force);
                    if (progress && force) force = false;
                }
            }
            if (!progress && !force)
            {
                force = true;
            }
            else if (!progress && force)
            {
                done = true;
            }
        }
    }

    public bool AttemptMonsterMatch(QuestData.Spawn spawn, bool force = true)
    {
        if (monsterSelect.ContainsKey(spawn.sectionName))
        {
            return false;
        }
        if ((spawn.mTraitsPool.Length + spawn.mTraitsRequired.Length) == 0)
        {
            foreach (string t in spawn.mTypes)
            {
                if (monsterSelect.ContainsKey(t))
                {
                    monsterSelect.Add(spawn.sectionName, monsterSelect[t]);
                    return true;
                }
                if (t.IndexOf("Spawn") == 0)
                {
                    return false;
                }
                string monster = t;
                if (monster.IndexOf("Monster") != 0 && monster.IndexOf("CustomMonster") != 0)
                {
                    monster = "Monster" + monster;
                }
                // Monster type might be a unique for this quest
                if (game.quest.qd.components.ContainsKey(monster))
                {
                    monsterSelect.Add(spawn.sectionName, monster);
                    return true;
                }
                // Monster type might exist in content packs, 'Monster' is optional
                else if (game.cd.monsters.ContainsKey(monster))
                {
                    monsterSelect.Add(spawn.sectionName, monster);
                    return true;
                }
            }
        }
        else
        {
            // List of exclusions
            List<string> exclude = new List<string>();
            foreach (string t in spawn.mTypes)
            {
                if (monsterSelect.ContainsKey(t))
                {
                    exclude.Add(monsterSelect[t]);
                }
                else if (t.IndexOf("Spawn") == 0 && !force)
                {
                    return false;
                }
                else
                {
                    exclude.Add(t);
                }
            }

            // Start a list of matches
            List<string> list = new List<string>();
            foreach (KeyValuePair<string, MonsterData> kv in game.cd.monsters)
            {
                bool allFound = true;
                foreach (string t in spawn.mTraitsRequired)
                {
                    // Does the monster have this trait?
                    if (!kv.Value.ContainsTrait(t))
                    {
                        // Trait missing, exclude monster
                        allFound = false;
                    }
                }

                // Must have one of these traits
                bool oneFound = (spawn.mTraitsPool.Length == 0);
                foreach (string t in spawn.mTraitsPool)
                {
                    // Does the monster have this trait?
                    if (kv.Value.ContainsTrait(t))
                    {
                        oneFound = true;
                    }
                }

                bool excludeBool = false;
                foreach (string t in exclude)
                {
                    if (t.Equals(kv.Key)) excludeBool = true;
                }

                // Monster has all traits
                if (allFound && oneFound && !excludeBool)
                {
                    list.Add(kv.Key);
                }
            }

            if (list.Count == 0)
            {
                ValkyrieDebug.Log("Error: Unable to find monster of traits specified in event: " + spawn.sectionName);
                Destroyer.MainMenu();
                return false;
            }

            // Pick monster at random from candidates
            monsterSelect.Add(spawn.sectionName, list[Random.Range(0, list.Count)]);
            return true;
        }
        return false;
    }

    // Construct a quest from save data string
    // Used for undo
    public Quest(string save)
    {
        LoadQuest(IniRead.ReadFromString(save));
    }

    // Construct a quest from save iniData
    public Quest(IniData saveData)
    {
        LoadQuest(saveData);
    }

    public void ChangeQuest(string path)
    {
        Game game = Game.Get();

        // Clean up everything marked as 'board'
        foreach (GameObject go in GameObject.FindGameObjectsWithTag("board"))
            Object.Destroy(go);
        game.tokenBoard.tc.Clear();

        phase = MoMPhase.investigator;
        game.cc.gameObject.transform.position = new Vector3(0, 0, -8);

        game.cc.minLimit = false;
        game.cc.maxLimit = false;

        // Set static quest data
        qd = new QuestData(questPath + "/" + path);
        questPath = Path.GetDirectoryName(qd.questPath);

        vars.TrimQuest();

        undo = new Stack<string>();

        // Initialise data
        boardItems = new Dictionary<string, BoardComponent>();
        monsters = new List<Monster>();
        heroSelection = new Dictionary<string, List<Quest.Hero>>();
        puzzle = new Dictionary<string, Puzzle>();
        eventQuota = new Dictionary<string, int>();
        undo = new Stack<string>();
        monsterSelect = new Dictionary<string, string>();

        GenerateMonsterSelection();
        eManager = new EventManager();

        // Set quest vars for selected expansions
        foreach (string s in game.cd.GetLoadedPackIDs())
        {
            if (s.Length > 0)
            {
                vars.SetValue("#" + s, 1);
            }
        }
        vars.SetValue("#round", 1);

        // Set quest flag based on hero count
        int heroCount = 0;
        foreach (Quest.Hero h in heroes)
        {
            h.activated = false;
            h.defeated = false;
            h.selected = false;
        }
        game.quest.vars.SetValue("#heroes", heroCount);

        List<string> music = new List<string>();
        foreach (AudioData ad in game.cd.audio.Values)
        {
            if (ad.ContainsTrait("quest")) music.Add(ad.file);
        }
        game.audioControl.Music(music);

        // Update the screen
        game.monsterCanvas.UpdateList();
        game.heroCanvas.UpdateStatus();

        if (game.gameType is D2EGameType)
        {
            // Start round events
            eManager.EventTriggerType("StartRound", false);
            // Start the quest (top of stack)
            eManager.EventTriggerType("EventStart", false);
            eManager.TriggerEvent();
        }
        else
        {
            new InvestigatorItems();
        }
    }

    // Read save data
    public void LoadQuest(IniData saveData)
    {
        game = Game.Get();

        // This happens anyway but we need it to be here before the following code is executed (also needed for loading saves)
        game.quest = this;

        // Get state
        bool.TryParse(saveData.Get("Quest", "heroesSelected"), out heroesSelected);
        bool horror;
        bool.TryParse(saveData.Get("Quest", "horror"), out horror);
        if (horror)
        {
            phase = MoMPhase.horror;
        }

        // Set camera
        float camx, camy, camz;
        float.TryParse(saveData.Get("Quest", "camx"), out camx);
        float.TryParse(saveData.Get("Quest", "camy"), out camy);
        float.TryParse(saveData.Get("Quest", "camz"), out camz);
        game.cc.gameObject.transform.position = new Vector3(camx, camy, camz);

        game.cc.minLimit = false;
        if (saveData.Get("Quest", "camxmin").Length > 0)
        {
            game.cc.minLimit = true;
            int.TryParse(saveData.Get("Quest", "camxmin"), out game.cc.minPanX);
            int.TryParse(saveData.Get("Quest", "camymin"), out game.cc.minPanY);
        }

        game.cc.maxLimit = false;
        if (saveData.Get("Quest", "camxmax").Length > 0)
        {
            game.cc.maxLimit = true;
            int.TryParse(saveData.Get("Quest", "camxmax"), out game.cc.maxPanX);
            int.TryParse(saveData.Get("Quest", "camymax"), out game.cc.maxPanY);
        }

        // Set static quest data
        qd = new QuestData(saveData.Get("Quest", "path"));

        questPath = saveData.Get("Quest", "originalpath");

        monsterSelect = saveData.Get("SelectMonster");
        if (monsterSelect == null)
        {
            // Support old saves
            monsterSelect = new Dictionary<string, string>();
            GenerateMonsterSelection();
        }

        // Clear all tokens
        game.tokenBoard.Clear();
        // Clean up everything marked as 'board'
        foreach (GameObject go in GameObject.FindGameObjectsWithTag("board"))
            Object.Destroy(go);

        // Repopulate items on the baord
        boardItems = new Dictionary<string, BoardComponent>();
        Dictionary<string, string> saveBoard = saveData.Get("Board");
        foreach (KeyValuePair<string, string> kv in saveBoard)
        {
            if (kv.Key.IndexOf("Door") == 0)
            {
                boardItems.Add(kv.Key, new Door(qd.components[kv.Key] as QuestData.Door, game));
            }
            if (kv.Key.IndexOf("Token") == 0)
            {
                boardItems.Add(kv.Key, new Token(qd.components[kv.Key] as QuestData.Token, game));
            }
            if (kv.Key.IndexOf("Tile") == 0)
            {
                boardItems.Add(kv.Key, new Tile(qd.components[kv.Key] as QuestData.Tile, game));
            }
            if (kv.Key.IndexOf("UI") == 0)
            {
                boardItems.Add(kv.Key, new UI(qd.components[kv.Key] as QuestData.UI, game));
            }
        }

        // Restore event log
        log = new List<LogEntry>();
        foreach (KeyValuePair<string, string> kv in saveData.Get("Log"))
        {
            log.Add(new LogEntry(kv.Key, kv.Value));
        }

        Dictionary<string, string> saveVars = saveData.Get("Vars");
        vars = new VarManager(saveVars);

        // Set items
        items = new HashSet<string>();
        Dictionary<string, string> saveItems = saveData.Get("Items");
        foreach (KeyValuePair<string, string> kv in saveItems)
        {
            items.Add(kv.Key);
        }

        // Clean undo stack (we don't save undo stack)
        // When performing undo this is replaced later
        undo = new Stack<string>();

        // Fetch hero state
        heroes = new List<Hero>();
        monsters = new List<Monster>();
        foreach (KeyValuePair<string, Dictionary<string, string>> kv in saveData.data)
        {
{'fraction_non_alphanumeric': 0.10369093276098659, 'fraction_numerical': 0.0019351887688680905, 'mean_word_length': 1.5702658708627237, 'pattern_counts': {'":': 0, '<': 113, '<?xml version=': 0, '>': 119, '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': '4608369', 'n_tokens_mistral': 7710, 'n_tokens_neox': 7329, 'n_words': 2040}