diff --git a/Assets/SEE/Controls/Actions/ShowCodeAction.cs b/Assets/SEE/Controls/Actions/ShowCodeAction.cs index 0e7f8b134b..e181ef46d0 100644 --- a/Assets/SEE/Controls/Actions/ShowCodeAction.cs +++ b/Assets/SEE/Controls/Actions/ShowCodeAction.cs @@ -254,10 +254,28 @@ public static CodeWindow ShowVCSDiff(GraphElementRef graphElementRef, DiffCity c public static CodeWindow ShowCode(GraphElementRef graphElementRef) { GraphElement graphElement = graphElementRef.Elem; - // File name of source code file to read from it - (string filename, string absolutePlatformPath) = GetPath(graphElement); - CodeWindow codeWindow = GetOrCreateCodeWindow(graphElementRef, filename); - codeWindow.EnterFromFile(absolutePlatformPath); + CodeWindow codeWindow; + if (graphElement.TryGetCommitID(out string commitID)) + { + codeWindow = GetOrCreateCodeWindow(graphElementRef, graphElement.Filename); + if (!graphElement.TryGetRepositoryPath(out string repositoryPath)) + { + string message = $"Selected {GetName(graphElement)} has no repository path."; + ShowNotification.Error("No repository path", message, log: false); + throw new InvalidOperationException(message); + } + IVersionControl vcs = VersionControlFactory.GetVersionControl(VCSKind.Git, repositoryPath); + string[] fileContent = vcs.Show(graphElement.ID, commitID). + Split("\\n", StringSplitOptions.RemoveEmptyEntries); + codeWindow.EnterFromText(fileContent); + } + else + { + (string filename, string absolutePlatformPath) = GetPath(graphElement); + codeWindow = GetOrCreateCodeWindow(graphElementRef, filename); + // File name of source code file to read from it + codeWindow.EnterFromFile(absolutePlatformPath); + } // Pass line number to automatically scroll to it, if it exists if (graphElement.SourceLine is { } line) diff --git a/Assets/SEE/DataModel/DG/Graph.cs b/Assets/SEE/DataModel/DG/Graph.cs index 7fb96b4ad0..eccff6f781 100644 --- a/Assets/SEE/DataModel/DG/Graph.cs +++ b/Assets/SEE/DataModel/DG/Graph.cs @@ -938,7 +938,7 @@ private void GatherRoots() /// The name of a node metric that reflects the node's depth within the node hierarchy. /// It is equivalent to the node attribute . /// - public const string MetricLevel = "Metric.Level"; + public const string MetricLevel = Metrics.Prefix + "Level"; /// /// Sets the metric of each node to its Level. @@ -1019,7 +1019,7 @@ void MergeNodeAttributes(Node targetNode, Node sourceNode) targetNode.SetInt(attribute.Key, attribute.Value); } // Level may change when merging two graphs into one - else if (value != attribute.Value && attribute.Key != "Metric.Level") + else if (value != attribute.Value && attribute.Key != Metrics.Prefix + "Level") { throw new InvalidOperationException($"Node attribute {attribute.Key} differs in nodes " + $"{targetNode} and {sourceNode}"); diff --git a/Assets/SEE/DataModel/DG/IO/JaCoCoImporter.cs b/Assets/SEE/DataModel/DG/IO/JaCoCoImporter.cs index 29676aa8b1..c741ba8f92 100644 --- a/Assets/SEE/DataModel/DG/IO/JaCoCoImporter.cs +++ b/Assets/SEE/DataModel/DG/IO/JaCoCoImporter.cs @@ -302,7 +302,7 @@ static void AddMetrics(XmlReader xmlReader, Node nodeToAddMetrics) int missed = int.Parse(xmlReader.GetAttribute("missed")!, CultureInfo.InvariantCulture.NumberFormat); int covered = int.Parse(xmlReader.GetAttribute("covered")!, CultureInfo.InvariantCulture.NumberFormat); - string metricNamePrefix = JaCoCo.Prefix + "." + xmlReader.GetAttribute("type"); + string metricNamePrefix = JaCoCo.Prefix + xmlReader.GetAttribute("type"); nodeToAddMetrics.SetInt(metricNamePrefix + "_missed", missed); nodeToAddMetrics.SetInt(metricNamePrefix + "_covered", covered); diff --git a/Assets/SEE/DataModel/DG/StandardNames.cs b/Assets/SEE/DataModel/DG/StandardNames.cs index 9a065c063a..bbe7cd7689 100644 --- a/Assets/SEE/DataModel/DG/StandardNames.cs +++ b/Assets/SEE/DataModel/DG/StandardNames.cs @@ -19,6 +19,18 @@ public enum NumericAttributeNames IssuesTotal } + /// + /// Provides a common prefix for all metrics. + /// + public static class Metrics + { + /// + /// Prefix for all metrics. + /// + public const string Prefix = "Metric."; + } + + /// /// Provides an extension for . /// @@ -35,18 +47,18 @@ public static string Name(this NumericAttributeNames numericAttributeName) { return numericAttributeName switch { - NumericAttributeNames.NumberOfTokens => "Metric.Number_of_Tokens", - NumericAttributeNames.CloneRate => "Metric.Clone_Rate", - NumericAttributeNames.LOC => "Metric.Lines.LOC", - NumericAttributeNames.Complexity => "Metric.Complexity", - NumericAttributeNames.ArchitectureViolations => "Metric.Architecture_Violations", - NumericAttributeNames.Clone => "Metric.Clone", - NumericAttributeNames.Cycle => "Metric.Cycle", - NumericAttributeNames.DeadCode => "Metric.Dead_Code", - NumericAttributeNames.Metric => "Metric.Metric", - NumericAttributeNames.Style => "Metric.Style", - NumericAttributeNames.Universal => "Metric.Universal", - NumericAttributeNames.IssuesTotal => "Metric.IssuesTotal", + NumericAttributeNames.NumberOfTokens => Metrics.Prefix + "Number_of_Tokens", + NumericAttributeNames.CloneRate => Metrics.Prefix + "Clone_Rate", + NumericAttributeNames.LOC => Metrics.Prefix + "Lines.LOC", + NumericAttributeNames.Complexity => Metrics.Prefix + "Complexity", + NumericAttributeNames.ArchitectureViolations => Metrics.Prefix + "Architecture_Violations", + NumericAttributeNames.Clone => Metrics.Prefix + "Clone", + NumericAttributeNames.Cycle => Metrics.Prefix + "Cycle", + NumericAttributeNames.DeadCode => Metrics.Prefix + "Dead_Code", + NumericAttributeNames.Metric => Metrics.Prefix + "Metric", + NumericAttributeNames.Style => Metrics.Prefix + "Style", + NumericAttributeNames.Universal => Metrics.Prefix + "Universal", + NumericAttributeNames.IssuesTotal => Metrics.Prefix + "IssuesTotal", _ => throw new System.Exception("Unknown attribute name " + numericAttributeName) }; } @@ -61,32 +73,32 @@ public static class JaCoCo /// /// The prefix of each JaCoCo metric. /// - public const string Prefix = "Metric.JaCoCo"; + public const string Prefix = Metrics.Prefix + "JaCoCo."; /// /// The number of instructions that were not executed. /// - public const string InstructionMissed = "Metric.JaCoCo.INSTRUCTION_missed"; + public const string InstructionMissed = Prefix + "INSTRUCTION_missed"; /// /// The number of instructions that were executed. /// - public const string InstructionCovered = "Metric.JaCoCo.INSTRUCTION_covered"; + public const string InstructionCovered = Prefix + "INSTRUCTION_covered"; /// /// InstructionCovered / (InstructionCovered + InstructionMissed). /// - public const string PercentageOfInstructionCovered = "Metric.JaCoCo.INSTRUCTION_percentage"; + public const string PercentageOfInstructionCovered = Prefix + "INSTRUCTION_percentage"; /// /// The number of branches (conditional statement constitute branches) that were not executed. /// - public const string BranchMissed = "Metric.JaCoCo.BRANCH_missed"; + public const string BranchMissed = Prefix + "BRANCH_missed"; /// /// The number of branches (conditional statement constitute branches) that were executed. /// - public const string BranchCovered = "Metric.JaCoCo.BRANCH_covered"; + public const string BranchCovered = Prefix + "BRANCH_covered"; /// /// BranchCovered / (BranchMissed + BranchCovered). /// - public const string PercentageOfBranchCovered = "Metric.JaCoCo.BRANCH_percentage"; + public const string PercentageOfBranchCovered = Prefix + "BRANCH_percentage"; /// /// Cyclomatic complexity is defined for each non-abstract method and is also @@ -95,7 +107,7 @@ public static class JaCoCo /// in (linear) combination, generate all possible paths through a method. /// This metric counts the missed such paths. /// - public const string ComplexityMissed = "Metric.JaCoCo.COMPLEXITY_missed"; + public const string ComplexityMissed = Prefix + "COMPLEXITY_missed"; /// /// Cyclomatic complexity is defined for each non-abstract method and is also /// aggregated from methods to classes, packages, and groups they are contained. @@ -103,11 +115,11 @@ public static class JaCoCo /// in (linear) combination, generate all possible paths through a method. /// This metric counts the covered such paths. /// - public const string ComplexityCovered = "Metric.JaCoCo.COMPLEXITY_covered"; + public const string ComplexityCovered = Prefix + "COMPLEXITY_covered"; /// /// ComplexityCovered / (ComplexityMissed + ComplexityCovered). /// - public const string PercentageOfComplexityCovered = "Metric.JaCoCo.COMPLEXITY_percentage"; + public const string PercentageOfComplexityCovered = Prefix + "COMPLEXITY_percentage"; /// /// This metric is defined for all class files that have been compiled with debug information, @@ -116,7 +128,7 @@ public static class JaCoCo /// this line has been executed. /// This metric counts the number of such lines missed. /// - public const string LineMissed = "Metric.JaCoCo.LINE_missed"; + public const string LineMissed = Prefix + "LINE_missed"; /// /// This metric is defined for all class files that have been compiled with debug information, /// such that coverage information for individual lines can be calculated. @@ -124,11 +136,11 @@ public static class JaCoCo /// this line has been executed /// This metric counts the number of such lines covered. /// - public const string LineCovered = "Metric.JaCoCo.LINE_covered"; + public const string LineCovered = Prefix + "LINE_covered"; /// /// LineCovered / (LineMissed + LineCovered). /// - public const string PercentageOfLineCovered = "Metric.JaCoCo.LINE_percentage"; + public const string PercentageOfLineCovered = Prefix + "LINE_percentage"; /// /// A method is considered as executed when at least one of its instructions has been executed. @@ -137,7 +149,7 @@ public static class JaCoCo /// like implicit and thus generated default constructors or initializers for constants. /// This metric counts the number of missed methods. /// - public const string MethodMissed = "Metric.JaCoCo.METHOD_missed"; + public const string MethodMissed = Prefix + "METHOD_missed"; /// /// A method is considered as executed when at least one of its instructions has been executed. /// As JaCoCo works on byte code level also constructors and static initializers are counted as methods. @@ -145,28 +157,28 @@ public static class JaCoCo /// like implicit and thus generated default constructors or initializers for constants. /// This metric counts the number of covered methods. /// - public const string MethodCovered = "Metric.JaCoCo.METHOD_covered"; + public const string MethodCovered = Prefix + "METHOD_covered"; /// /// MethodCovered / (MethodMissed + MethodCovered). /// - public const string PercentageOfMethodCovered = "Metric.JaCoCo.METHOD_percentage"; + public const string PercentageOfMethodCovered = Prefix + "METHOD_percentage"; /// /// A class is considered as executed when at least one of its methods has been executed. /// Note that JaCoCo considers constructors as well as static initializers as methods. /// This metric counts the number of missed classes. /// - public const string ClassMissed = "Metric.JaCoCo.CLASS_missed"; + public const string ClassMissed = Prefix + "CLASS_missed"; /// /// A class is considered as executed when at least one of its methods has been executed. /// Note that JaCoCo considers constructors as well as static initializers as methods. /// This metric counts the number of covered classes. /// - public const string ClassCovered = "Metric.JaCoCo.CLASS_covered"; + public const string ClassCovered = Prefix + "CLASS_covered"; /// /// ClassCovered / (ClassMissed + ClassCovered). /// - public const string PercentageOfClassCovered = "Metric.JaCoCo.CLASS_percentage"; + public const string PercentageOfClassCovered = Prefix + "CLASS_percentage"; } /// diff --git a/Assets/SEE/DataModel/DG/VCSExtensions.cs b/Assets/SEE/DataModel/DG/VCSExtensions.cs new file mode 100644 index 0000000000..686d37fc66 --- /dev/null +++ b/Assets/SEE/DataModel/DG/VCSExtensions.cs @@ -0,0 +1,74 @@ +namespace SEE.DataModel.DG +{ + /// + /// Provides convenience extension properties for the VCS related attributes. + /// + public static class VCSExtensions + { + /// + /// The attribute name for the commitID.. + /// + public const string CommitIDAttribute = "CommitID"; + + /// + /// Returns the commit ID of the . + /// + /// graph whose commit ID is requested + public static bool TryGetCommitID(this Graph graph, out string commitID) + { + return graph.TryGetString(CommitIDAttribute, out commitID); + } + + /// + /// Sets the commit ID of the to + /// + /// graph whose commit ID is to be set + /// value to be set + public static void CommitID(this Graph graph, string value) + { + graph.SetString(CommitIDAttribute, value); + } + + /// + /// Returns the commit ID of the . + /// + /// graph element whose commit ID is requested + public static bool TryGetCommitID(this GraphElement graphElement, out string commitID) + { + return graphElement.ItsGraph.TryGetString(CommitIDAttribute, out commitID); + } + + /// + /// The attribute name for the repository path. + /// + public const string RepositoryPathAttribute = "RepositoryPath"; + + /// + /// Returns the repository path of the . + /// + /// graph whose repository path is requested + public static bool TryGetRepositoryPath(this Graph graph, out string repositoryPath) + { + return graph.TryGetString(RepositoryPathAttribute, out repositoryPath); + } + + /// + /// Sets the repository path of the to + /// + /// graph whose repository path is to be set + /// value to be set + public static void RepositoryPath(this Graph graph, string value) + { + graph.SetString(RepositoryPathAttribute, value); + } + + /// + /// Returns the repository path of the . + /// + /// graph element whose repository path is requested + public static bool TryGetRepositoryPath(this GraphElement graphElement, out string repositoryPath) + { + return graphElement.ItsGraph.TryGetString(RepositoryPathAttribute, out repositoryPath); + } + } +} \ No newline at end of file diff --git a/Assets/SEE/DataModel/DG/VCSExtensions.cs.meta b/Assets/SEE/DataModel/DG/VCSExtensions.cs.meta new file mode 100644 index 0000000000..6533bc12b4 --- /dev/null +++ b/Assets/SEE/DataModel/DG/VCSExtensions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 80930361a53496148bfe4cb7cedd976e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SEE/Game/Charts/AxisContentDropdown.cs b/Assets/SEE/Game/Charts/AxisContentDropdown.cs index 88b23b0580..16b43fb725 100644 --- a/Assets/SEE/Game/Charts/AxisContentDropdown.cs +++ b/Assets/SEE/Game/Charts/AxisContentDropdown.cs @@ -82,7 +82,7 @@ private void UpdateInternal() /// either entry or entry with the ChartManager.MetricPrefix private string GetEntry(string entry) { - return entry.Equals(specialEntry) ? entry : ChartManager.MetricPrefix + entry; + return entry.Equals(specialEntry) ? entry : DataModel.DG.Metrics.Prefix + entry; } /// @@ -126,7 +126,7 @@ private void FillDropDown() { // Add all node metrics without their prefix string[] options = chartContent.AllMetricNames.ToArray(); - int metricPrefixLength = ChartManager.MetricPrefix.Length; + int metricPrefixLength = DataModel.DG.Metrics.Prefix.Length; for (int i = 0; i < options.Length; i++) { options[i] = options[i].Remove(0, metricPrefixLength); diff --git a/Assets/SEE/Game/Charts/ChartContent.cs b/Assets/SEE/Game/Charts/ChartContent.cs index 6ae788c752..2bd2a54c95 100644 --- a/Assets/SEE/Game/Charts/ChartContent.cs +++ b/Assets/SEE/Game/Charts/ChartContent.cs @@ -613,7 +613,7 @@ private void GetAllNumericAttributes() Debug.LogWarning("There are no nodes for showing metrics.\n"); } #endif - foreach (string cname in Attributable.NumericAttributeNames.Where(cname => cname.StartsWith(ChartManager.MetricPrefix))) + foreach (string cname in Attributable.NumericAttributeNames.Where(cname => cname.StartsWith(Metrics.Prefix))) { AllMetricNames.Add(cname); } diff --git a/Assets/SEE/Game/Charts/ChartManager.cs b/Assets/SEE/Game/Charts/ChartManager.cs index 9002a1e56a..c2732b1887 100644 --- a/Assets/SEE/Game/Charts/ChartManager.cs +++ b/Assets/SEE/Game/Charts/ChartManager.cs @@ -20,7 +20,6 @@ // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. using SEE.Controls; -using SEE.DataModel; using SEE.GO; using SEE.Utils; using UnityEngine; @@ -32,11 +31,6 @@ namespace SEE.Game.Charts /// public class ChartManager : MonoBehaviour { - /// - /// The prefix of the name of a metric shown in a chart. - /// - public const string MetricPrefix = "Metric."; - /// /// The instance of the , to ensure there will be only one. /// diff --git a/Assets/SEE/Game/City/SEECity.cs b/Assets/SEE/Game/City/SEECity.cs index 936c6b4d1d..a5e58d3bbd 100644 --- a/Assets/SEE/Game/City/SEECity.cs +++ b/Assets/SEE/Game/City/SEECity.cs @@ -305,7 +305,7 @@ public virtual async UniTask LoadDataAsync() { try { - using (LoadingSpinner.ShowDeterminate($"Loading city \"{gameObject.name}\"...", + using (LoadingSpinner.ShowDeterminate($"Loading city \"{gameObject.name}\"...\n", out Action reportProgress)) { void ReportProgress(float x) diff --git a/Assets/SEE/Game/HolisticMetrics/Metrics/AverageCommentDensity.cs b/Assets/SEE/Game/HolisticMetrics/Metrics/AverageCommentDensity.cs index e279be6912..6b3ef95533 100644 --- a/Assets/SEE/Game/HolisticMetrics/Metrics/AverageCommentDensity.cs +++ b/Assets/SEE/Game/HolisticMetrics/Metrics/AverageCommentDensity.cs @@ -11,7 +11,7 @@ internal class AverageCommentDensity : Metric /// /// We will try to get this attribute for each node. Should be the comment density for each node. /// - private const string attributeName = "Metric.Comment.Density"; + private const string attributeName = SEE.DataModel.DG.Metrics.Prefix + "Comment.Density"; /// /// Calculates the average comment density for the nodes of the given . diff --git a/Assets/SEE/Game/HolisticMetrics/Metrics/AverageLinesOfCode.cs b/Assets/SEE/Game/HolisticMetrics/Metrics/AverageLinesOfCode.cs index 1d7dc8bb66..3a6aeab3b6 100644 --- a/Assets/SEE/Game/HolisticMetrics/Metrics/AverageLinesOfCode.cs +++ b/Assets/SEE/Game/HolisticMetrics/Metrics/AverageLinesOfCode.cs @@ -12,7 +12,7 @@ internal class AverageLinesOfCode : Metric /// /// This const contains the name of the attribute we will try to get for each node, the lines of code metric. /// - private const string attributeName = "Metric.Lines.LOC"; + private const string attributeName = SEE.DataModel.DG.Metrics.Prefix + "Lines.LOC"; /// /// Calculates the average lines of code for the nodes of the given . diff --git a/Assets/SEE/Game/HolisticMetrics/Metrics/LinesOfCode.cs b/Assets/SEE/Game/HolisticMetrics/Metrics/LinesOfCode.cs index 7ac1654800..6d4f268caf 100644 --- a/Assets/SEE/Game/HolisticMetrics/Metrics/LinesOfCode.cs +++ b/Assets/SEE/Game/HolisticMetrics/Metrics/LinesOfCode.cs @@ -13,7 +13,7 @@ internal class LinesOfCode : Metric /// This is the attribute name which we will try to get for each node. This should give us the lines of code /// metric for each node. /// - private const string attributeName = "Metric.Lines.LOC"; + private const string attributeName = SEE.DataModel.DG.Metrics.Prefix + "Lines.LOC"; /// /// Returns the lines of code metric from each node of the graph underlying diff --git a/Assets/SEE/GraphProviders/Evolution.meta b/Assets/SEE/GraphProviders/Evolution.meta new file mode 100644 index 0000000000..b057b423ea --- /dev/null +++ b/Assets/SEE/GraphProviders/Evolution.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c21c74c64e546c94d8537db4db047a99 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SEE/GraphProviders/GraphProviderFactory.cs b/Assets/SEE/GraphProviders/GraphProviderFactory.cs index 701243d204..e13210375e 100644 --- a/Assets/SEE/GraphProviders/GraphProviderFactory.cs +++ b/Assets/SEE/GraphProviders/GraphProviderFactory.cs @@ -27,6 +27,7 @@ internal static GraphProvider NewInstance(GraphProviderKind kind) GraphProviderKind.Pipeline => new PipelineGraphProvider(), GraphProviderKind.JaCoCo => new JaCoCoGraphProvider(), GraphProviderKind.MergeDiff => new MergeDiffGraphProvider(), + GraphProviderKind.VCS => new VCSGraphProvider(), GraphProviderKind.LSP => new LSPGraphProvider(), _ => throw new NotImplementedException($"Not implemented for {kind}") }; diff --git a/Assets/SEE/GraphProviders/GraphProviderKind.cs b/Assets/SEE/GraphProviders/GraphProviderKind.cs index 2e48565a47..85e06c9cd9 100644 --- a/Assets/SEE/GraphProviders/GraphProviderKind.cs +++ b/Assets/SEE/GraphProviders/GraphProviderKind.cs @@ -30,6 +30,10 @@ public enum GraphProviderKind /// Dashboard, /// + /// For . + /// + VCS, + /// /// For . /// Reflexion, diff --git a/Assets/SEE/GraphProviders/VCSGraphProvider.cs b/Assets/SEE/GraphProviders/VCSGraphProvider.cs new file mode 100644 index 0000000000..04ee0ba92d --- /dev/null +++ b/Assets/SEE/GraphProviders/VCSGraphProvider.cs @@ -0,0 +1,409 @@ +using Cysharp.Threading.Tasks; +using LibGit2Sharp; +using SEE.DataModel.DG; +using SEE.Game.City; +using SEE.UI.RuntimeConfigMenu; +using SEE.Utils.Config; +using SEE.Utils.Paths; +using Sirenix.OdinInspector; +using Sirenix.Serialization; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using UnityEngine; +using SEE.Scanner; +using System.Threading; +using Microsoft.Extensions.FileSystemGlobbing; +using SEE.Utils; + +namespace SEE.GraphProviders +{ + /// + /// Creates a graph based on the content of a version control system. + /// Nodes represent directories and files. Their nesting corresponds to + /// the directory structure of the repository. Files are leaf nodes. + /// Files nodes contain metrics that can be gathered based on a simple + /// lexical analysis, such as Halstead, McCabe and lines of code. + /// + public class VCSGraphProvider : GraphProvider + { + /// + /// The path to the git repository. + /// + [ShowInInspector, Tooltip("Path to the git repository."), HideReferenceObjectPicker] + public DirectoryPath RepositoryPath = new(); + + /// + /// The commit id. + /// + [ShowInInspector, Tooltip("The new commit id."), HideReferenceObjectPicker] + public string CommitID = ""; + + /// + /// The list of path globbings to include or exclude files. + /// + [OdinSerialize] + [ShowInInspector, ListDrawerSettings(ShowItemCount = true), + Tooltip("Path globbings to include (true) or exclude files (false)"), RuntimeTab(GraphProviderFoldoutGroup), HideReferenceObjectPicker] + public Dictionary PathGlobbing = new() + { + { "**/*", true } + }; + + public override GraphProviderKind GetKind() + { + return GraphProviderKind.VCS; + } + + /// + /// Loads the metrics and nodes from the given git repository and commitID into the . + /// + /// The graph into which the metrics shall be loaded + /// This parameter is currently ignored. + /// This parameter is currently ignored. + /// This parameter is currently ignored. + public override async UniTask ProvideAsync(Graph graph, AbstractSEECity city, Action changePercentage = null, + CancellationToken token = default) + { + CheckArguments(city); + return await UniTask.FromResult(GetVCSGraph(PathGlobbing, RepositoryPath.Path, CommitID)); + } + + /// + /// Checks whether the assumptions on and + /// and hold. + /// If not, exceptions are thrown accordingly. + /// + /// To be checked + /// thrown in case , + /// or + /// is undefined or does not exist or is null + protected void CheckArguments(AbstractSEECity city) + { + if (string.IsNullOrEmpty(RepositoryPath.Path)) + { + throw new ArgumentException("Empty repository path.\n"); + } + if (!Directory.Exists(RepositoryPath.Path)) + { + throw new ArgumentException($"Directory {RepositoryPath.Path} does not exist.\n"); + } + if (string.IsNullOrEmpty(CommitID)) + { + throw new ArgumentException("Empty CommitID.\n"); + } + if (city == null) + { + throw new ArgumentException("The given city is null.\n"); + } + } + + /// + /// The node type for directories. + /// + private const string directoryNodeType = "Directory"; + /// + /// The node type for files. + /// + private const string fileNodeType = "File"; + + /// + /// Builds the VCS graph with specific metrics. + /// + /// The paths which get included/excluded. + /// The path to the repository. + /// The commitID where the files exist. + /// the graph. + private static Graph GetVCSGraph(Dictionary pathGlobbing, string repositoryPath, string commitID) + { + string[] pathSegments = repositoryPath.Split(Path.DirectorySeparatorChar); + + Graph graph = new(repositoryPath, pathSegments[^1]); + graph.CommitID(commitID); + graph.RepositoryPath(repositoryPath); + + // The main directory. + NewNode(graph, pathSegments[^1], directoryNodeType, pathSegments[^1]); + + using (Repository repo = new(repositoryPath)) + { + LibGit2Sharp.Tree tree = repo.Lookup(commitID).Tree; + // Get all files using "git ls-tree -r --name-only". + IEnumerable files = GetFilteredFiles(ListTree(tree), pathGlobbing); + + // Build the graph structure. + foreach (string filePath in files.Where(path => !string.IsNullOrEmpty(path))) + { + string[] filePathSegments = filePath.Split('/'); + // Files in the main directory. + if (filePathSegments.Length == 1) + { + graph.GetNode(pathSegments[^1]).AddChild(NewNode(graph, filePath, fileNodeType, filePath)); + } + // Other directories/files. + else + { + BuildGraphFromPath(filePath, null, null, graph, graph.GetNode(pathSegments[^1])); + } + } + AddMetricsToNode(graph, repo, commitID); + } + graph.FinalizeNodeHierarchy(); + return graph; + } + + /// + /// Filtering the files after include/exclude patterns. + /// + /// all files, unfiltered + /// the include/exclude patterns + /// filtered files + static List GetFilteredFiles(List files, Dictionary pathGlobbing) + { + Matcher matcher = new(); + + foreach(KeyValuePair pattern in pathGlobbing) + { + if (pattern.Value) + { + matcher.AddInclude(pattern.Key); + } + else + { + matcher.AddExclude(pattern.Key); + } + } + + List matchedFiles = new(); + + foreach (string file in files) + { + if (matcher.Match(file).HasMatches) + { + matchedFiles.Add(file); + } + } + + return matchedFiles; + } + + /// + /// Creates and adds a new node to and returns it. + /// + /// Where to add the node + /// Unique ID of the new node + /// Type of the new node + /// The source name of the node + /// a new node added to + public static Node NewNode(Graph graph, string id, string type, string name) + { + Node result = new() + { + SourceName = name, + ID = id, + Type = type + }; + result.Filename = result.SourceName; + result.Directory = Path.GetDirectoryName(result.ID); + graph.AddNode(result); + return result; + } + + /// + /// Creates a new node for each element of a filepath, that does not + /// already exists in the graph. + /// + /// The remaining part of the path + /// The parent node from the current element of the path + /// The path of the current parent, which will eventually be part of the ID + /// The graph to which the new node belongs to + /// The root node of the main directory + /// The node for the given path or null. + public static Node BuildGraphFromPath(string path, Node parent, string parentPath, + Graph graph, Node rootNode) + { + string[] pathSegments = path.Split('/'); + string nodePath = string.Join('/', pathSegments, 1, pathSegments.Length - 1); + + // Current pathSegment is in the main directory. + if (parentPath == null) + { + Node currentSegmentNode = graph.GetNode(pathSegments[0]); + + // Directory exists already. + if (currentSegmentNode != null) + { + return BuildGraphFromPath(nodePath, currentSegmentNode, pathSegments[0], graph, rootNode); + } + + // Directory does not exist. + if (currentSegmentNode == null && pathSegments.Length > 1 && parent == null) + { + rootNode.AddChild(NewNode(graph, pathSegments[0], directoryNodeType, pathSegments[0])); + return BuildGraphFromPath(nodePath, graph.GetNode(pathSegments[0]), + pathSegments[0], graph, rootNode); + } + } + + // Current pathSegment is not in the main directory. + if (parentPath != null) + { + string currentPathSegment = parentPath + '/' + pathSegments[0]; + Node currentPathSegmentNode = graph.GetNode(currentPathSegment); + + // The node for the current pathSegment exists. + if (currentPathSegmentNode != null) + { + return BuildGraphFromPath(nodePath, currentPathSegmentNode, + currentPathSegment, graph, rootNode); + } + + // The node for the current pathSegment does not exist, and the node is a directory. + if (currentPathSegmentNode == null && + pathSegments.Length > 1) + { + parent.AddChild(NewNode(graph, currentPathSegment, directoryNodeType, pathSegments[0])); + return BuildGraphFromPath(nodePath, graph.GetNode(currentPathSegment), + currentPathSegment, graph, rootNode); + } + + // The node for the current pathSegment does not exist, and the node is a file. + if (currentPathSegmentNode == null && + pathSegments.Length == 1) + { + Node addedFileNode = NewNode(graph, currentPathSegment, fileNodeType, pathSegments[0]); + parent.AddChild(addedFileNode); + return addedFileNode; + } + } + + return null; + } + + /// + /// Gets the paths from a repository at the time of a given commitID. + /// It is equivalent to "git ls-tree --name-only -r commitID" + /// + /// The tree of the given commit. + /// a list of paths. + private static List ListTree(LibGit2Sharp.Tree tree) + { + List fileList = new(); + + foreach (TreeEntry entry in tree) + { + if (entry.TargetType == TreeEntryTargetType.Blob) + { + fileList.Add(entry.Path); + } + else if (entry.TargetType == TreeEntryTargetType.Tree) + { + LibGit2Sharp.Tree subtree = (LibGit2Sharp.Tree)entry.Target; + fileList.AddRange(ListTree(subtree)); + } + } + + return fileList; + } + + /// + /// Retrieves the token stream for given file content from its repository and commit ID. + /// + /// The filePath from the node. + /// The repository from which the file content is retrieved. + /// The commitID where the files exist. + /// The language the given text is written in. + /// The token stream for the specified file and commit. + public static IEnumerable RetrieveTokens(string filePath, Repository repository, string commitID, + TokenLanguage language) + { + Blob blob = repository.Lookup($"{commitID}:{filePath}"); + + if (blob != null) + { + string fileContent = blob.GetContentText(); + return SEEToken.FromString(fileContent, language); + } + else + { + // Blob does not exist. + return Enumerable.Empty(); + } + } + + /// + /// Adds Halstead, McCabe and lines of code metrics to the corresponding node for the supported TokenLanguages + /// in . + /// Otherwise, metrics are not available. + /// + /// The graph where the metric should be added. + /// The repository from which the file content is retrieved. + /// The commitID where the files exist. + protected static void AddMetricsToNode(Graph graph, Repository repository, string commitID) + { + foreach (Node node in graph.Nodes()) + { + if (node.Type == fileNodeType) + { + string filePath = Filenames.OnCurrentPlatform(node.ID); + TokenLanguage language = TokenLanguage.FromFileExtension(Path.GetExtension(filePath).TrimStart('.')); + if (language != TokenLanguage.Plain) + { + IEnumerable tokens = RetrieveTokens(filePath, repository, commitID, language); + int complexity = TokenMetrics.CalculateMcCabeComplexity(tokens); + int linesOfCode = TokenMetrics.CalculateLinesOfCode(tokens); + TokenMetrics.HalsteadMetrics halsteadMetrics = TokenMetrics.CalculateHalsteadMetrics(tokens); + node.SetInt(Metrics.Prefix + "LOC", linesOfCode); + node.SetInt(Metrics.Prefix + "McCabe_Complexity", complexity); + node.SetInt(Metrics.Prefix + "Halstead.Distinct_Operators", halsteadMetrics.DistinctOperators); + node.SetInt(Metrics.Prefix + "Halstead.Distinct_Operands", halsteadMetrics.DistinctOperands); + node.SetInt(Metrics.Prefix + "Halstead.Total_Operators", halsteadMetrics.TotalOperators); + node.SetInt(Metrics.Prefix + "Halstead.Total_Operands", halsteadMetrics.TotalOperands); + node.SetInt(Metrics.Prefix + "Halstead.Program_Vocabulary", halsteadMetrics.ProgramVocabulary); + node.SetInt(Metrics.Prefix + "Halstead.Program_Length", halsteadMetrics.ProgramLength); + node.SetFloat(Metrics.Prefix + "Halstead.Estimated_Program_Length", halsteadMetrics.EstimatedProgramLength); + node.SetFloat(Metrics.Prefix + "Halstead.Volume", halsteadMetrics.Volume); + node.SetFloat(Metrics.Prefix + "Halstead.Difficulty", halsteadMetrics.Difficulty); + node.SetFloat(Metrics.Prefix + "Halstead.Effort", halsteadMetrics.Effort); + node.SetFloat(Metrics.Prefix + "Halstead.Time_Required_To_Program", halsteadMetrics.TimeRequiredToProgram); + node.SetFloat(Metrics.Prefix + "Halstead.Number_Of_Delivered_Bugs", halsteadMetrics.NumberOfDeliveredBugs); + } + } + } + } + + #region Config I/O + + /// + /// Label of attribute in the configuration file. + /// + private const string pathGlobbingLabel = "PathGlobbing"; + + /// + /// Label of attribute in the configuration file. + /// + private const string repositoryPathLabel = "RepositoryPath"; + + /// + /// Label of attribute in the configuration file. + /// + private const string commitIDLabel = "CommitID"; + + protected override void SaveAttributes(ConfigWriter writer) + { + writer.Save(PathGlobbing, pathGlobbingLabel); + writer.Save(CommitID, commitIDLabel); + RepositoryPath.Save(writer, repositoryPathLabel); + } + + protected override void RestoreAttributes(Dictionary attributes) + { + ConfigIO.Restore(attributes, pathGlobbingLabel, ref PathGlobbing); + ConfigIO.Restore(attributes, commitIDLabel, ref CommitID); + RepositoryPath.Restore(attributes, repositoryPathLabel); + } + + #endregion + } +} diff --git a/Assets/SEE/GraphProviders/VCSGraphProvider.cs.meta b/Assets/SEE/GraphProviders/VCSGraphProvider.cs.meta new file mode 100644 index 0000000000..723ca24300 --- /dev/null +++ b/Assets/SEE/GraphProviders/VCSGraphProvider.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f09407cf375a243148d5a40dd5719968 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SEE/SEE.asmdef b/Assets/SEE/SEE.asmdef index 9e2d7bd770..5fc4bb46a5 100644 --- a/Assets/SEE/SEE.asmdef +++ b/Assets/SEE/SEE.asmdef @@ -66,7 +66,8 @@ "Supercluster.KDTree.Standard.dll", "Markdig.dll", "System.Collections.Immutable.dll", - "MoreLinq.dll" + "MoreLinq.dll", + "Microsoft.Extensions.FileSystemGlobbing.dll" ], "autoReferenced": false, "defineConstraints": [], diff --git a/Assets/SEE/Scanner.meta b/Assets/SEE/Scanner.meta new file mode 100644 index 0000000000..0ff72623ef --- /dev/null +++ b/Assets/SEE/Scanner.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7bed03afa7a43b84c99e933f870d7b06 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SEE/UI/Window/CodeWindow/Input/SEEToken.cs b/Assets/SEE/Scanner/SEEToken.cs similarity index 96% rename from Assets/SEE/UI/Window/CodeWindow/Input/SEEToken.cs rename to Assets/SEE/Scanner/SEEToken.cs index 5af3440709..c7a035dca7 100644 --- a/Assets/SEE/UI/Window/CodeWindow/Input/SEEToken.cs +++ b/Assets/SEE/Scanner/SEEToken.cs @@ -5,7 +5,7 @@ using Antlr4.Runtime; using UnityEngine; -namespace SEE.UI.Window.CodeWindow +namespace SEE.Scanner { /// /// Represents a token from a source code file, including and a . @@ -163,6 +163,13 @@ public class Type /// public static readonly Type Keyword = new("Keywords", "D988F2"); // purple + /// + /// Branch keyword tokens. + /// + /// We want s have the same color as + /// other s. + public static readonly Type BranchKeyword = new("BranchKeywords", "D988F2"); // purple + /// /// Number literal tokens. This includes integer literals, floating point literals, etc. /// @@ -241,7 +248,7 @@ public static Type FromAntlrType(TokenLanguage language, string symbolicName) Type type = AllTokens.SingleOrDefault(x => x.Name.Equals(typeName)); if (type == null) { - Debug.LogError($"Unknown token type: {typeName}"); + Debug.LogError($"Unknown token type: {typeName}/{symbolicName}"); } return type ?? Unknown; } diff --git a/Assets/SEE/UI/Window/CodeWindow/Input/SEEToken.cs.meta b/Assets/SEE/Scanner/SEEToken.cs.meta similarity index 100% rename from Assets/SEE/UI/Window/CodeWindow/Input/SEEToken.cs.meta rename to Assets/SEE/Scanner/SEEToken.cs.meta diff --git a/Assets/SEE/UI/Window/CodeWindow/Input/TokenLanguage.cs b/Assets/SEE/Scanner/TokenLanguage.cs similarity index 88% rename from Assets/SEE/UI/Window/CodeWindow/Input/TokenLanguage.cs rename to Assets/SEE/Scanner/TokenLanguage.cs index 7c3be57709..04f43a9b3a 100644 --- a/Assets/SEE/UI/Window/CodeWindow/Input/TokenLanguage.cs +++ b/Assets/SEE/Scanner/TokenLanguage.cs @@ -3,7 +3,7 @@ using System.Linq; using Antlr4.Runtime; -namespace SEE.UI.Window.CodeWindow +namespace SEE.Scanner { /// /// Represents a language a is in. @@ -48,6 +48,11 @@ public class TokenLanguage /// public ISet Keywords { get; } + /// + /// Symbolic names for branch keywords of a language. + /// + public ISet BranchKeywords { get; } + /// /// Symbolic names for number literals of a language. This includes integer literals, floating point literals, etc. /// @@ -94,19 +99,27 @@ public class TokenLanguage }; /// - /// Set of antlr type names for Java keywords. + /// Set of antlr type names for Java keywords excluding . /// private static readonly HashSet javaKeywords = new() { - "ABSTRACT", "ASSERT", "BOOLEAN", "BREAK", "BYTE", "CASE", "CATCH", "CHAR", "CLASS", "CONST", "CONTINUE", - "DEFAULT", "DO", "DOUBLE", "ELSE", "ENUM", "EXPORTS", "EXTENDS", "FINAL", "FINALLY", "FLOAT", "FOR", - "IF", "GOTO", "IMPLEMENTS", "IMPORT", "INSTANCEOF", "INT", "INTERFACE", "LONG", "MODULE", "NATIVE", "NEW", + "ABSTRACT", "ASSERT", "BOOLEAN", "BREAK", "BYTE", "CASE", "CATCH", "CHAR", "CLASS", "CONST", "CONTINUE", + "DEFAULT", "DO", "DOUBLE", "ELSE", "ENUM", "EXPORTS", "EXTENDS", "FINAL", "FINALLY", "FLOAT", + "GOTO", "IMPLEMENTS", "IMPORT", "INSTANCEOF", "INT", "INTERFACE", "LONG", "MODULE", "NATIVE", "NEW", "OPEN", "OPERNS", "PACKAGE", "PRIVATE", "PROTECTED", "PROVIDES", "PUBLIC", "REQUIRES", "RETURN", "SHORT", - "STATIC", "STRICTFP", "SUPER", "SWITCH", "SYNCHRONIZED", "THIS", "THROW", "THROWS", "TO", "TRANSIENT", - "TRANSITIVE", "TRY", "USES", "VOID", "VOLATILE", "WHILE", "WITH", "UNDER_SCORE", + "STATIC", "STRICTFP", "SUPER", "SYNCHRONIZED", "THIS", "THROW", "THROWS", "TO", "TRANSIENT", + "TRANSITIVE", "USES", "VOID", "VOLATILE", "WITH", "UNDER_SCORE", "BooleanLiteral", "NullLiteral" }; + /// + /// Set of antlr type names for Java branch keywords. + /// + private static readonly HashSet javaBranchKeywords = new() + { + "FOR", "IF", "SWITCH", "TRY", "WHILE" + }; + /// /// Set of antlr type names for Java integer and floating point literals. /// @@ -162,7 +175,7 @@ public class TokenLanguage }; /// - /// Set of antlr type names for CSharp keywords. + /// Set of antlr type names for CSharp keywords excluding . /// private static readonly HashSet cSharpKeywords = new() { @@ -170,13 +183,13 @@ public class TokenLanguage "ABSTRACT", "ADD", "ALIAS", "ARGLIST", "AS", "ASCENDING", "ASYNC", "AWAIT", "BASE", "BOOL", "BREAK", "BY", "BYTE", "CASE", "CATCH", "CHAR", "CHECKED", "CLASS", "CONST", "CONTINUE", "DECIMAL", "DEFAULT", "DELEGATE", "DESCENDING", "DO", "DOUBLE", "DYNAMIC", "ELSE", "ENUM", "EQUALS", "EVENT", "EXPLICIT", "EXTERN", "FALSE", - "FINALLY", "FIXED", "FLOAT", "FOR", "FOREACH", "FROM", "GET", "GOTO", "GROUP", "IF", "IMPLICIT", "IN", "INT", + "FINALLY", "FIXED", "FLOAT", "FROM", "GET", "GOTO", "GROUP", "IMPLICIT", "IN", "INT", "INTERFACE", "INTERNAL", "INTO", "IS", "JOIN", "LET", "LOCK", "LONG", "NAMEOF", "NAMESPACE", "NEW", "NULL_", "OBJECT", "ON", "OPERATOR", "ORDERBY", "OUT", "OVERRIDE", "PARAMS", "PARTIAL", "PRIVATE", "PROTECTED", "PUBLIC", "READONLY", "REF", "REMOVE", "RETURN", "SBYTE", "SEALED", "SELECT", "SET", "SHORT", "SIZEOF", - "STACKALLOC", "STATIC", "STRING", "STRUCT", "SWITCH", "THIS", "THROW", "TRUE", "TRY", "TYPEOF", "UINT", + "STACKALLOC", "STATIC", "STRING", "STRUCT", "THIS", "THROW", "TRUE", "TYPEOF", "UINT", "ULONG", "UNCHECKED", "UNMANAGED", "UNSAFE", "USHORT", "USING", "VAR", "VIRTUAL", "VOID", "VOLATILE", "WHEN", - "WHERE", "WHILE", "YIELD", "SHARP", + "WHERE", "YIELD", "SHARP", // Directive keywords (anything within a directive is treated as a keyword, similar to IDEs "DIRECTIVE_TRUE", "DIRECTIVE_FALSE", "DEFINE", "UNDEF", "DIRECTIVE_IF", "ELIF", "DIRECTIVE_ELSE", "ENDIF", "LINE", "ERROR", "WARNING", "REGION", "ENDREGION", "PRAGMA", "NULLABLE", @@ -184,6 +197,14 @@ public class TokenLanguage "DIRECTIVE_OP_EQ", "DIRECTIVE_OP_NE", "DIRECTIVE_OP_AND", "DIRECTIVE_OP_OR", "CONDITIONAL_SYMBOL" }; + /// + /// Set of antlr type names for CSharp branch keywords. + /// + private static readonly HashSet cSharpBranchKeywords = new() + { + "FOR", "FOREACH", "IF", "SWITCH", "TRY", "WHILE" + }; + /// /// Set of antlr type names for CSharp integer and floating point literals. /// @@ -261,25 +282,33 @@ public class TokenLanguage }; /// - /// Set of antlr type names for CPP keywords. + /// Set of antlr type names for CPP keywords excluding . /// private static readonly HashSet cppKeywords = new() { - "Alignas", "Alignof", "Asm", "Auto", "Bool", "Break", "Case", - "Catch", "Char", "Char16", "Char32", "Class", "Const", "Constexpr", "Const_cast", - "Continue", "Decltype", "Default", "Delete", "Do", "Double", "Dynamic_cast", - "Else", "Enum", "Explicit", "Export", "Extern", "False_", "Final", "Float", - "For", "Friend", "Goto", "If", "Inline", "Int", "Long", "Mutable", "Namespace", + "Alignas", "Alignof", "Asm", "Auto", "Bool", "Break", "Case", "Catch", "Continue", + "Char", "Char16", "Char32", "Class", "Const", "Constexpr", "Const_cast", + "Decltype", "Default", "Delete", "Do", "Double", "Dynamic_cast", "Else", + "Enum", "Explicit", "Export", "Extern", "False_", "Final", "Float", + "Friend", "Goto", "Inline", "Int", "Long", "Mutable", "Namespace", "New", "Noexcept", "Nullptr", "Operator", "Override", "Private", "Protected", "Public", "Register", "Reinterpret_cast", "Return", "Short", "Signed", - "Sizeof", "Static", "Static_assert", "Static_cast", "Struct", "Switch", - "Template", "This", "Thread_local", "Throw", "True_", "Try", "Typedef", + "Sizeof", "Static", "Static_assert", "Static_cast", "Struct", + "Template", "This", "Thread_local", "Throw", "True_", "Typedef", "Typeid_", "Typename_", "Union", "Unsigned", "Using", "Virtual", "Void", - "Volatile", "Wchar", "While", + "Volatile", "Wchar", "BooleanLiteral", "PointerLiteral", "UserDefinedLiteral", "MultiLineMacro", "Directive" }; + /// + /// Set of antlr type names for CPP branch keywords. + /// + private static readonly HashSet cppBranchKeywords = new() + { + "For", "If", "Switch", "Try", "While" + }; + /// /// Set of antlr type names for CPP integer and floating point literals. /// @@ -344,6 +373,9 @@ public class TokenLanguage /// Set of antlr type names for keywords. There are none here. private static readonly HashSet plainKeywords = new(); + /// Set of antlr type names for branch keywords. There are none here. + private static readonly HashSet plainBranchKeywords = new(); + /// Set of antlr type names for numbers. private static readonly HashSet plainNumbers = new(); @@ -380,25 +412,25 @@ public class TokenLanguage /// /// Token Language for Java. /// - public static readonly TokenLanguage Java = new(javaFileName, javaExtensions, javaKeywords, javaNumbers, + public static readonly TokenLanguage Java = new(javaFileName, javaExtensions, javaKeywords, javaBranchKeywords, javaNumbers, javaStrings, javaPunctuation, javaIdentifiers, javaWhitespace, javaNewlines, javaComments); /// /// Token Language for C#. /// - public static readonly TokenLanguage CSharp = new(cSharpFileName, cSharpExtensions, cSharpKeywords, cSharpNumbers, + public static readonly TokenLanguage CSharp = new(cSharpFileName, cSharpExtensions, cSharpKeywords, cSharpBranchKeywords, cSharpNumbers, cSharpStrings, cSharpPunctuation, cSharpIdentifiers, cSharpWhitespace, cSharpNewlines, cSharpComments); /// /// Token Language for CPP. /// - public static readonly TokenLanguage CPP = new(cppFileName, cppExtensions, cppKeywords, cppNumbers, + public static readonly TokenLanguage CPP = new(cppFileName, cppExtensions, cppKeywords, cppBranchKeywords, cppNumbers, cppStrings, cppPunctuation, cppIdentifiers, cppWhitespace, cppNewlines, cppComments); /// /// Token language for plain text. /// - public static readonly TokenLanguage Plain = new(plainFileName, plainExtensions, plainKeywords, plainNumbers, + public static readonly TokenLanguage Plain = new(plainFileName, plainExtensions, plainKeywords, plainBranchKeywords, plainNumbers, plainStrings, plainPunctuation, plainIdentifiers, plainWhitespace, plainNewlines, plainComments); #endregion @@ -417,8 +449,9 @@ public class TokenLanguage /// Whitespace for this language /// Newlines for this language /// Comments for this language + /// Branches for this language /// Number of spaces a tab is equivalent to - private TokenLanguage(string lexerFileName, ISet fileExtensions, ISet keywords, + private TokenLanguage(string lexerFileName, ISet fileExtensions, ISet keywords, ISet branchKeywords, ISet numberLiterals, ISet stringLiterals, ISet punctuation, ISet identifiers, ISet whitespace, ISet newline, ISet comments, int tabWidth = defaultTabWidth) @@ -436,6 +469,7 @@ private TokenLanguage(string lexerFileName, ISet fileExtensions, ISet + /// Provides metrics calculated based on code tokens. + /// + public static class TokenMetrics + { + /// + /// Calculates the McCabe cyclomatic complexity for provided code. + /// + /// The tokens used for which the complexity should be calculated. + /// Returns the McCabe cyclomatic complexity. + public static int CalculateMcCabeComplexity(IEnumerable tokens) + { + int complexity = 1; // Starting complexity for a single method or function. + + // Count decision points (branches). + complexity += tokens.Count(t => t.TokenType == SEEToken.Type.BranchKeyword); + + return complexity; + } + + /// + /// Helper record to store Halstead metrics. + /// + /// The number of distinct operators in the code. + /// The number of distinct operands in the code. + /// The total number of operators in the code. + /// The total number of operands in the code. + /// The program vocabulary, i.e. the sum of distinct operators and operands. + /// The program length, i.e. the sum of total operators and operands. + /// The estimated program length based on the program vocabulary. + /// The program volume, which is a measure of the program's size and complexity. + /// The program difficulty, which is a measure of how difficult the code is to understand and modify. + /// The program effort, which is a measure of the effort required to understand and modify the code. + /// The estimated time required to program the code, based on the program effort. + /// The estimated number of delivered bugs in the code, based on the program volume. + public record HalsteadMetrics( + int DistinctOperators, + int DistinctOperands, + int TotalOperators, + int TotalOperands, + int ProgramVocabulary, + int ProgramLength, + float EstimatedProgramLength, + float Volume, + float Difficulty, + float Effort, + float TimeRequiredToProgram, + float NumberOfDeliveredBugs + ); + + /// + /// Calculates the Halstead metrics for provided code. + /// + /// The tokens for which the metrics should be calculated. + /// Returns the Halstead metrics. + public static HalsteadMetrics CalculateHalsteadMetrics(IEnumerable tokens) + { + // Set of token types which are operands. + HashSet operandTypes = new() + { + SEEToken.Type.Identifier, + SEEToken.Type.Keyword, + SEEToken.Type.BranchKeyword, + SEEToken.Type.NumberLiteral, + SEEToken.Type.StringLiteral + }; + + // Identify operands. + HashSet operands = new(tokens.Where(t => operandTypes.Contains(t.TokenType)).Select(t => t.Text)); + + // Identify operators. + HashSet operators = new(tokens.Where(t => t.TokenType == SEEToken.Type.Punctuation).Select(t => t.Text)); + + // Count the total number of operands and operators. + int totalOperands = tokens.Count(t => operandTypes.Contains(t.TokenType)); + int totalOperators = tokens.Count(t => t.TokenType == SEEToken.Type.Punctuation); + + // Derivative Halstead metrics. + int programVocabulary = operators.Count + operands.Count; + int programLength = totalOperators + totalOperands; + float estimatedProgramLength = operators.Count == 0 ? 0 : (float)((operators.Count * Mathf.Log(operators.Count, 2) + operands.Count * Mathf.Log(operands.Count, 2))); + float volume = programVocabulary == 0 ? 0 : (float)(programLength * Mathf.Log(programVocabulary, 2)); + float difficulty = operands.Count == 0 ? 0 : operators.Count / 2.0f * (totalOperands / (float)operands.Count); + float effort = difficulty * volume; + float timeRequiredToProgram = effort / 18.0f; // Formula: Time T = effort E / S, where S = Stroud's number of psychological 'moments' per second; typically a figure of 18 is used in Software Science. + float numberOfDeliveredBugs = volume / 3000.0f; // Formula: Bugs B = effort E^(2/3) / 3000 or bugs B = volume V / 3000 are both used. 3000 is an empirical estimate. + + return new HalsteadMetrics( + operators.Count, + operands.Count, + totalOperators, + totalOperands, + programVocabulary, + programLength, + estimatedProgramLength, + volume, + difficulty, + effort, + timeRequiredToProgram, + numberOfDeliveredBugs + ); + } + + /// + /// Calculates the number of lines of code for the provided token stream, excluding comments. + /// + /// The tokens for which the lines of code should be counted. + /// Returns the number of lines of code. + public static int CalculateLinesOfCode(IEnumerable tokens) + { + int linesOfCode = 0; + bool comment = false; + + foreach (SEEToken token in tokens) + { + if (token.TokenType == SEEToken.Type.Newline) + { + if (!comment) + { + linesOfCode++; + } + } + else if (token.TokenType == SEEToken.Type.Comment) + { + comment = true; + } + else if (token.TokenType != SEEToken.Type.Whitespace) + { + comment = false; + } + } + return linesOfCode; + } + } +} \ No newline at end of file diff --git a/Assets/SEE/Scanner/TokenMetrics.cs.meta b/Assets/SEE/Scanner/TokenMetrics.cs.meta new file mode 100644 index 0000000000..9093d34673 --- /dev/null +++ b/Assets/SEE/Scanner/TokenMetrics.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fc68dfc19833d3144a58aee060513a07 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SEE/UI/Window/CodeWindow/Input/CodeWindowInput.cs b/Assets/SEE/UI/Window/CodeWindow/Input/CodeWindowInput.cs index eaa858f107..10c8c27afd 100644 --- a/Assets/SEE/UI/Window/CodeWindow/Input/CodeWindowInput.cs +++ b/Assets/SEE/UI/Window/CodeWindow/Input/CodeWindowInput.cs @@ -10,6 +10,7 @@ using SEE.UI.Notification; using SEE.Net.Dashboard; using SEE.Net.Dashboard.Model.Issues; +using SEE.Scanner; using SEE.Utils; using UnityEngine; using UnityEngine.Assertions; diff --git a/Assets/SEETests/TestConfigIO.cs b/Assets/SEETests/TestConfigIO.cs index 10d8692f30..bbde823ba9 100644 --- a/Assets/SEETests/TestConfigIO.cs +++ b/Assets/SEETests/TestConfigIO.cs @@ -1053,7 +1053,7 @@ private static void WipeOutNodeSettings(VisualNodeAttributes settings) { settings.Shape = NodeShapes.Blocks; settings.IsRelevant = false; - settings.MetricToLength = new List { "0.001", "Metric.LOC" }; + settings.MetricToLength = new List { "0.001", SEE.DataModel.DG.Metrics.Prefix + "LOC" }; settings.ColorProperty.ColorMetric = "X"; settings.MinimalBlockLength = 90000; settings.MaximalBlockLength = 1000000; diff --git a/Assets/SEETests/TestDashboard.cs b/Assets/SEETests/TestDashboard.cs index f50ea4a674..f7820a2a28 100644 --- a/Assets/SEETests/TestDashboard.cs +++ b/Assets/SEETests/TestDashboard.cs @@ -63,7 +63,7 @@ public IEnumerator TestDashboardMetrics() => UniTask.ToCoroutine(async () => public IEnumerator TestDashboardMetricValue() => UniTask.ToCoroutine(async () => { const string entity = "81"; // This entity does not exist. - const string metric = "Metric.LOC"; + const string metric = SEE.DataModel.DG.Metrics.Prefix + "LOC"; MetricValueRange range = await DashboardRetriever.Instance.GetMetricValueRangeAsync(entity, metric); Assert.IsNotNull(range); Assert.IsNotEmpty(range.Values); diff --git a/Assets/SEETests/TestGraphIO.cs b/Assets/SEETests/TestGraphIO.cs index cf38982867..3c09c82ffd 100644 --- a/Assets/SEETests/TestGraphIO.cs +++ b/Assets/SEETests/TestGraphIO.cs @@ -107,8 +107,8 @@ public async Task TestRandomGraphWriter([Values(true, false)] bool compress) Constraint innerNodesConstraint = new("File", 3, "imports", 0.01f); List attributeConstraints = new() { - new RandomAttributeDescriptor("Metric.LOC", 200, 50, -10, 100), - new RandomAttributeDescriptor("Metric.Clone_Rate", 0.5f, 0.1f, -0.5f, 1.3f), + new RandomAttributeDescriptor(Metrics.Prefix + "LOC", 200, 50, -10, 100), + new RandomAttributeDescriptor(Metrics.Prefix + "Clone_Rate", 0.5f, 0.1f, -0.5f, 1.3f), }; const string basename = "random"; @@ -218,8 +218,8 @@ private static Node NewNode(Graph graph, string linkname) }; result.SetToggle("Linkage.Is_Definition"); result.SetString("stringAttribute", "somestring"); - result.SetFloat("Metric.Halstead.Volume", 49.546f); - result.SetInt("Metric.LOC", 10); + result.SetFloat(Metrics.Prefix + "Halstead.Volume", 49.546f); + result.SetInt(Metrics.Prefix + "LOC", 10); graph.AddNode(result); return result; } diff --git a/Assets/SEETests/TestGraphProviderIO.cs b/Assets/SEETests/TestGraphProviderIO.cs index ce035934d1..267e6f06af 100644 --- a/Assets/SEETests/TestGraphProviderIO.cs +++ b/Assets/SEETests/TestGraphProviderIO.cs @@ -1,7 +1,15 @@ -using NUnit.Framework; +using LibGit2Sharp; +using NUnit.Framework; +using SEE.DataModel.DG; +using SEE.Game.City; +using SEE.Scanner; using SEE.Utils; using SEE.Utils.Config; +using SEE.Utils.Paths; +using System.Collections.Generic; using System.IO; +using System.Linq; +using System.Threading.Tasks; using UnityEngine; namespace SEE.GraphProviders @@ -254,6 +262,157 @@ private static void AreEqualDiffMergeGraphProviders(MergeDiffGraphProvider saved #endregion + #region VCSGraphProvider + + public async Task GetVCSGraphAsync() + { + VCSGraphProvider saved = GetVCSGraphProvider(); + SEECity testCity = NewVanillaSEECity(); ; + Graph testGraph = new("test", "test"); + Graph graph = await saved.ProvideAsync(testGraph, testCity); + return graph; + } + + [Test] + public async Task TestVCSGraphProviderAsync() + { + Graph graph = await GetVCSGraphAsync(); + List pathsFromGraph = new(); + foreach (GraphElement elem in graph.Elements()) + { + pathsFromGraph.Add(elem.ID); + } + + string repositoryPath = Application.dataPath; + string projectPath = repositoryPath.Substring(0, repositoryPath.LastIndexOf("/")); + string projectName = Path.GetFileName(projectPath); + + List actualList = new() + { + projectName, + ".gitignore", + "Assets", + "Assets/Scenes.meta", + "Assets/Scenes", + "Assets/Scenes/SampleScene.unity", + "Assets/Scenes/SampleScene.unity.meta", + "Packages", + "Packages/manifest.json", + "ProjectSettings", + "ProjectSettings/AudioManager.asset", + "ProjectSettings/ClusterInputManager.asset", + "ProjectSettings/DynamicsManager.asset", + "ProjectSettings/EditorBuildSettings.asset", + "ProjectSettings/EditorSettings.asset", + "ProjectSettings/GraphicsSettings.asset", + "ProjectSettings/InputManager.asset", + "ProjectSettings/NavMeshAreas.asset", + "ProjectSettings/Physics2DSettings.asset", + "ProjectSettings/PresetManager.asset", + "ProjectSettings/ProjectSettings.asset", + "ProjectSettings/ProjectVersion.txt", + "ProjectSettings/QualitySettings.asset", + "ProjectSettings/TagManager.asset", + "ProjectSettings/TimeManager.asset", + "ProjectSettings/UnityConnectSettings.asset", + "ProjectSettings/VFXManager.asset", + "ProjectSettings/XRSettings.asset" + }; + Assert.AreEqual(28, pathsFromGraph.Count()); + Assert.IsTrue(actualList.OrderByDescending(x => x).ToList().SequenceEqual(pathsFromGraph.OrderByDescending(x => x).ToList())); + } + + private VCSGraphProvider GetVCSGraphProvider() + { + return new VCSGraphProvider() + { + RepositoryPath = new DirectoryPath(Path.GetDirectoryName(Application.dataPath)), + CommitID = "b10e1f49c144c0a22aa0d972c946f93a82ad3461", + }; + } + + [Test] + public async Task TestRetrieveTokensAsync() + { + Graph graph = await GetVCSGraphAsync(); + Node fileNode = graph.Nodes().First(t => t.Type == "File"); + string filePath = fileNode.ID; + string commitID = "b10e1f49c144c0a22aa0d972c946f93a82ad3461"; + string repoPath = Path.GetDirectoryName(Application.dataPath); + using Repository repo = new(repoPath); + TokenLanguage language = TokenLanguage.FromFileExtension(Path.GetExtension(filePath).TrimStart('.')); + + IEnumerable tokens = VCSGraphProvider.RetrieveTokens(filePath, repo, commitID, language); + + Assert.IsNotNull(tokens); + Assert.NotZero(tokens.Count()); + } + + [Test] + public async Task TestAddMetricsToNodeAsync() + { + Graph graph = await GetVCSGraphAsync(); + string repoPath = Path.GetDirectoryName(Application.dataPath); + string commitID = "b10e1f49c144c0a22aa0d972c946f93a82ad3461"; + using Repository repo = new(repoPath); + + foreach (Node node in graph.Nodes()) + { + string filePath = node.ID.Replace('\\', '/'); + TokenLanguage language = TokenLanguage.FromFileExtension(Path.GetExtension(filePath).TrimStart('.')); + if (node.Type == "File" && language != TokenLanguage.Plain) + { + IEnumerable tokens = VCSGraphProvider.RetrieveTokens(filePath, repo, commitID, language); + AssertMetricsCanBeAdded(node); + } + + AssertMetricsCannotBeAdded(node); + } + } + + private static void AssertMetricsCanBeAdded(Node node) + { + Assert.IsTrue(node.HasToggle(Metrics.Prefix + "LOD")); + Assert.IsTrue(node.HasToggle(Metrics.Prefix + "McCabe_Complexity")); + Assert.IsTrue(node.HasToggle(Metrics.Prefix + "Halstead.Distinct_Operators")); + Assert.IsTrue(node.HasToggle(Metrics.Prefix + "Halstead.Distinct_Operands")); + Assert.IsTrue(node.HasToggle(Metrics.Prefix + "Halstead.Total_Operators")); + Assert.IsTrue(node.HasToggle(Metrics.Prefix + "Halstead.Total_Operands")); + Assert.IsTrue(node.HasToggle(Metrics.Prefix + "Halstead.Program_Vocabulary")); + Assert.IsTrue(node.HasToggle(Metrics.Prefix + "Halstead.Program_Length")); + Assert.IsTrue(node.HasToggle(Metrics.Prefix + "Halstead.Estimated_Program_Length")); + Assert.IsTrue(node.HasToggle(Metrics.Prefix + "Halstead.Volume")); + Assert.IsTrue(node.HasToggle(Metrics.Prefix + "Halstead.Difficulty")); + Assert.IsTrue(node.HasToggle(Metrics.Prefix + "Halstead.Effort")); + Assert.IsTrue(node.HasToggle(Metrics.Prefix + "Halstead.Time_Required_To_Program")); + Assert.IsTrue(node.HasToggle(Metrics.Prefix + "Halstead.Number_Of_Delivered_Bugs")); + } + + private static void AssertMetricsCannotBeAdded(Node node) + { + Assert.IsFalse(node.HasToggle(Metrics.Prefix + "LOC")); + Assert.IsFalse(node.HasToggle(Metrics.Prefix + "McCabe_Complexity")); + Assert.IsFalse(node.HasToggle(Metrics.Prefix + "Halstead.Distinct_Operators")); + Assert.IsFalse(node.HasToggle(Metrics.Prefix + "Halstead.Distinct_Operands")); + Assert.IsFalse(node.HasToggle(Metrics.Prefix + "Halstead.Total_Operators")); + Assert.IsFalse(node.HasToggle(Metrics.Prefix + "Halstead.Total_Operands")); + Assert.IsFalse(node.HasToggle(Metrics.Prefix + "Halstead.Program_Vocabulary")); + Assert.IsFalse(node.HasToggle(Metrics.Prefix + "Halstead.Program_Length")); + Assert.IsFalse(node.HasToggle(Metrics.Prefix + "Halstead.Estimated_Program_Length")); + Assert.IsFalse(node.HasToggle(Metrics.Prefix + "Halstead.Volume")); + Assert.IsFalse(node.HasToggle(Metrics.Prefix + "Halstead.Difficulty")); + Assert.IsFalse(node.HasToggle(Metrics.Prefix + "Halstead.Effort")); + Assert.IsFalse(node.HasToggle(Metrics.Prefix + "Halstead.Time_Required_To_Program")); + Assert.IsFalse(node.HasToggle(Metrics.Prefix + "Halstead.Number_Of_Delivered_Bugs")); + } + + #endregion + + private static T NewVanillaSEECity() where T : Component + { + return new GameObject().AddComponent(); + } + private GraphProvider Load() { using ConfigReader stream = new(filename); @@ -269,3 +428,4 @@ private void Save(GraphProvider saved) } } } + diff --git a/Assets/SEETests/TestGraphProviders.cs b/Assets/SEETests/TestGraphProviders.cs index be74313d69..461926c09f 100644 --- a/Assets/SEETests/TestGraphProviders.cs +++ b/Assets/SEETests/TestGraphProviders.cs @@ -69,7 +69,7 @@ public IEnumerator TestCSVJaCoCoGXLGraphProvider() => } // Metric from CSV import. { - Assert.IsTrue(node.TryGetInt("Metric.Developers", out int value)); + Assert.IsTrue(node.TryGetInt(Metrics.Prefix + "Developers", out int value)); Assert.AreEqual(3, value); } }); diff --git a/Assets/SEETests/TestTokenMetrics.cs b/Assets/SEETests/TestTokenMetrics.cs new file mode 100644 index 0000000000..10abc030ca --- /dev/null +++ b/Assets/SEETests/TestTokenMetrics.cs @@ -0,0 +1,172 @@ +using NUnit.Framework; +using System.Collections.Generic; + +namespace SEE.Scanner +{ + /// + /// Test cases for . + /// + internal class TestTokenMetrics + { + /// + /// Checks whether the provided code has the expected McCabe cyclomatic complexity. + /// + /// The provided code. + /// The expected McCabe cyclomatic complexity. + [Test] + [TestCase(@"using System; + + public class Program + { + public static void Main() + { + if (true) + { + //This is a comment. Do not count them in, even if it seems tempting. + Console.WriteLine(""Hello, if World!""); + } + else + { + //This is another comment. Do look further. + Console.WriteLine(""Hello, else World!""); + } + } + }", 2)] + [TestCase(@"public class NoBranchProgram + { + public int Add(int a, int b) + { + return a + b; + } + }", 1)] + [TestCase("public class EmptyClass\n {\n }", 1)] + [TestCase("public class DoesNotCompile\n{\n break; continue; case 2: while do if else foreach for switch try catch }", 7)] + public void TestCalculateMcCabeComplexity(string code, int expected) + { + IEnumerable tokens = SEEToken.FromString(code, TokenLanguage.CSharp); + int complexity = TokenMetrics.CalculateMcCabeComplexity(tokens); + Assert.AreEqual(expected, complexity); + } + + /// + /// Checks whether the provided code has the expected Halstead metrics. + /// + [Test] + public void TestCalculateHalsteadMetrics() + { + const float tolerance = 0.001f; // Tolerance for float value comparisons. + + // Test case for empty code, in case DistinctOperators, DistinctOperands and/or ProgramVocabulary values are zero. + string emptyCode = ""; + + IEnumerable tokensEmptyCode = SEEToken.FromString(emptyCode, TokenLanguage.Plain); + TokenMetrics.HalsteadMetrics expectedEmptyCode = new(DistinctOperators: 0, + DistinctOperands: 0, + TotalOperators: 0, + TotalOperands: 0, + ProgramVocabulary: 0, + ProgramLength: 0, + EstimatedProgramLength: 0f, + Volume: 0f, + Difficulty: 0f, + Effort: 0f, + TimeRequiredToProgram: 0f, + NumberOfDeliveredBugs: 0f); + TokenMetrics.HalsteadMetrics metricsEmptyCode = TokenMetrics.CalculateHalsteadMetrics(tokensEmptyCode); + Assert.AreEqual(expectedEmptyCode, metricsEmptyCode); + + // Test case for standard code. + string code = @"public class Program { + + // A comment for the sake of it. + public static void main(String[] args) { + int x = 5 + 3 * 2; + System.out.println(x); + } + }"; + + IEnumerable tokens = SEEToken.FromString(code, TokenLanguage.Java); + TokenMetrics.HalsteadMetrics expected = new(DistinctOperators: 11, + DistinctOperands: 16, + TotalOperators: 17, + TotalOperands: 18, + ProgramVocabulary: 27, + ProgramLength: 35, + EstimatedProgramLength: 102.0537f, + Volume: 166.4211f, + Difficulty: 6.1875f, + Effort: 1029.73f, + TimeRequiredToProgram: 57.20724f, + NumberOfDeliveredBugs: 0.05547369f); + TokenMetrics.HalsteadMetrics metrics = TokenMetrics.CalculateHalsteadMetrics(tokens); + + Assert.AreEqual(expected.DistinctOperators, metrics.DistinctOperators); + Assert.AreEqual(expected.DistinctOperands, metrics.DistinctOperands); + Assert.AreEqual(expected.TotalOperators, metrics.TotalOperators); + Assert.AreEqual(expected.TotalOperands, metrics.TotalOperands); + Assert.AreEqual(expected.ProgramVocabulary, metrics.ProgramVocabulary); + Assert.AreEqual(expected.ProgramLength, metrics.ProgramLength); + Assert.AreEqual(expected.EstimatedProgramLength, metrics.EstimatedProgramLength, tolerance); + Assert.AreEqual(expected.Volume, metrics.Volume, tolerance); + Assert.AreEqual(expected.Difficulty, metrics.Difficulty, tolerance); + Assert.AreEqual(expected.Effort, metrics.Effort, tolerance); + Assert.AreEqual(expected.TimeRequiredToProgram, metrics.TimeRequiredToProgram, tolerance); + Assert.AreEqual(expected.NumberOfDeliveredBugs, metrics.NumberOfDeliveredBugs, tolerance); + + // Test case for code with no operators to test Plain Text. + string codeWithNoOperators = "This arbitary file has no code.\nJust plain words."; // "." is its own operand. + + IEnumerable tokensNoOperators = SEEToken.FromString(codeWithNoOperators, TokenLanguage.Plain); + TokenMetrics.HalsteadMetrics expectedNoOperators = new(DistinctOperators: 0, + DistinctOperands: 10, + TotalOperators: 0, + TotalOperands: 11, + ProgramVocabulary: 10, + ProgramLength: 11, + EstimatedProgramLength: 0f, + Volume: 36.54121f, + Difficulty: 0f, + Effort: 0f, + TimeRequiredToProgram: 0f, + NumberOfDeliveredBugs: 0.0121804f); + TokenMetrics.HalsteadMetrics metricsNoOperators = TokenMetrics.CalculateHalsteadMetrics(tokensNoOperators); + + Assert.AreEqual(expectedNoOperators.DistinctOperators, metricsNoOperators.DistinctOperators); + Assert.AreEqual(expectedNoOperators.DistinctOperands, metricsNoOperators.DistinctOperands); + Assert.AreEqual(expectedNoOperators.TotalOperators, metricsNoOperators.TotalOperators); + Assert.AreEqual(expectedNoOperators.TotalOperands, metricsNoOperators.TotalOperands); + Assert.AreEqual(expectedNoOperators.ProgramVocabulary, metricsNoOperators.ProgramVocabulary); + Assert.AreEqual(expectedNoOperators.ProgramLength, metricsNoOperators.ProgramLength); + Assert.AreEqual(expectedNoOperators.EstimatedProgramLength, metricsNoOperators.EstimatedProgramLength, tolerance); + Assert.AreEqual(expectedNoOperators.Volume, metricsNoOperators.Volume, tolerance); + Assert.AreEqual(expectedNoOperators.Difficulty, metricsNoOperators.Difficulty, tolerance); + Assert.AreEqual(expectedNoOperators.Effort, metricsNoOperators.Effort, tolerance); + Assert.AreEqual(expectedNoOperators.TimeRequiredToProgram, metricsNoOperators.TimeRequiredToProgram, tolerance); + Assert.AreEqual(expectedNoOperators.NumberOfDeliveredBugs, metricsNoOperators.NumberOfDeliveredBugs, tolerance); + } + + /// + /// Checks whether the provided code has the expected lines of code. + /// + /// The provided code. + /// The expected lines of code. + [Test] + [TestCase(@"class Program { + public: + int x; + + // A comment. + void setX(int y) { + x = y; // An inline comment. + } + }; + ", 7)] + [TestCase(" ", 0)] + public void TestCalculateLinesOfCode(string code, int expected) + { + IEnumerable tokens = SEEToken.FromString(code, TokenLanguage.CPP); + int linesOfCode = TokenMetrics.CalculateLinesOfCode(tokens); + Assert.AreEqual(expected, linesOfCode); + } + } +} diff --git a/Assets/SEETests/TestTokenMetrics.cs.meta b/Assets/SEETests/TestTokenMetrics.cs.meta new file mode 100644 index 0000000000..b69b2ff395 --- /dev/null +++ b/Assets/SEETests/TestTokenMetrics.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 359641af0ee4eb445bc4665ab6779b71 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scenes/SEENewWorld.unity b/Assets/Scenes/SEENewWorld.unity index d0275132c7..b876cf600b 100644 --- a/Assets/Scenes/SEENewWorld.unity +++ b/Assets/Scenes/SEENewWorld.unity @@ -10059,6 +10059,118 @@ PrefabInstance: m_AddedGameObjects: [] m_AddedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: dc09ca83af09d6d4b8b33c7c5c4a13ee, type: 3} +--- !u!1001 &471867952 +PrefabInstance: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + serializedVersion: 3 + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: -4216859302048453862, guid: 616cd0a1c5e06384e8441efb4837d445, + type: 3} + propertyPath: m_RootOrder + value: 140 + objectReference: {fileID: 0} + - target: {fileID: -4216859302048453862, guid: 616cd0a1c5e06384e8441efb4837d445, + type: 3} + propertyPath: m_LocalPosition.x + value: -30.14087 + objectReference: {fileID: 0} + - target: {fileID: -4216859302048453862, guid: 616cd0a1c5e06384e8441efb4837d445, + type: 3} + propertyPath: m_LocalPosition.y + value: 0.4470662 + objectReference: {fileID: 0} + - target: {fileID: -4216859302048453862, guid: 616cd0a1c5e06384e8441efb4837d445, + type: 3} + propertyPath: m_LocalPosition.z + value: 13.127973 + objectReference: {fileID: 0} + - target: {fileID: -4216859302048453862, guid: 616cd0a1c5e06384e8441efb4837d445, + type: 3} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: -4216859302048453862, guid: 616cd0a1c5e06384e8441efb4837d445, + type: 3} + propertyPath: m_LocalRotation.x + value: -0 + objectReference: {fileID: 0} + - target: {fileID: -4216859302048453862, guid: 616cd0a1c5e06384e8441efb4837d445, + type: 3} + propertyPath: m_LocalRotation.y + value: -0 + objectReference: {fileID: 0} + - target: {fileID: -4216859302048453862, guid: 616cd0a1c5e06384e8441efb4837d445, + type: 3} + propertyPath: m_LocalRotation.z + value: -0 + objectReference: {fileID: 0} + - target: {fileID: -4216859302048453862, guid: 616cd0a1c5e06384e8441efb4837d445, + type: 3} + propertyPath: m_LocalEulerAnglesHint.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: -4216859302048453862, guid: 616cd0a1c5e06384e8441efb4837d445, + type: 3} + propertyPath: m_LocalEulerAnglesHint.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: -4216859302048453862, guid: 616cd0a1c5e06384e8441efb4837d445, + type: 3} + propertyPath: m_LocalEulerAnglesHint.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: -927199367670048503, guid: 616cd0a1c5e06384e8441efb4837d445, + type: 3} + propertyPath: m_Name + value: Desk01 + objectReference: {fileID: 0} + - target: {fileID: -927199367670048503, guid: 616cd0a1c5e06384e8441efb4837d445, + type: 3} + propertyPath: m_StaticEditorFlags + value: 4294967295 + objectReference: {fileID: 0} + - target: {fileID: 100000, guid: 616cd0a1c5e06384e8441efb4837d445, type: 3} + propertyPath: m_Name + value: VCSTable + objectReference: {fileID: 0} + - target: {fileID: 100000, guid: 616cd0a1c5e06384e8441efb4837d445, type: 3} + propertyPath: m_StaticEditorFlags + value: 4294967295 + objectReference: {fileID: 0} + - target: {fileID: 400000, guid: 616cd0a1c5e06384e8441efb4837d445, type: 3} + propertyPath: m_RootOrder + value: 17 + objectReference: {fileID: 0} + - target: {fileID: 400000, guid: 616cd0a1c5e06384e8441efb4837d445, type: 3} + propertyPath: m_LocalPosition.x + value: -1.6799998 + objectReference: {fileID: 0} + - target: {fileID: 400000, guid: 616cd0a1c5e06384e8441efb4837d445, type: 3} + propertyPath: m_LocalPosition.z + value: 0.963 + objectReference: {fileID: 0} + - target: {fileID: 400000, guid: 616cd0a1c5e06384e8441efb4837d445, type: 3} + propertyPath: m_LocalRotation.x + value: -0 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: + - targetCorrespondingSourceObject: {fileID: 400000, guid: 616cd0a1c5e06384e8441efb4837d445, + type: 3} + insertIndex: -1 + addedObject: {fileID: 1770094064} + m_AddedComponents: [] + m_SourcePrefab: {fileID: 100100000, guid: 616cd0a1c5e06384e8441efb4837d445, type: 3} +--- !u!4 &471867953 stripped +Transform: + m_CorrespondingSourceObject: {fileID: 400000, guid: 616cd0a1c5e06384e8441efb4837d445, + type: 3} + m_PrefabInstance: {fileID: 471867952} + m_PrefabAsset: {fileID: 0} --- !u!1 &484407758 GameObject: m_ObjectHideFlags: 0 @@ -34067,6 +34179,840 @@ Transform: - {fileID: 1042245598} m_Father: {fileID: 1658517675} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1770094063 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1770094064} + - component: {fileID: 1770094070} + - component: {fileID: 1770094069} + - component: {fileID: 1770094068} + - component: {fileID: 1770094067} + - component: {fileID: 1770094065} + m_Layer: 0 + m_Name: VCSCity + m_TagString: Code City + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1770094064 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1770094063} + serializedVersion: 2 + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 45.799995, z: 0} + m_LocalScale: {x: 147.204, y: 0.0001859913, z: 322.03818} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 471867953} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &1770094065 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1770094063} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 253abae38e5d8014abb73913836a3d5f, type: 3} + m_Name: + m_EditorClassIdentifier: + serializationData: + SerializedFormat: 2 + SerializedBytes: + ReferencedUnityObjects: [] + SerializedBytesString: + Prefab: {fileID: 0} + PrefabModificationsReferencedUnityObjects: [] + PrefabModifications: [] + SerializationNodes: + - Name: HierarchicalEdges + Entry: 7 + Data: 0|System.Collections.Generic.HashSet`1[[System.String, mscorlib]], System.Core + - Name: + Entry: 12 + Data: 4 + - Name: + Entry: 1 + Data: Enclosing + - Name: + Entry: 1 + Data: Belongs_To + - Name: + Entry: 1 + Data: Part_Of + - Name: + Entry: 1 + Data: Defined_In + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: NodeTypes + Entry: 7 + Data: 1|SEE.Game.City.NodeTypeVisualsMap, SEE + - Name: map + Entry: 7 + Data: 2|SEE.Game.City.VisualNodeAttributesMapping, SEE + - Name: comparer + Entry: 7 + Data: 3|System.Collections.Generic.GenericEqualityComparer`1[[System.String, + mscorlib]], mscorlib + - Name: + Entry: 8 + Data: + - Name: + Entry: 12 + Data: 2 + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: Directory + - Name: $v + Entry: 7 + Data: 4|SEE.Game.City.VisualNodeAttributes, SEE + - Name: IsRelevant + Entry: 5 + Data: true + - Name: Shape + Entry: 3 + Data: 0 + - Name: MetricToLength + Entry: 7 + Data: 5|System.Collections.Generic.List`1[[System.String, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 3 + - Name: + Entry: 1 + Data: 0.001 + - Name: + Entry: 1 + Data: 0.001 + - Name: + Entry: 1 + Data: 0.001 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: ColorProperty + Entry: 7 + Data: 6|SEE.Game.City.ColorProperty, SEE + - Name: Property + Entry: 3 + Data: 0 + - Name: TypeColor + Entry: 7 + Data: UnityEngine.Color, UnityEngine.CoreModule + - Name: + Entry: 4 + Data: 0.784313738 + - Name: + Entry: 4 + Data: 0.784313738 + - Name: + Entry: 4 + Data: 0.784313738 + - Name: + Entry: 4 + Data: 1 + - Name: + Entry: 8 + Data: + - Name: ByLevel + Entry: 5 + Data: true + - Name: ColorMetric + Entry: 1 + Data: + - Name: + Entry: 8 + Data: + - Name: MinimalBlockLength + Entry: 4 + Data: 0.001 + - Name: MaximalBlockLength + Entry: 4 + Data: 1 + - Name: AntennaSettings + Entry: 7 + Data: 7|SEE.Game.City.AntennaAttributes, SEE + - Name: AntennaSections + Entry: 7 + Data: 8|System.Collections.Generic.List`1[[System.String, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: LabelSettings + Entry: 7 + Data: 9|SEE.Game.LabelAttributes, SEE + - Name: Show + Entry: 5 + Data: true + - Name: Distance + Entry: 4 + Data: 0.2 + - Name: FontSize + Entry: 4 + Data: 0.4 + - Name: AnimationFactor + Entry: 4 + Data: 0.5 + - Name: LabelAlpha + Entry: 4 + Data: 1 + - Name: + Entry: 8 + Data: + - Name: OutlineWidth + Entry: 4 + Data: 1 + - Name: ShowNames + Entry: 5 + Data: false + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: File + - Name: $v + Entry: 7 + Data: 10|SEE.Game.City.VisualNodeAttributes, SEE + - Name: IsRelevant + Entry: 5 + Data: true + - Name: Shape + Entry: 3 + Data: 0 + - Name: MetricToLength + Entry: 7 + Data: 11|System.Collections.Generic.List`1[[System.String, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 3 + - Name: + Entry: 1 + Data: Metric.LOC + - Name: + Entry: 1 + Data: Metric.LOC + - Name: + Entry: 1 + Data: Metric.LOC + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: ColorProperty + Entry: 7 + Data: 12|SEE.Game.City.ColorProperty, SEE + - Name: Property + Entry: 3 + Data: 1 + - Name: TypeColor + Entry: 7 + Data: UnityEngine.Color, UnityEngine.CoreModule + - Name: + Entry: 4 + Data: 1 + - Name: + Entry: 4 + Data: 1 + - Name: + Entry: 4 + Data: 1 + - Name: + Entry: 4 + Data: 1 + - Name: + Entry: 8 + Data: + - Name: ByLevel + Entry: 5 + Data: true + - Name: ColorMetric + Entry: 1 + Data: Metric.McCabe_Complexity + - Name: + Entry: 8 + Data: + - Name: MinimalBlockLength + Entry: 4 + Data: 0.001 + - Name: MaximalBlockLength + Entry: 4 + Data: 1 + - Name: AntennaSettings + Entry: 7 + Data: 13|SEE.Game.City.AntennaAttributes, SEE + - Name: AntennaSections + Entry: 7 + Data: 14|System.Collections.Generic.List`1[[System.String, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: LabelSettings + Entry: 7 + Data: 15|SEE.Game.LabelAttributes, SEE + - Name: Show + Entry: 5 + Data: true + - Name: Distance + Entry: 4 + Data: 0.2 + - Name: FontSize + Entry: 4 + Data: 0.4 + - Name: AnimationFactor + Entry: 4 + Data: 0.5 + - Name: LabelAlpha + Entry: 4 + Data: 1 + - Name: + Entry: 8 + Data: + - Name: OutlineWidth + Entry: 4 + Data: 1 + - Name: ShowNames + Entry: 5 + Data: false + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: MarkerAttributes + Entry: 7 + Data: 16|SEE.Game.City.MarkerAttributes, SEE + - Name: MarkerHeight + Entry: 4 + Data: 0.2 + - Name: MarkerWidth + Entry: 4 + Data: 0.01 + - Name: AdditionBeamColor + Entry: 7 + Data: UnityEngine.Color, UnityEngine.CoreModule + - Name: + Entry: 4 + Data: 0 + - Name: + Entry: 4 + Data: 1 + - Name: + Entry: 4 + Data: 0 + - Name: + Entry: 4 + Data: 1 + - Name: + Entry: 8 + Data: + - Name: ChangeBeamColor + Entry: 7 + Data: UnityEngine.Color, UnityEngine.CoreModule + - Name: + Entry: 4 + Data: 1 + - Name: + Entry: 4 + Data: 0.921568632 + - Name: + Entry: 4 + Data: 0.0156862754 + - Name: + Entry: 4 + Data: 1 + - Name: + Entry: 8 + Data: + - Name: DeletionBeamColor + Entry: 7 + Data: UnityEngine.Color, UnityEngine.CoreModule + - Name: + Entry: 4 + Data: 0 + - Name: + Entry: 4 + Data: 0 + - Name: + Entry: 4 + Data: 0 + - Name: + Entry: 4 + Data: 1 + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: MetricToColor + Entry: 7 + Data: 17|SEE.Game.City.ColorMap, SEE + - Name: map + Entry: 7 + Data: 18|SEE.Game.City.ColorRangeMapping, SEE + - Name: comparer + Entry: 9 + Data: 3 + - Name: + Entry: 12 + Data: 1 + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: Metric.McCabe_Complexity + - Name: $v + Entry: 7 + Data: SEE.Game.ColorRange, SEE + - Name: Lower + Entry: 7 + Data: UnityEngine.Color, UnityEngine.CoreModule + - Name: + Entry: 4 + Data: 1 + - Name: + Entry: 4 + Data: 1 + - Name: + Entry: 4 + Data: 1 + - Name: + Entry: 4 + Data: 1 + - Name: + Entry: 8 + Data: + - Name: Upper + Entry: 7 + Data: UnityEngine.Color, UnityEngine.CoreModule + - Name: + Entry: 4 + Data: 1 + - Name: + Entry: 4 + Data: 0 + - Name: + Entry: 4 + Data: 0 + - Name: + Entry: 4 + Data: 1 + - Name: + Entry: 8 + Data: + - Name: NumberOfColors + Entry: 3 + Data: 15 + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: CoseGraphSettings + Entry: 7 + Data: 19|SEE.Layout.NodeLayouts.Cose.CoseGraphAttributes, SEE + - Name: EdgeLength + Entry: 3 + Data: 20 + - Name: UseSmartIdealEdgeCalculation + Entry: 5 + Data: false + - Name: UseSmartMultilevelScaling + Entry: 5 + Data: false + - Name: PerLevelIdealEdgeLengthFactor + Entry: 4 + Data: 0.1 + - Name: UseSmartRepulsionRangeCalculation + Entry: 5 + Data: false + - Name: GravityStrength + Entry: 4 + Data: 0.8 + - Name: CompoundGravityStrength + Entry: 4 + Data: 1.5 + - Name: RepulsionStrength + Entry: 4 + Data: 50 + - Name: MultiLevelScaling + Entry: 5 + Data: false + - Name: ListInnerNodeToggle + Entry: 7 + Data: 20|System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.Boolean, + mscorlib]], mscorlib + - Name: comparer + Entry: 7 + Data: 21|System.Collections.Generic.GenericEqualityComparer`1[[System.String, + mscorlib]], mscorlib + - Name: + Entry: 8 + Data: + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: InnerNodeLayout + Entry: 7 + Data: 22|System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[SEE.Game.City.NodeLayoutKind, + SEE]], mscorlib + - Name: comparer + Entry: 9 + Data: 21 + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: InnerNodeShape + Entry: 7 + Data: 23|System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[SEE.Game.City.NodeShapes, + SEE]], mscorlib + - Name: comparer + Entry: 9 + Data: 21 + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: LoadedForNodeTypes + Entry: 7 + Data: 24|System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.Boolean, + mscorlib]], mscorlib + - Name: comparer + Entry: 9 + Data: 21 + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: UseCalculationParameter + Entry: 5 + Data: true + - Name: UseIterativeCalculation + Entry: 5 + Data: false + - Name: + Entry: 8 + Data: + - Name: DataProvider + Entry: 7 + Data: 25|SEE.GraphProviders.PipelineGraphProvider, SEE + - Name: Pipeline + Entry: 7 + Data: 26|System.Collections.Generic.List`1[[SEE.GraphProviders.GraphProvider, + SEE]], mscorlib + - Name: + Entry: 12 + Data: 1 + - Name: + Entry: 7 + Data: 27|SEE.GraphProviders.VCSGraphProvider, SEE + - Name: RepositoryPath + Entry: 7 + Data: 28|SEE.Utils.Paths.DirectoryPath, SEE + - Name: Root + Entry: 3 + Data: 1 + - Name: relativePath + Entry: 1 + Data: + - Name: absolutePath + Entry: 1 + Data: + - Name: + Entry: 8 + Data: + - Name: CommitID + Entry: 1 + Data: 0878f91f900dc90d89c594c521ac1d3b9edd7097 + - Name: PathGlobbing + Entry: 7 + Data: 29|System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.Boolean, + mscorlib]], mscorlib + - Name: comparer + Entry: 9 + Data: 21 + - Name: + Entry: 12 + Data: 1 + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: Assets/SEE/**/*.cs + - Name: $v + Entry: 5 + Data: true + - Name: + Entry: 8 + Data: + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + LODCulling: 0.001 + ConfigurationPath: + Root: 3 + relativePath: /SEE/SEEVCS.cfg + absolutePath: + sourceCodeDirectory: + Root: 1 + relativePath: + absolutePath: + SolutionPath: + Root: 1 + relativePath: /SEEIT.sln + absolutePath: + IgnoreSelfLoopsInLifting: 0 + MaximalAntennaSegmentHeight: 0.5 + AntennaWidth: 0.1 + BaseAnimationDuration: 1 + ProgressBar: 0 + ZScoreScale: 0 + ScaleOnlyLeafMetrics: 1 + NodeLayoutSettings: + Kind: 3 + IncrementalTreeMap: + LocalMovesDepth: 3 + LocalMovesBranchingLimit: 4 + pNorm: 1 + PaddingMm: 5 + GradientDescentPrecision: -4 + LayoutPath: + Root: 2 + relativePath: + absolutePath: + EdgeLayoutSettings: + Kind: 3 + AnimationKind: 2 + AnimateInnerEdges: 1 + EdgeWidth: 0.01 + EdgesAboveBlocks: 1 + Tension: 0.85 + EdgeSelectionSettings: + TubularSegments: 50 + Radius: 0.005 + RadialSegments: 8 + AreSelectable: 1 + ErosionSettings: + ShowInnerErosions: 0 + ShowLeafErosions: 0 + ErosionScalingFactor: 1.5 + ShowIssuesInCodeWindow: 0 + ArchitectureIssue: Metric.Architecture_Violations + CloneIssue: Metric.Clone + CycleIssue: Metric.Cycle + DeadCodeIssue: Metric.Dead_Code + MetricIssue: Metric.Metric + StyleIssue: Metric.Style + UniversalIssue: Metric.Universal + ArchitectureIssueSum: Metric.Architecture_Violations_SUM + CloneIssueSum: Metric.Clone_SUM + CycleIssueSum: Metric.Cycle_SUM + DeadCodeIssueSum: Metric.Dead_Code_SUM + MetricIssueSum: Metric.Metric_SUM + StyleIssueSum: Metric.Style_SUM + UniversalIssueSum: Metric.Universal_SUM + BoardSettings: + LoadBoardOnStartup: 0 + BoardPath: + Root: 2 + relativePath: + absolutePath: +--- !u!114 &1770094067 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1770094063} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 7623b0249cfceff40b25a7b4ea3b89f4, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &1770094068 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1770094063} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2e5d4facdf0010e4898868f60a952c2b, type: 3} + m_Name: + m_EditorClassIdentifier: + HeightOffset: 0.0015009642 +--- !u!65 &1770094069 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1770094063} + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_IsTrigger: 0 + m_ProvidesContacts: 0 + m_Enabled: 1 + serializedVersion: 3 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &1770094070 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1770094063} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 800ec33a9c0fe564b9b72cdd97dc8d9e, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} --- !u!1 &1777023170 GameObject: m_ObjectHideFlags: 0 @@ -40446,3 +41392,4 @@ SceneRoots: - {fileID: 387723966} - {fileID: 1706202779} - {fileID: 1166896206} + - {fileID: 471867952} diff --git a/Assets/StreamingAssets/SEE/SEEVCS.cfg b/Assets/StreamingAssets/SEE/SEEVCS.cfg new file mode 100644 index 0000000000..2c93f5aa41 --- /dev/null +++ b/Assets/StreamingAssets/SEE/SEEVCS.cfg @@ -0,0 +1,224 @@ +ConfigPath : { + Root : "StreamingAssets"; + RelativePath : "/SEE/SEEVCS.cfg"; + AbsolutePath : ""; +}; +ProjectPath : { + Root : "ProjectFolder"; + RelativePath : ""; + AbsolutePath : ""; +}; +SolutionPath : { + Root : "ProjectFolder"; + RelativePath : "/SEEIT.sln"; + AbsolutePath : ""; +}; +LODCulling : 0.00100000; +HierarchicalEdges : [ + "Enclosing"; + "Belongs_To"; + "Part_Of"; + "Defined_In"; +]; +NodeTypes : [ + { + nodeType : "Directory"; + visualNodeAttributes : { + Shape : "Blocks"; + IsRelevant : True; + MetricToLength : [ + "0.001"; + "0.001"; + "0.001"; + ]; + ColorProperty : { + Property : "Type"; + TypeColor : { + Red : 0.78431370; + Green : 0.78431370; + Blue : 0.78431370; + Alpha : 1.00000000; + }; + ByLevel : True; + ColorMetric : ""; + }; + MinimalBlockLength : 0.00100000; + MaximalBlockLength : 1.00000000; + LabelSettings : { + Show : True; + Distance : 0.20000000; + FontSize : 0.40000000; + AnimationDuration : 0.50000000; + LabelAlpha : 1.00000000; + }; + AntennnaSettings : { + AntennaSections : [ + ]; + }; + OutlineWidth : 1.00000000; + ShowNames : False; + }; + }; + { + nodeType : "File"; + visualNodeAttributes : { + Shape : "Blocks"; + IsRelevant : True; + MetricToLength : [ + "Metric.LOC"; + "Metric.LOC"; + "Metric.LOC"; + ]; + ColorProperty : { + Property : "Metric"; + TypeColor : { + Red : 1.00000000; + Green : 1.00000000; + Blue : 1.00000000; + Alpha : 1.00000000; + }; + ByLevel : True; + ColorMetric : "Metric.McCabe_Complexity"; + }; + MinimalBlockLength : 0.00100000; + MaximalBlockLength : 1.00000000; + LabelSettings : { + Show : True; + Distance : 0.20000000; + FontSize : 0.40000000; + AnimationDuration : 0.50000000; + LabelAlpha : 1.00000000; + }; + AntennnaSettings : { + AntennaSections : [ + ]; + }; + OutlineWidth : 1.00000000; + ShowNames : False; + }; + }; +]; +IgnoreSelfLoopsInLifting : False; +MaximalAntennaSegmentHeight : 0.50000000; +AntennaWidth : 0.10000000; +BaseAnimationDuration : 1.00000000; +MetricToColor : [ + { + name : "Metric.McCabe_Complexity"; + color : { + Lower : { + Red : 1.00000000; + Green : 1.00000000; + Blue : 1.00000000; + Alpha : 1.00000000; + }; + Upper : { + Red : 1.00000000; + Green : 0.00000000; + Blue : 0.00000000; + Alpha : 1.00000000; + }; + NumberOfColors : 15; + }; + }; +]; +ZScoreScale : False; +ScaleOnlyLeafMetrics : True; +ErosionIssues : { + ShowInnerErosions : False; + ShowLeafErosions : False; + ShowIssuesInCodeWindow : False; + ErosionScalingFactor : 1.50000000; + StyleIssue : "Metric.Style"; + UniversalIssue : "Metric.Universal"; + MetricIssue : "Metric.Metric"; + Dead_CodeIssue : "Metric.Dead_Code"; + CycleIssue : "Metric.Cycle"; + CloneIssue : "Metric.Clone"; + ArchitectureIssue : "Metric.Architecture_Violations"; + StyleIssue_SUM : "Metric.Style_SUM"; + UniversalIssue_SUM : "Metric.Universal_SUM"; + MetricIssue_SUM : "Metric.Metric_SUM"; + Dead_CodeIssue_SUM : "Metric.Dead_Code_SUM"; + CycleIssue_SUM : "Metric.Cycle_SUM"; + CloneIssue_SUM : "Metric.Clone_SUM"; + ArchitectureIssue_SUM : "Metric.Architecture_Violations_SUM"; +}; +BoardSettings : { + LoadBoardOnStartup : False; + BoardPath : { + Root : "AssetsFolder"; + RelativePath : ""; + AbsolutePath : ""; + }; +}; +NodeLayout : { + NodeLayout : "Treemap"; + LayoutPath : { + Root : "AssetsFolder"; + RelativePath : ""; + AbsolutePath : ""; + }; + IncrementalTreeMap : { + LocalMovesDepth : 3; + LocalMovesBranchingLimit : 4; + PNorm : "P2Euclidean"; + GradientDescentPrecision : -4; + Padding : 5.00000000; + }; +}; +EdgeLayout : { + EdgeLayout : "Bundling"; + AnimationKind : "None"; + AnimateInnerEdges : True; + EdgeWidth : 0.01000000; + EdgesAboveBlocks : True; + Tension : 0.85000000; +}; +EdgeSelection : { + TubularSegments : 50; + Radius : 0.00500000; + RadialSegments : 8; + AreSelectable : True; +}; +CoseGraph : { + EdgeLength : 20; + UseSmartIdealEdgeCalculation : False; + UseSmartMultilevelScaling : False; + PerLevelIdealEdgeLengthFactor : 0.10000000; + UseSmartRepulsionRangeCalculation : False; + GravityStrength : 0.80000000; + CompoundGravityStrength : 1.50000000; + RepulsionStrength : 50.00000000; + MultiLevelScaling : False; + ListInnerNodeToggle : [ + ]; + InnerNodeLayout : [ + ]; + InnerNodeShape : [ + ]; + LoadedForNodeTypes : [ + ]; + UseCalculationParameter : True; + UseIterativeCalculation : False; +}; +data : { + kind : "Pipeline"; + pipeline : [ + { + kind : "VCS"; + PathGlobbing : [ + [ + "Assets/SEE/**/*.cs"; + True; + ]; + ]; + CommitID : "0878f91f900dc90d89c594c521ac1d3b9edd7097"; + RepositoryPath : { + Root : "ProjectFolder"; + RelativePath : ""; + AbsolutePath : ""; + }; + }; + ]; +}; diff --git a/Assets/StreamingAssets/SEE/SEEVCS.cfg.meta b/Assets/StreamingAssets/SEE/SEEVCS.cfg.meta new file mode 100644 index 0000000000..fc0ce24ee1 --- /dev/null +++ b/Assets/StreamingAssets/SEE/SEEVCS.cfg.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 4b36f207b6cebb94fa20f835eb51bb48 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-1.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-1.gxl.xz index 0417994246..d8a340e7e3 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-1.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-1.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-10.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-10.gxl.xz index 703b75ec06..adab7eaf72 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-10.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-10.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-100.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-100.gxl.xz index 161b73a58e..606646df3f 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-100.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-100.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-101.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-101.gxl.xz index 61a2305c47..4a4ad843b6 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-101.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-101.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-102.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-102.gxl.xz index 52d995268c..6721ed4903 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-102.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-102.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-11.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-11.gxl.xz index 16ed1ecd90..53a3c2b1e4 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-11.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-11.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-12.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-12.gxl.xz index 1448d77523..3ac57a35be 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-12.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-12.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-13.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-13.gxl.xz index df69ae0493..538c69a238 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-13.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-13.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-14.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-14.gxl.xz index a10d133626..4191dd74ff 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-14.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-14.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-15.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-15.gxl.xz index ad732f0ccf..399533c030 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-15.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-15.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-16.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-16.gxl.xz index 773fa3b65b..224f58da37 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-16.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-16.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-17.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-17.gxl.xz index 397a67dcb7..61f0b0a016 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-17.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-17.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-18.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-18.gxl.xz index 810c7db409..b484a00d63 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-18.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-18.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-19.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-19.gxl.xz index 63b6fd4ac6..c63c44df9e 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-19.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-19.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-2.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-2.gxl.xz index 6f9cd2f12c..27c975a34a 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-2.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-2.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-20.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-20.gxl.xz index 46b76bb55b..3269db6468 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-20.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-20.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-21.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-21.gxl.xz index 733b49dff4..59aff52c63 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-21.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-21.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-22.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-22.gxl.xz index a2fda5596d..0bb8548a33 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-22.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-22.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-23.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-23.gxl.xz index 185a0083ed..ae15b4781f 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-23.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-23.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-24.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-24.gxl.xz index 185a0083ed..ae15b4781f 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-24.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-24.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-25.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-25.gxl.xz index c1aeb9325c..353afead93 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-25.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-25.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-26.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-26.gxl.xz index 20290b131e..3cb384e23a 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-26.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-26.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-27.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-27.gxl.xz index 5a8cc838e2..19e6be1c07 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-27.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-27.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-28.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-28.gxl.xz index 1940c644f2..af577bb8be 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-28.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-28.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-29.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-29.gxl.xz index bc6c5d94e0..7c45892b32 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-29.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-29.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-3.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-3.gxl.xz index f7fd7da7bf..2bacce4d1c 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-3.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-3.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-30.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-30.gxl.xz index 7fb5ab052e..5210397949 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-30.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-30.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-31.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-31.gxl.xz index 0bad85a680..199c535182 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-31.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-31.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-32.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-32.gxl.xz index f28b3dacad..c676a2b929 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-32.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-32.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-33.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-33.gxl.xz index 54d703c40c..bf1cd455ae 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-33.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-33.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-34.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-34.gxl.xz index 4762179130..e6c897ccbc 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-34.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-34.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-35.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-35.gxl.xz index 9e0d4021d4..07a0d25501 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-35.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-35.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-36.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-36.gxl.xz index ab738ee66b..2c6d22054e 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-36.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-36.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-37.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-37.gxl.xz index f3dd2fdbfa..5350298df0 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-37.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-37.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-38.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-38.gxl.xz index 21e05cb88c..afe5f2c64c 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-38.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-38.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-39.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-39.gxl.xz index ebd8dadac6..01e5595726 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-39.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-39.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-4.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-4.gxl.xz index 08b7da65ec..b50cdafde1 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-4.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-4.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-40.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-40.gxl.xz index b5a04df97f..ff8fbff7a1 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-40.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-40.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-41.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-41.gxl.xz index b5a04df97f..ff8fbff7a1 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-41.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-41.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-42.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-42.gxl.xz index 87c6a03a8e..2bae8032a7 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-42.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-42.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-43.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-43.gxl.xz index f0f84912fe..28da10e8d7 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-43.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-43.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-44.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-44.gxl.xz index 1c2cf7eb8b..a28c4ec7ec 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-44.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-44.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-45.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-45.gxl.xz index 9888809a3a..4123e69de4 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-45.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-45.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-46.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-46.gxl.xz index 532d2fbe8c..07b6db42fc 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-46.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-46.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-47.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-47.gxl.xz index a3ea9fc5c6..8d14554d5f 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-47.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-47.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-48.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-48.gxl.xz index 7eac35d2da..f8ea09c84b 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-48.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-48.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-49.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-49.gxl.xz index aa50a83ce7..69424569eb 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-49.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-49.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-5.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-5.gxl.xz index 288aab794a..bd71f7af95 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-5.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-5.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-50.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-50.gxl.xz index eb86b1f12e..4685669c56 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-50.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-50.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-51.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-51.gxl.xz index eb86b1f12e..4685669c56 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-51.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-51.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-52.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-52.gxl.xz index d804c34fdc..3ff28bfcd6 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-52.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-52.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-53.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-53.gxl.xz index e1a33fb129..f6e95afd0c 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-53.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-53.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-54.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-54.gxl.xz index b3869b0e34..3f9cdf1dc3 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-54.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-54.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-55.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-55.gxl.xz index a228435343..aa7dde4974 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-55.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-55.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-56.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-56.gxl.xz index eb12d8e7a4..26d58a8789 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-56.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-56.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-57.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-57.gxl.xz index 15fb7fa2bb..4e950d9e71 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-57.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-57.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-58.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-58.gxl.xz index 20526443de..3c9878389f 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-58.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-58.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-59.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-59.gxl.xz index 7ba9445276..3ff89fef11 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-59.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-59.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-6.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-6.gxl.xz index 45ba23cb03..5d2a3904b6 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-6.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-6.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-60.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-60.gxl.xz index d6c0d051ab..c5a74dd8c3 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-60.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-60.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-61.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-61.gxl.xz index 56a521b553..a75e34237a 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-61.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-61.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-62.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-62.gxl.xz index 9688a39a2c..8381b682cd 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-62.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-62.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-63.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-63.gxl.xz index 91377b4dae..f11de6b7bf 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-63.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-63.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-64.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-64.gxl.xz index 19eeeea587..d2b7c1cad8 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-64.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-64.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-65.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-65.gxl.xz index 977690befd..18b0ff5f8c 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-65.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-65.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-66.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-66.gxl.xz index 977690befd..18b0ff5f8c 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-66.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-66.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-67.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-67.gxl.xz index 5ad34a43b8..08a4433a28 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-67.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-67.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-68.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-68.gxl.xz index 4494cd5e84..e7963f7e55 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-68.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-68.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-69.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-69.gxl.xz index 3d3b19a554..ae11226643 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-69.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-69.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-7.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-7.gxl.xz index d8b2c5a64b..644e5df7a2 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-7.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-7.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-70.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-70.gxl.xz index 0104763b47..1ac4dec2ac 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-70.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-70.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-71.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-71.gxl.xz index bef7058037..9fd15f355a 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-71.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-71.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-72.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-72.gxl.xz index 8598dc9fa9..edc443c95a 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-72.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-72.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-73.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-73.gxl.xz index 858ba80d69..c5ea50d260 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-73.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-73.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-74.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-74.gxl.xz index bc5c7385d5..4d40ca6a86 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-74.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-74.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-75.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-75.gxl.xz index 659997ec85..f2edb30340 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-75.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-75.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-76.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-76.gxl.xz index ef9fffa136..94cf0322e6 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-76.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-76.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-77.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-77.gxl.xz index 074ea5cfa1..e1f442a8d9 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-77.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-77.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-78.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-78.gxl.xz index 959e5faec0..c2277a72f0 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-78.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-78.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-79.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-79.gxl.xz index 67d87b91ad..8190ec757a 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-79.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-79.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-8.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-8.gxl.xz index 00b00d81af..528f55d782 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-8.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-8.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-80.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-80.gxl.xz index e4611413e4..2d9517373c 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-80.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-80.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-81.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-81.gxl.xz index efff77b767..d11685928e 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-81.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-81.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-82.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-82.gxl.xz index 5ad036f1b2..ee373a6e1f 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-82.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-82.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-83.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-83.gxl.xz index 30a20174bd..cb85ad4896 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-83.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-83.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-84.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-84.gxl.xz index aa1a2bb06f..844125f4d4 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-84.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-84.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-85.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-85.gxl.xz index b2cf1ee2df..068c5bf929 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-85.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-85.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-86.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-86.gxl.xz index b2cf1ee2df..068c5bf929 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-86.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-86.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-87.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-87.gxl.xz index f4973ef982..0619acb018 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-87.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-87.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-88.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-88.gxl.xz index dae61212cd..3dc5803610 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-88.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-88.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-89.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-89.gxl.xz index 2ba5f32c27..ed33605a76 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-89.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-89.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-9.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-9.gxl.xz index a6c50bfd51..8f11f11dec 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-9.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-9.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-90.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-90.gxl.xz index 0d5183edfa..2baba3744b 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-90.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-90.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-91.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-91.gxl.xz index f0f327f74e..55f28012f4 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-91.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-91.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-92.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-92.gxl.xz index 8dadcd98dd..d592ff1611 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-92.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-92.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-93.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-93.gxl.xz index f34feac856..ec4b4e356d 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-93.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-93.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-94.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-94.gxl.xz index 0b57f83bbc..71e2e61d03 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-94.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-94.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-95.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-95.gxl.xz index 37a2348500..c193971efb 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-95.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-95.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-96.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-96.gxl.xz index 16b1d2785a..f021dfe520 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-96.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-96.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-97.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-97.gxl.xz index 39dea13a2f..6fd0ddd7b8 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-97.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-97.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-98.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-98.gxl.xz index 6ece49a9a3..fe9f7d2d27 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-98.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-98.gxl.xz differ diff --git a/Assets/StreamingAssets/animation-clones-SEE/clones-99.gxl.xz b/Assets/StreamingAssets/animation-clones-SEE/clones-99.gxl.xz index 6ece49a9a3..fe9f7d2d27 100644 Binary files a/Assets/StreamingAssets/animation-clones-SEE/clones-99.gxl.xz and b/Assets/StreamingAssets/animation-clones-SEE/clones-99.gxl.xz differ diff --git a/Assets/packages.config b/Assets/packages.config index 81da0ae1ee..3c1a5879dd 100644 --- a/Assets/packages.config +++ b/Assets/packages.config @@ -16,6 +16,7 @@ +