Exemplo n.º 1
0
        /// <summary>
        /// Actions under the resolver.
        /// </summary>
        protected override void ExecuteTaskResolved()
        {
            GuidCacheXml guidcachexml = GuidCacheXml.Load(new FileInfo(Bag.GetString(AttributeName.GuidCacheFile)).OpenRead());

            // Global structure of the WiX fragment file
            var wix = new Wix();
            var wixFragmentComponents = new Fragment();             // Fragment with the payload

            wix.AddChild(wixFragmentComponents);
            var wixDirectoryRef = new DirectoryRef();             // Mount into the directories tree, defined externally

            wixFragmentComponents.AddChild(wixDirectoryRef);
            wixDirectoryRef.Id = Bag.GetString(AttributeName.WixDirectoryId);
            var wixDirectory = new Directory();             // A locally created nameless directory that does not add any nested folders but defines the sources location

            wixDirectoryRef.AddChild(wixDirectory);
            wixDirectory.Id         = DirectoryId;
            wixDirectory.FileSource = Bag.GetString(AttributeName.ProductBinariesDir);
            var wixFragmentGroup = new Fragment();             // Fragment with the component-group that collects the components

            wix.AddChild(wixFragmentGroup);
            var wixComponentGroup = new ComponentGroup();             // ComponentGroup that collects the components

            wixFragmentGroup.AddChild(wixComponentGroup);
            wixComponentGroup.Id = Bag.GetString(AttributeName.WixComponentGroupId);

            // A component for the generated Registry entries
            var wixComponentRegistry = new Component();

            wixDirectory.AddChild(wixComponentRegistry);
            wixComponentRegistry.Id       = RegistryComponentIdPrefix;
            wixComponentRegistry.Guid     = guidcachexml[GuidIdXml.MsiComponent_ProductBinaries_Registry_Hkmu].ToString("B").ToUpper();
            wixComponentRegistry.DiskId   = Bag.Get <int>(AttributeName.DiskId);
            wixComponentRegistry.Location = Component.LocationType.local;
            var wixComponentRegistryRef = new ComponentRef();

            wixComponentGroup.AddChild(wixComponentRegistryRef);
            wixComponentRegistryRef.Id = wixComponentRegistry.Id;

            // Create the Registry key for the Plugins section
            CreatePluginsRegistryKey(wixComponentRegistry);

            // Load the AllAssemblies file
            AllAssembliesXml allassembliesxml = AllAssembliesXml.LoadFrom(Bag.Get <TaskItemByValue>(AttributeName.AllAssembliesXml).ItemSpec);

            // Tracks the files on the target machine, to prevent the same file from being installed both as an assembly and as a reference
            var mapTargetFiles = new Dictionary <string, string>();

            int nGeneratedComponents = ProcessAssemblies(wixDirectory, wixComponentGroup, wixComponentRegistry, allassembliesxml, mapTargetFiles, guidcachexml);

            // Save to the output file
            using (var xw = new XmlTextWriter(new FileStream(Bag.GetString(AttributeName.OutputFile), FileMode.Create, FileAccess.Write, FileShare.Read), Encoding.UTF8))
            {
                xw.Formatting = Formatting.Indented;
                wix.OutputXml(xw);
            }

            // Report (also to see the target in the build logs)
            Log.LogMessage(MessageImportance.Normal, "Generated {0} product binary components.", nGeneratedComponents);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Processes the installation files, produces the WiX data.
        /// </summary>
        private int ConvertFiles(DirectoryRef wixDirectoryRef, ComponentGroup wixComponentGroup, InstallationDataXml dataxml, IDictionary <string, string> macros)
        {
            int nProduced = 0;

            // Each installation folder derives a component, regardless of whether there are more files in the same folder, or not
            foreach (FolderXml folderxml in dataxml.Files)
            {
                folderxml.AssertValid();

                // Create the component with the files
                var wixComponent = new Component();
                wixComponent.Id       = string.Format("{0}.{1}", ComponentIdPrefix, folderxml.Id);
                wixComponent.Guid     = folderxml.MsiComponentGuid;
                wixComponent.DiskId   = Bag.Get <int>(AttributeName.DiskId);
                wixComponent.Location = Component.LocationType.local;
                ConvertFiles_AddToDirectory(folderxml, wixComponent, wixDirectoryRef);                 // To the directory structure

                // Add to the feature
                var wixComponentRef = new ComponentRef();
                wixComponentRef.Id = wixComponent.Id;
                wixComponentGroup.AddChild(wixComponentRef);                 // To the feature

                var diSource = new DirectoryInfo(Path.Combine(LocalInstallDataResolved.ResolveSourceDirRoot(folderxml.SourceRoot, Bag), folderxml.SourceDir));
                if (!diSource.Exists)
                {
                    throw new InvalidOperationException(string.Format("The source folder “{0}” does not exist.", diSource.FullName));
                }

                // Add files
                foreach (FileXml filexml in folderxml.Files)
                {
                    filexml.AssertValid();

                    FileInfo[] files = diSource.GetFiles(filexml.SourceName);
                    if (files.Length == 0)
                    {
                        throw new InvalidOperationException(string.Format("There are no files matching the “{0}” mask in the source folder “{1}”.", filexml.SourceName, diSource.FullName));
                    }
                    if ((files.Length > 1) && (filexml.TargetName.Length > 0))
                    {
                        throw new InvalidOperationException(string.Format("There are {2} files matching the “{0}” mask in the source folder “{1}”, in which case it's illegal to specify a target name for the file.", filexml.SourceName, diSource.FullName, files.Length));
                    }

                    foreach (FileInfo fiSource in files)
                    {
                        nProduced++;

                        var wixFile = new File();
                        wixComponent.AddChild(wixFile);
                        wixFile.Id       = string.Format("{0}.{1}.{2}", FileIdPrefix, folderxml.Id, fiSource.Name).Replace('-', '_').Replace(' ', '_'); // Replace chars that are not allowed in the ID
                        wixFile.Name     = filexml.TargetName.Length > 0 ? filexml.TargetName : fiSource.Name;                                          // Explicit target name, if present and if a single file; otherwise, use from source
                        wixFile.Checksum = YesNoType.yes;
                        wixFile.ReadOnly = YesNoType.yes;
                        wixFile.Source   = fiSource.FullName;
                    }
                }
            }

            return(nProduced);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Creates a new WiX Component for populating with the values of a specific hive, or reuses an existing one.
        /// Registry items from different hives must not be mixed within a single component.
        /// </summary>
        /// <param name="hive">Registry hive.</param>
        /// <param name="directory">A WiX directory to parent the newly-created component.</param>
        /// <param name="componentgroup">A group of components to register the newly-created component into.</param>
        protected Component GetComponentForHive(RegistryHiveXml hive, DirectoryRef directory, ComponentGroup componentgroup)
        {
            if (directory == null)
            {
                throw new ArgumentNullException("directory");
            }
            if (componentgroup == null)
            {
                throw new ArgumentNullException("componentgroup");
            }

            Component component;

            if (myMapHiveToComponent.TryGetValue(hive, out component)) // Lookup
            {
                return(component);                                     // Reuse existing
            }
            // Create a new one
            component = new Component();
            myMapHiveToComponent.Add(hive, component);
            directory.AddChild(component);
            component.Id = string.Format("{0}.{1}", ComponentIdPrefix, hive);

            // Chose a GUID for the component, assign
            component.Guid = myGuidCache[GetGuidId(hive)].ToString("B").ToUpperInvariant();

            // Register in the group
            var componentref = new ComponentRef();

            componentgroup.AddChild(componentref);
            componentref.Id = component.Id;

            return(component);
        }
Exemplo n.º 4
0
 private static void RenderPrefabObjectField <T>(ref ComponentRef <T> componentRef, ref bool dataChanged) where T : class
 {
     if (RenderObjectField(ref componentRef))
     {
         dataChanged = true;
     }
 }
Exemplo n.º 5
0
        private void Check_Checked(object sender, RoutedEventArgs e)
        {
            CheckBox     check = sender as CheckBox;
            ComponentRef com   = check.Tag as ComponentRef;

            com.SetActive(true);
        }
Exemplo n.º 6
0
                private static void RenderSceneObjectField <T>(ref ComponentRef <T> componentRef, ref bool dataChanged) where T : class
                {
                    //If current component is valid
                    if (componentRef.IsValid())
                    {
                        //Check its scene is loaded
                        Scene scene = componentRef.GetGameObjectRef().GetSceneRef().GetScene();

                        if (scene.isLoaded)
                        {
                            //Then render component field
                            if (RenderObjectField(ref componentRef))
                            {
                                dataChanged = true;
                            }
                        }
                        //If the scene is not loaded show warning and allow clearing of the component
                        else if (GameObjectRefEditor.RenderSceneNotLoadedField(componentRef.GetGameObjectRef()))
                        {
                            componentRef = new ComponentRef <T>(GameObjectRef.eSourceType.Scene);
                            dataChanged  = true;
                        }
                    }
                    //Else don't have a valid component set, renderer object field
                    else if (RenderObjectField(ref componentRef))
                    {
                        dataChanged = true;
                    }
                }
Exemplo n.º 7
0
 private void MakeMesh(ComponentRef reference)
 {
     reference.m_renderer.material       = m_meshMat;
     reference.m_renderer.material.color = Color.Lerp(m_minColor, m_maxColor, Random.Range(0.0f, 1.0f));
     m_objectVariations.SetCallback(reference.m_gameObjectSRT.SetSRT);
     m_hookerUpper.VaryModel(reference.m_mesh, m_numVertices, m_baseVerts, m_objectVariations, m_vertexGroups);
 }
Exemplo n.º 8
0
 public ComponentMethodRef(ComponentRef <Component> componentRef, string methodName)
 {
     _component       = componentRef;
     _methodName      = methodName;
     _method          = null;
     _editorCollapsed = false;
 }
Exemplo n.º 9
0
 public MaterialRef(ComponentRef <Renderer> renderer, int materialIndex)
 {
     _materialRef     = null;
     _materialIndex   = materialIndex;
     _renderer        = renderer;
     _editorCollapsed = false;
     _material        = null;
 }
Exemplo n.º 10
0
 public MaterialRef(AssetRef <Material> materialRef)
 {
     _materialRef     = materialRef;
     _materialIndex   = -1;
     _renderer        = new ComponentRef <Renderer>();
     _editorCollapsed = false;
     _material        = null;
 }
Exemplo n.º 11
0
 public MaterialRef(ComponentRef <Graphic> graphic)
 {
     _materialRef     = null;
     _materialIndex   = kGraphicMaterialIndex;
     _renderer        = new ComponentRef <Renderer>();
     _graphic         = graphic;
     _editorCollapsed = false;
     _material        = null;
 }
Exemplo n.º 12
0
            public bool RenderObjectProperties(GUIContent label)
            {
                bool dataChanged = false;

                if (label == null)
                {
                    label = new GUIContent();
                }

                label.text += " (" + this + ")";

                _editorFoldout = EditorGUILayout.Foldout(_editorFoldout, label);

                if (_editorFoldout)
                {
                    int origIndent = EditorGUI.indentLevel;
                    EditorGUI.indentLevel++;

                    eEditorType editorType = (eEditorType)EditorGUILayout.EnumPopup("Position Type", _editorType);

                    if (_editorType != editorType)
                    {
                        _editorType = editorType;
                        _pathNode   = new ComponentRef <PathNode>();
                        _path       = new ComponentRef <Path>();
                        _pathT      = 0.0f;
                        dataChanged = true;
                    }

                    switch (_editorType)
                    {
                    case eEditorType.Node:
                    {
                        _pathNode = SerializationEditorGUILayout.ObjectField(_pathNode, new GUIContent("Path Node"), ref dataChanged);
                    }
                    break;

                    case eEditorType.PathT:
                    {
                        _path = SerializationEditorGUILayout.ObjectField(_path, new GUIContent("Path"), ref dataChanged);

                        EditorGUI.BeginChangeCheck();
                        _pathT = EditorGUILayout.Slider(_pathT, 0.0f, 1.0f);
                        if (EditorGUI.EndChangeCheck())
                        {
                            dataChanged = true;
                        }
                    }
                    break;
                    }

                    EditorGUI.indentLevel = origIndent;
                }

                return(dataChanged);
            }
Exemplo n.º 13
0
 private void MakeBaseMesh(ComponentRef reference)
 {
     reference.m_renderer.material       = m_meshMat;
     reference.m_renderer.material.color = Color.Lerp(m_minColor, m_maxColor, 0.5f);
     m_objectVariations.SetCallback(reference.m_gameObjectSRT.SetSRT);
     Vector3[] positions, normals;
     VariationMath.OffsetTransformVertsIntoArrays(Vector3.zero, Matrix4x4.identity, out positions, out normals, m_numVertices, m_floatsPerVertex, m_normalOffset, m_baseVerts);
     m_hookerUpper.SetMeshValues(reference.m_mesh, positions, normals);
     m_objectVariations.ClearVariations();
 }
Exemplo n.º 14
0
        /// <summary>
        /// Processes the files that should be taken from the “References” folder and installed “AS IS”.
        /// </summary>
        private int ProcessReferences(Directory wixDirectory, ComponentGroup wixComponentGroup, AllAssembliesXml allassembliesxml, Dictionary <string, string> mapTargetFiles)
        {
            int nGeneratedComponents = 0;

            // Replaces illegal chars with underscores
            var regexMakeId = new Regex("[^a-zA-Z0-9_.]");

            foreach (ItemGroupXml group in allassembliesxml.ItemGroup)
            {
                if (group.References == null)
                {
                    continue;
                }
                foreach (ReferenceXml referencexml in group.References)
                {
                    nGeneratedComponents++;
                    var fiReference = new FileInfo(Path.Combine(Bag.GetString(AttributeName.ProductReferencesDir), referencexml.Include));
                    if (!fiReference.Exists)
                    {
                        throw new InvalidOperationException(string.Format("The reference file “{0}” could not be found.", fiReference.FullName));
                    }

                    string sIdSuffix = regexMakeId.Replace(fiReference.Name, "_");

                    // Create the component for the assembly (one per assembly)
                    var wixComponent = new Component();
                    wixDirectory.AddChild(wixComponent);
                    wixComponent.Id       = string.Format("{0}.{1}", FileComponentIdPrefix, sIdSuffix);
                    wixComponent.Guid     = referencexml.MsiGuid;
                    wixComponent.DiskId   = Bag.Get <int>(AttributeName.DiskId);
                    wixComponent.Location = Component.LocationType.local;

                    // Register component in the group
                    var componentref = new ComponentRef();
                    wixComponentGroup.AddChild(componentref);
                    componentref.Id = wixComponent.Id;

                    // Add the reference file (and make it the key path)
                    var wixFileReference = new File();
                    wixComponent.AddChild(wixFileReference);
                    wixFileReference.Id       = string.Format("{0}.{1}", FileIdPrefix, sIdSuffix);
                    wixFileReference.Name     = fiReference.Name;
                    wixFileReference.KeyPath  = YesNoType.yes;
                    wixFileReference.Checksum = YesNoType.yes;
                    wixFileReference.Vital    = YesNoType.yes;
                    wixFileReference.ReadOnly = YesNoType.yes;

                    RegisterTargetFile(wixFileReference.Name, string.Format("The “{0}” reference.", referencexml.Include), mapTargetFiles);
                }
            }

            return(nGeneratedComponents);
        }
Exemplo n.º 15
0
                private static ComponentRef <T> ComponentField <T>(ComponentRef <T> componentRef, GUIContent label, ref bool dataChanged) where T : class
                {
                    if (label == null)
                    {
                        label = new GUIContent();
                    }

                    label.text += " (" + componentRef + ")";

                    bool editorCollapsed = !EditorGUILayout.Foldout(!componentRef._editorCollapsed, label);

                    if (editorCollapsed != componentRef._editorCollapsed)
                    {
                        componentRef._editorCollapsed = editorCollapsed;
                        dataChanged = true;
                    }

                    if (!editorCollapsed)
                    {
                        int origIndent = EditorGUI.indentLevel;
                        EditorGUI.indentLevel++;

                        //Show drop down for gameobject type.
                        GameObjectRef.eSourceType sourceType = SerializationEditorGUILayout.ObjectField(componentRef.GetGameObjectRef().GetSourceType(), "Source Type", ref dataChanged);

                        if (sourceType != componentRef.GetGameObjectRef().GetSourceType())
                        {
                            componentRef = new ComponentRef <T>(sourceType);
                            dataChanged  = true;
                        }

                        switch (sourceType)
                        {
                        case GameObjectRef.eSourceType.Scene:
                            RenderSceneObjectField(ref componentRef, ref dataChanged);
                            break;

                        case GameObjectRef.eSourceType.Prefab:
                            RenderPrefabObjectField(ref componentRef, ref dataChanged);
                            break;

                        case GameObjectRef.eSourceType.Loaded:
                            RenderLoadedObjectField(ref componentRef, ref dataChanged);
                            break;
                        }

                        EditorGUI.indentLevel = origIndent;
                    }


                    return(componentRef);
                }
Exemplo n.º 16
0
            public bool RenderObjectProperties(GUIContent label)
            {
                bool dataChanged = false;

                if (label == null)
                {
                    label = new GUIContent();
                }

                label.text += " (" + this + ")";

                _editorFoldout = EditorGUILayout.Foldout(_editorFoldout, label);

                if (_editorFoldout)
                {
                    int origIndent = EditorGUI.indentLevel;
                    EditorGUI.indentLevel++;

                    _animator = SerializationEditorGUILayout.ObjectField(_animator, new GUIContent("Animator"), ref dataChanged);

                    IAnimator animator = _animator.GetComponent();

                    if (animator != null)
                    {
                        string[] animationNames = animator.GetAnimationNames();
                        int      currentIndex   = -1;

                        for (int i = 0; i < animationNames.Length; i++)
                        {
                            if (animationNames[i] == _animationId)
                            {
                                currentIndex = i;
                                break;
                            }
                        }

                        int index = EditorGUILayout.Popup("Animation", currentIndex == -1 ? 0 : currentIndex, animationNames);

                        if (currentIndex != index)
                        {
                            _animationId = animationNames[index];
                            dataChanged  = true;
                        }
                    }

                    EditorGUI.indentLevel = origIndent;
                }

                return(dataChanged);
            }
Exemplo n.º 17
0
    public GameObject MakeInstance()
    {
        ComponentRef  compRef = new ComponentRef();
        GameObject    display = new GameObject();
        GameObjectSRT toVary  = new GameObjectSRT();

        toVary.SetObject(display);

        compRef.m_mesh          = display.AddComponent <MeshFilter>().mesh;
        compRef.m_renderer      = display.AddComponent <MeshRenderer>();
        compRef.m_gameObjectSRT = toVary;

        MakeMesh(compRef);
        m_componentRefs.Add(compRef);
        return(display);
    }
Exemplo n.º 18
0
                private static void RenderLoadedObjectField <T>(ref ComponentRef <T> componentRef, ref bool dataChanged) where T : class
                {
                    //If the component is valid
                    if (componentRef.IsValid())
                    {
                        //Check its scene is loaded
                        Scene scene = componentRef.GetGameObjectRef().GetSceneRef().GetScene();

                        if (scene.isLoaded)
                        {
                            //If loaded and not tried finding editor loader, find it now
                            GameObjectLoader gameObjectLoader = componentRef.GetGameObjectRef().GetEditorGameObjectLoader(scene);

                            //If have a valid loader...
                            if (gameObjectLoader != null)
                            {
                                //Check its loaded
                                if (gameObjectLoader.IsLoaded())
                                {
                                    //Then render component field
                                    if (RenderObjectField(ref componentRef))
                                    {
                                        dataChanged = true;
                                    }
                                }
                                //If the loader is not loaded show warning and allow clearing of the component
                                else if (GameObjectRefEditor.RenderLoadedNotLoadedField(gameObjectLoader))
                                {
                                    componentRef = new ComponentRef <T>(GameObjectRef.eSourceType.Loaded);
                                    dataChanged  = true;
                                }
                            }
                        }
                        //If the scene is not loaded show warning and allow clearing of the component
                        else if (GameObjectRefEditor.RenderSceneNotLoadedField(componentRef.GetGameObjectRef()))
                        {
                            componentRef = new ComponentRef <T>(GameObjectRef.eSourceType.Loaded);
                            dataChanged  = true;
                        }
                    }
                    //Else don't have a component set, render component field
                    else if (RenderObjectField(ref componentRef))
                    {
                        dataChanged = true;
                    }
                }
Exemplo n.º 19
0
        public bool Execute()
        {
            try
            {
                if (Keys.ControlKey.IsPressed())
                {
                    if (MessageBox.Show("Debug?", "Debug UpdateHydraInstaller", MessageBoxButtons.YesNo) == DialogResult.Yes)
                    {
                        Debugger.Launch();
                    }
                }

                var      solutionPath    = Path.GetFullPath(Environment.ExpandEnvironmentVariables("%HYDRASOLUTIONPATH%"));
                var      productFilePath = Path.Combine(solutionPath, @"Hydra.InstallerStandalone\Product.wxs");
                var      applicationGeneratorBinaries = Path.Combine(solutionPath, @"ApplicationGenerator\bin", this.Configuration);
                var      applicationGeneratorProject  = Path.Combine(solutionPath, @"ApplicationGenerator\ApplicationGenerator.csproj");
                var      components       = ComponentFinder.GetComponents(applicationGeneratorBinaries, applicationGeneratorProject, this.TargetFramework, this.TargetAssembly, productFilePath);
                var      directories      = ComponentFinder.GetDirectories(applicationGeneratorBinaries, applicationGeneratorProject, this.TargetFramework, this.TargetAssembly, productFilePath);
                var      document         = XDocument.Load(productFilePath);
                var      namespaceManager = new XmlNamespaceManager(new NameTable());
                var      programMenuXml   = typeof(UpdateHydraInstaller).ReadResource <string>("ApplicationGeneratorBuildTasks.ProgramMenu.xml");
                XElement elementFeature;
                XElement elementDirectory;
                ApplicationGeneratorBuildTasks.Directory groupDirectory;
                ApplicationGeneratorBuildTasks.Directory topLeveDirectory;
                ComponentGroupRef componentGroupRef;
                XElement          elementGroupDirectory;
                XElement          elementComponentGroupRef;
                XElement          elementProgramMenu;
                XElement          elementProgramMenuDirectory;
                XElement          elementApplicationShortcutComponentRef;
                XElement          elementFragmentComponentGroup;
                ApplicationGeneratorBuildTasks.Directory programMenuDirectory;

                namespaceManager.AddNamespace("wi", "http://schemas.microsoft.com/wix/2006/wi");

                elementFeature   = document.XPathSelectElement("/wi:Wix/wi:Product/wi:Feature", namespaceManager);
                elementDirectory = document.XPathSelectElement("/wi:Wix/wi:Fragment/wi:Directory", namespaceManager);

                elementFeature.Elements().Remove();
                elementDirectory.Elements().Remove();

                foreach (var component in components)
                {
                    var elementComponent    = component.ToXElement <Component>();
                    var elementFile         = component.File.ToXElement <ApplicationGeneratorBuildTasks.File>();
                    var elementComponentRef = component.CreateComponentRef().ToXElement <ComponentRef>();

                    elementComponent.Add(elementFile);

                    elementDirectory.Add(elementComponent);
                    elementFeature.Add(elementComponentRef);
                }

                groupDirectory           = new ApplicationGeneratorBuildTasks.Directory(this.TargetAssembly + ".Binaries");
                componentGroupRef        = groupDirectory.CreateComponentGroupRef();
                elementGroupDirectory    = groupDirectory.ToXElement <ApplicationGeneratorBuildTasks.Directory>();
                elementComponentGroupRef = componentGroupRef.ToXElement <ComponentGroupRef>();

                elementDirectory.Add(elementGroupDirectory);
                elementFeature.Add(elementComponentGroupRef);

                topLeveDirectory = new ApplicationGeneratorBuildTasks.Directory();
                topLeveDirectory.Directories.AddRange(directories);

                AddDirectories(elementFeature, elementDirectory, topLeveDirectory);

                // add start menu elements

                elementProgramMenuDirectory = elementDirectory.XPathSelectElement("wi:Directory[@Id='ProgramMenuFolder']", namespaceManager);

                if (elementProgramMenuDirectory != null)
                {
                    elementProgramMenuDirectory.Remove();
                }

                programMenuDirectory = new ApplicationGeneratorBuildTasks.Directory("ProgramMenuFolder")
                {
                    Directories = new List <ApplicationGeneratorBuildTasks.Directory> {
                        new ApplicationGeneratorBuildTasks.Directory("HydraShortcuts", "CloudIDEaaS Hydra")
                    }
                };
                elementProgramMenuDirectory = programMenuDirectory.ToXElement <ApplicationGeneratorBuildTasks.Directory>();

                foreach (var shortcutDirectory in programMenuDirectory.Directories)
                {
                    elementProgramMenuDirectory.Add(shortcutDirectory.ToXElement <ApplicationGeneratorBuildTasks.Directory>());
                }

                elementDirectory.Add(elementProgramMenuDirectory);

                elementApplicationShortcutComponentRef = elementFeature.XPathSelectElement("wi:ComponentRef[@Id='ApplicationShortcut']", namespaceManager);

                if (elementApplicationShortcutComponentRef != null)
                {
                    elementApplicationShortcutComponentRef.Remove();
                }

                elementApplicationShortcutComponentRef = new ComponentRef("ApplicationShortcut").ToXElement <ComponentRef>();

                elementFeature.Add(new ComponentRef("ApplicationShortcut").ToXElement <ComponentRef>());

                elementFragmentComponentGroup = document.Root.XPathSelectElement("wi:Fragment/wi:ComponentGroup[@Id='ProductComponents']", namespaceManager);

                if (elementFragmentComponentGroup != null)
                {
                    elementFragmentComponentGroup.Remove();
                }

                elementProgramMenu = XElement.Parse(programMenuXml);
                document.Root.Add(elementProgramMenu);

                document.Save(productFilePath, SaveOptions.DisableFormatting);
            }
            catch (Exception ex)
            {
                var error = string.Format("Error installing Hydra Visual Studio templates. \r\nError: {0}", ex.ToString());

                var message = new BuildErrorEventArgs(string.Empty, string.Empty, string.Empty, 0, 0, 0, 0, error, "", "", DateTime.Now);
                this.BuildEngine.LogErrorEvent(message);

                Console.WriteLine(error);

                return(false);
            }

            return(true);
        }
Exemplo n.º 20
0
 public virtual void VisitComponentRef(ComponentRef node)
 {
 }
                public static ComponentMethodRef <T> ComponentMethodRefField <T>(ComponentMethodRef <T> componentMethodRef, Type returnType, GUIContent label, ref bool dataChanged)
                {
                    if (label == null)
                    {
                        label = new GUIContent();
                    }

                    label.text += " (" + componentMethodRef + ")";

                    bool editorCollapsed = !EditorGUILayout.Foldout(!componentMethodRef._editorCollapsed, label);

                    if (editorCollapsed != componentMethodRef._editorCollapsed)
                    {
                        componentMethodRef._editorCollapsed = editorCollapsed;
                        dataChanged = true;
                    }

                    if (!editorCollapsed)
                    {
                        int origIndent = EditorGUI.indentLevel;
                        EditorGUI.indentLevel++;

                        bool componentChanged = false;
                        ComponentRef <Component> component = SerializationEditorGUILayout.ObjectField(componentMethodRef.GetComponentRef(), new GUIContent("Object"), ref componentChanged);

                        Component currentComponent = component.GetBaseComponent();

                        if (currentComponent != null)
                        {
                            string[] methodNames = GetMethods(currentComponent, returnType);

                            if (methodNames.Length > 0)
                            {
                                int currentIndex = 0;

                                for (int i = 0; i < methodNames.Length; i++)
                                {
                                    if (methodNames[i] == componentMethodRef.GetMethodName())
                                    {
                                        currentIndex = i;
                                        break;
                                    }
                                }

                                EditorGUI.BeginChangeCheck();

                                int newIndex = EditorGUILayout.Popup("Method", currentIndex, methodNames);

                                if (EditorGUI.EndChangeCheck() || componentChanged)
                                {
                                    componentMethodRef = new ComponentMethodRef <T>(component, methodNames[newIndex]);
                                    dataChanged        = true;
                                }
                            }
                            else if (componentChanged)
                            {
                                componentMethodRef = new ComponentMethodRef <T>(component, string.Empty);
                                dataChanged        = true;
                            }
                        }
                        else if (componentChanged)
                        {
                            componentMethodRef = new ComponentMethodRef <T>(component, string.Empty);
                            dataChanged        = true;
                        }

                        EditorGUI.indentLevel = origIndent;
                    }

                    return(componentMethodRef);
                }
Exemplo n.º 22
0
                public static object PropertyField(object obj, GUIContent label, ref bool dataChanged, GUIStyle style, params GUILayoutOption[] options)
                {
                    MaterialRef materialRef = (MaterialRef)obj;

                    if (label == null)
                    {
                        label = new GUIContent();
                    }

                    label.text += " (" + materialRef + ")";

                    bool editorCollapsed = !EditorGUILayout.Foldout(!materialRef._editorCollapsed, label);

                    if (editorCollapsed != materialRef._editorCollapsed)
                    {
                        materialRef._editorCollapsed = editorCollapsed;
                        dataChanged = true;
                    }

                    if (!editorCollapsed)
                    {
                        int origIndent = EditorGUI.indentLevel;
                        EditorGUI.indentLevel++;

                        eEdtiorType editorType = materialRef.GetMaterialIndex() == -1 ? eEdtiorType.Shared : eEdtiorType.Instanced;


                        //Draw type dropdown
                        {
                            EditorGUI.BeginChangeCheck();
                            editorType = (eEdtiorType)EditorGUILayout.EnumPopup("Material Type", editorType);

                            if (EditorGUI.EndChangeCheck())
                            {
                                dataChanged = true;
                                materialRef = new MaterialRef(editorType == eEdtiorType.Shared ? -1 : 0);
                            }
                        }

                        //Draw renderer field
                        if (editorType == eEdtiorType.Instanced)
                        {
                            bool renderChanged = false;
                            ComponentRef <Renderer> rendererComponentRef = SerializationEditorGUILayout.ObjectField(materialRef.GetRenderer(), new GUIContent("Renderer"), ref renderChanged);

                            if (renderChanged)
                            {
                                dataChanged = true;
                                materialRef = new MaterialRef(rendererComponentRef, 0);
                            }

                            //Show drop down for materials
                            Renderer renderer = rendererComponentRef.GetComponent();

                            if (renderer != null)
                            {
                                string[] materialNames = new string[renderer.sharedMaterials.Length];

                                for (int i = 0; i < materialNames.Length; i++)
                                {
                                    materialNames[i] = renderer.sharedMaterials[i].name;
                                }

                                EditorGUI.BeginChangeCheck();
                                int materialIndex = EditorGUILayout.Popup("Material", materialRef.GetMaterialIndex(), materialNames);
                                if (EditorGUI.EndChangeCheck())
                                {
                                    dataChanged = true;
                                    materialRef = new MaterialRef(rendererComponentRef, materialIndex);
                                }
                            }
                        }
                        else
                        {
                            bool assetChanged            = false;
                            AssetRef <Material> assetRef = SerializationEditorGUILayout.ObjectField(materialRef.GetAsset(), new GUIContent("Material"), ref assetChanged);

                            if (assetChanged)
                            {
                                dataChanged = true;
                                materialRef = new MaterialRef(assetRef);
                            }
                        }

                        EditorGUI.indentLevel = origIndent;
                    }


                    return(materialRef);
                }
Exemplo n.º 23
0
        /// <summary>
        /// Processes those AllAssemblies.Xml entries that are our own product assemblies.
        /// </summary>
        private int ProcessAssemblies(Directory wixDirectory, ComponentGroup wixComponentGroup, Component wixComponentRegistry, AllAssembliesXml allassembliesxml, Dictionary <string, string> mapTargetFiles, GuidCacheXml guidcachexml)
        {
            // Collect the assemblies
            int nGeneratedComponents = 0;

            foreach (ItemGroupXml group in allassembliesxml.ItemGroup)
            {
                if (group.AllAssemblies == null)
                {
                    continue;
                }
                foreach (AssemblyXml assemblyxml in group.AllAssemblies)
                {
                    nGeneratedComponents++;
                    FileInfo fiAssembly = FindAssemblyFile(assemblyxml);
                    string   sExtension = fiAssembly.Extension.TrimStart('.');                   // The extension without a dot

                    // Create the component for the assembly (one per assembly)
                    var wixComponent = new Component();
                    wixDirectory.AddChild(wixComponent);
                    wixComponent.Id       = string.Format("{0}.{1}.{2}", FileComponentIdPrefix, assemblyxml.Include, sExtension);
                    wixComponent.Guid     = assemblyxml.MsiGuid;
                    wixComponent.DiskId   = Bag.Get <int>(AttributeName.DiskId);
                    wixComponent.Location = Component.LocationType.local;

                    // Register component in the group
                    var componentref = new ComponentRef();
                    wixComponentGroup.AddChild(componentref);
                    componentref.Id = wixComponent.Id;

                    // Add the assembly file (and make it the key path)
                    var wixFileAssembly = new File();
                    wixComponent.AddChild(wixFileAssembly);
                    wixFileAssembly.Id       = string.Format("{0}.{1}.{2}", FileIdPrefix, assemblyxml.Include, sExtension);
                    wixFileAssembly.Name     = string.Format("{0}.{1}", assemblyxml.Include, sExtension);
                    wixFileAssembly.KeyPath  = YesNoType.yes;
                    wixFileAssembly.Checksum = YesNoType.yes;
                    wixFileAssembly.Vital    = YesNoType.yes;
                    wixFileAssembly.ReadOnly = YesNoType.yes;

                    RegisterTargetFile(wixFileAssembly.Name, string.Format("The {0} product assembly.", assemblyxml.Include), mapTargetFiles);

                    // Check whether it's a managed or native assembly
                    AssemblyName assemblyname = null;
                    try
                    {
                        assemblyname = AssemblyName.GetAssemblyName(fiAssembly.FullName);
                    }
                    catch (BadImageFormatException)
                    {
                    }

                    // Add COM Self-Registration data
                    if (assemblyxml.ComRegister)
                    {
                        /*
                         * foreach(ISchemaElement harvested in HarvestComSelfRegistration(wixFileAssembly, fiAssembly))
                         * wixComponent.AddChild(harvested);
                         */
                        SelfRegHarvester.Harvest(fiAssembly, assemblyname != null, wixComponent, wixFileAssembly);
                    }

                    // Ensure the managed DLL has a strong name
                    if ((assemblyname != null) && (Bag.Get <bool>(AttributeName.RequireStrongName)))
                    {
                        byte[] token = assemblyname.GetPublicKeyToken();
                        if ((token == null) || (token.Length == 0))
                        {
                            throw new InvalidOperationException(string.Format("The assembly “{0}” does not have a strong name.", assemblyxml.Include));
                        }
                    }

                    // Add PDBs
                    if (Bag.Get <bool>(AttributeName.IncludePdb))
                    {
                        HarvestSatellite(assemblyxml, assemblyxml.Include + ".pdb", wixComponent, MissingSatelliteErrorLevel.Error, "PDB file", mapTargetFiles);
                    }

                    // Add XmlDocs
                    if ((assemblyname != null) && (Bag.Get <bool>(AttributeName.IncludeXmlDoc)))
                    {
                        HarvestSatellite(assemblyxml, assemblyxml.Include + ".xml", wixComponent, MissingSatelliteErrorLevel.Error, "XmlDoc file", mapTargetFiles);
                    }

                    // Add configs
                    HarvestSatellite(assemblyxml, assemblyxml.Include + "." + sExtension + ".config", wixComponent, (assemblyxml.HasAppConfig ? MissingSatelliteErrorLevel.Error : MissingSatelliteErrorLevel.None), "application configuration file", mapTargetFiles);
                    HarvestSatellite(assemblyxml, assemblyxml.Include + "." + sExtension + ".manifest", wixComponent, (assemblyxml.HasMainfest ? MissingSatelliteErrorLevel.Error : MissingSatelliteErrorLevel.None), "assembly manifest file", mapTargetFiles);
                    HarvestSatellite(assemblyxml, assemblyxml.Include + ".XmlSerializers." + sExtension, wixComponent, (assemblyxml.HasXmlSerializers ? MissingSatelliteErrorLevel.Error : MissingSatelliteErrorLevel.None), "serialization assembly", mapTargetFiles);

                    // Add publisher policy assemblies
                    if (assemblyname != null)
                    {
                        HarvestPublisherPolicyAssemblies(assemblyxml, wixDirectory, wixComponentGroup, ref nGeneratedComponents, mapTargetFiles, guidcachexml);
                    }

                    // Register as an OmeaPlugin
                    if (assemblyname != null)
                    {
                        RegisterPlugin(assemblyxml, wixFileAssembly, wixComponentRegistry);
                    }
                }
            }
            return(nGeneratedComponents);
        }
Exemplo n.º 24
0
        private void HarvestPublisherPolicyAssemblies(AssemblyXml assemblyxml, Directory directory, ComponentGroup componentgroup, ref int nGeneratedComponents, Dictionary <string, string> mapTargetFiles, GuidCacheXml guidcachexml)
        {
            if (!Bag.Get <bool>(AttributeName.IncludePublisherPolicy))
            {
                return;
            }

            int    nWasGeneratedComponents = nGeneratedComponents;
            var    diFolder           = new DirectoryInfo(Bag.GetString(AttributeName.ProductBinariesDir));
            string sSatelliteWildcard = string.Format("Policy.*.{0}.{1}", assemblyxml.Include, "dll");             // Even an EXE assembly has a DLL policy file

            foreach (FileInfo fiPolicyAssembly in diFolder.GetFiles(sSatelliteWildcard))
            {
                // Find the companion policy config file
                var fiPolicyConfig = new FileInfo(Path.ChangeExtension(fiPolicyAssembly.FullName, ".Config"));
                if (!fiPolicyConfig.Exists)
                {
                    throw new InvalidOperationException(string.Format("Could not locate the publisher policy config file for the assembly “{0}”; expected: “{1}”.", fiPolicyAssembly.FullName, fiPolicyConfig.FullName));
                }

                // We have to create a new component for each of the DLLs we'd like to GAC as publisher policy assemblies
                nGeneratedComponents++;

                // Create the component for the assembly (one per assembly)
                var component = new Component();
                directory.AddChild(component);
                component.Id       = string.Format("{0}.{1}", FileComponentIdPrefix, fiPolicyAssembly.Name);
                component.Guid     = guidcachexml[assemblyxml.Include + " PublisherPolicy"].ToString("B").ToUpper();
                component.DiskId   = Bag.Get <int>(AttributeName.DiskId);
                component.Location = Component.LocationType.local;

                // Register component in the group
                var componentref = new ComponentRef();
                componentgroup.AddChild(componentref);
                componentref.Id = component.Id;

                // Add the assembly file (and make it the key path)
                var fileAssembly = new File();
                component.AddChild(fileAssembly);
                fileAssembly.Id       = string.Format("{0}.{1}", FileIdPrefix, fiPolicyAssembly.Name);
                fileAssembly.Name     = fiPolicyAssembly.Name;
                fileAssembly.KeyPath  = YesNoType.yes;
                fileAssembly.Checksum = YesNoType.yes;
                fileAssembly.Vital    = YesNoType.no;
                fileAssembly.Assembly = File.AssemblyType.net;
                fileAssembly.ReadOnly = YesNoType.yes;

                RegisterTargetFile(fileAssembly.Name, string.Format("Publisher policy assembly file for the {0} product assembly.", assemblyxml.Include), mapTargetFiles);

                // Add the policy config file
                var filePolicy = new File();
                component.AddChild(filePolicy);
                filePolicy.Id       = string.Format("{0}.{1}", FileIdPrefix, fiPolicyConfig.Name);
                filePolicy.Name     = fiPolicyConfig.Name;
                filePolicy.KeyPath  = YesNoType.no;
                filePolicy.Checksum = YesNoType.yes;
                filePolicy.Vital    = YesNoType.no;
                filePolicy.ReadOnly = YesNoType.yes;

                RegisterTargetFile(fileAssembly.Name, string.Format("Publisher policy configuration file for the {0} product assembly.", assemblyxml.Include), mapTargetFiles);
            }

            if (nWasGeneratedComponents == nGeneratedComponents)            // None were actually collected
            {
                throw new InvalidOperationException(string.Format("Could not locate the Publisher Policy assemblies for the “{0}” assembly. The expected full path is “{1}\\{2}”.", assemblyxml.Include, diFolder.FullName, sSatelliteWildcard));
            }
        }
Exemplo n.º 25
0
                private static bool RenderObjectField <T>(ref ComponentRef <T> componentRef) where T : class
                {
                    bool       dataChanged = false;
                    GameObject gameObject  = null;

                    Component currentComponent = componentRef.GetBaseComponent();

                    //If T is a type of component can just use a normal object field
                    if (typeof(Component).IsAssignableFrom(typeof(T)))
                    {
                        Component component = EditorGUILayout.ObjectField(kLabel, currentComponent, typeof(T), true) as Component;
                        gameObject = component != null ? component.gameObject : null;
                    }
                    //Otherwise allow gameobject to be set and deal with typing when rendering index
                    else
                    {
                        gameObject = (GameObject)EditorGUILayout.ObjectField(kLabel, currentComponent != null ? currentComponent.gameObject : null, typeof(GameObject), true);
                    }

                    //Render drop down for typed components on the gameobject
                    if (gameObject != null)
                    {
                        //Show drop down to allow selecting different components on same game object
                        int         currentIndex  = 0;
                        Component[] allComponents = gameObject.GetComponents <Component>();

                        List <GUIContent> validComponentLabels = new List <GUIContent>();
                        List <Component>  validComponents      = new List <Component>();
                        List <Type>       validComponentTypes  = new List <Type>();

                        for (int i = 0; i < allComponents.Length; i++)
                        {
                            T typedComponent = allComponents[i] as T;

                            if (typedComponent != null)
                            {
                                int numberComponentsTheSameType = 0;
                                foreach (Type type in validComponentTypes)
                                {
                                    if (type == allComponents[i].GetType())
                                    {
                                        numberComponentsTheSameType++;
                                    }
                                }

                                validComponentLabels.Add(new GUIContent(allComponents[i].GetType().Name + (numberComponentsTheSameType > 0 ? " (" + numberComponentsTheSameType + ")" : "")));
                                validComponents.Add(allComponents[i]);
                                validComponentTypes.Add(allComponents[i].GetType());

                                if (allComponents[i] == currentComponent)
                                {
                                    currentIndex = validComponents.Count - 1;
                                }
                            }
                        }

                        if (validComponents.Count > 1)
                        {
                            int selectedIndex = EditorGUILayout.Popup(kLabel, currentIndex, validComponentLabels.ToArray());
                            dataChanged = currentComponent != validComponents[selectedIndex] || componentRef.GetComponentIndex() != selectedIndex;
                            if (dataChanged)
                            {
                                componentRef = new ComponentRef <T>(componentRef.GetGameObjectRef().GetSourceType(), validComponents[selectedIndex], selectedIndex);
                            }
                        }
                        else if (validComponents.Count == 1)
                        {
                            dataChanged = currentComponent != validComponents[0] || componentRef.GetComponentIndex() != 0;
                            if (dataChanged)
                            {
                                componentRef = new ComponentRef <T>(componentRef.GetGameObjectRef().GetSourceType(), validComponents[0], 0);
                            }
                        }
                        else if (validComponents.Count == 0)
                        {
                            dataChanged = currentComponent != null || componentRef.GetComponentIndex() != 0;
                            if (dataChanged)
                            {
                                componentRef = new ComponentRef <T>(componentRef.GetGameObjectRef().GetSourceType());
                            }
                        }
                    }
                    else
                    {
                        dataChanged = currentComponent != null || componentRef.GetComponentIndex() != 0;
                        if (dataChanged)
                        {
                            componentRef = new ComponentRef <T>(componentRef.GetGameObjectRef().GetSourceType());
                        }
                    }

                    return(dataChanged);
                }
Exemplo n.º 26
0
 protected override void ClearStaticValue()
 {
     _value = new ComponentRef <T>();
 }
Exemplo n.º 27
0
 public static ArtifactInstance FromComponentRef(ComponentRef c)
 {
     return(new ArtifactInstance(CKSetupClient.CKSetupType, c.Name + '/' + c.TargetFramework.ToStringFramework(), c.Version));
 }
Exemplo n.º 28
0
        private void createComponentRow(PropertyInfo prop, int row, PropertyFieldAttribute attr)
        {
            IList <ComponentRef> componentList = prop.GetValue(_selectedObject) as IList <ComponentRef>;
            Type comType = typeof(ComponentRef);

            for (int i = 0; i < componentList.Count; i++)
            {
                gridAddRowDef();
                CheckBox check = createCheckBox();
                check.IsChecked  = componentList[i].GetIsActive();
                check.Tag        = componentList[i];
                check.Checked   += Check_Checked;
                check.Unchecked += Check_Unchecked;
                gridAddTitle(15, componentList[i].GetName());
                gridAddEnd();
                ComponentRef          com       = componentList[i];
                List <ComponentField> fieldList = com.GetFields();
                for (int j = 0; j < fieldList.Count; j++)
                {
                    gridAddRowDef();
                    TextBlock title = gridAddTitle(30, fieldList[j].Name);
                    if ((fieldList[j].Type & ComponentFieldType.FT_FLOAT) == ComponentFieldType.FT_FLOAT ||
                        (fieldList[j].Type & ComponentFieldType.FT_INT) == ComponentFieldType.FT_INT)
                    {
                        NumberTextBox tb = createNumberTextBox();
                        tb.Text    = fieldList[j].Value;
                        tb.Tag     = fieldList[j];
                        tb._KeyUp += comNumTb__KeyUp;
                        title.Tag  = fieldList[j];
                        float value = Convert.ToSingle(fieldList[j].Value);
                        title.MouseLeftButtonDown += new MouseButtonEventHandler((object sender, MouseButtonEventArgs e) =>
                        {
                            _mouseDown = true;
                            _mousePosX = e.GetPosition(null).X;
                            title.CaptureMouse();
                        });
                        title.MouseMove += new MouseEventHandler((object sender, MouseEventArgs e) =>
                        {
                            if (_mouseDown)
                            {
                                double xPos      = e.GetPosition(null).X;
                                ComponentField f = (sender as TextBlock).Tag as ComponentField;
                                if ((f.Type & ComponentFieldType.FT_READONLY) == ComponentFieldType.FT_READONLY)
                                {
                                    return;
                                }
                                if ((f.Type & ComponentFieldType.FT_FLOAT) == ComponentFieldType.FT_FLOAT)
                                {
                                    if (xPos > _mousePosX)
                                    {
                                        value += 0.01f;
                                    }
                                    else if (xPos < _mousePosX)
                                    {
                                        value -= 0.01f;
                                    }
                                }
                                else if ((f.Type & ComponentFieldType.FT_INT) == ComponentFieldType.FT_INT)
                                {
                                    if (xPos > _mousePosX)
                                    {
                                        value += 1;
                                    }
                                    else if (xPos < _mousePosX)
                                    {
                                        value -= 1;
                                    }
                                }
                                tb.Text = value.ToString();
                                f.SetValue(tb.Text);
                                _mousePosX = xPos;
                            }
                        });
                        title.MouseLeftButtonUp += new MouseButtonEventHandler((object sender, MouseButtonEventArgs e) =>
                        {
                            _mouseDown = false;
                            _mousePosX = 0;
                            title.ReleaseMouseCapture();
                        });
                    }
                    else if (fieldList[j].Type == ComponentFieldType.FT_OBJECT)
                    {
                        TextBox tb = createTextBox(true);
                        tb.Tag    = fieldList[j];
                        tb.KeyUp += comTb_KeyUp;
                        tb.Text   = fieldList[j].Value;
                    }
                    else if (fieldList[j].Type == ComponentFieldType.FT_BOOLEAN)
                    {
                        ComboBox cb = createBoolControl();
                        cb.Tag = fieldList[j];
                        cb.SelectionChanged += comCb_SelectionChanged;
                        cb.SelectedIndex     = fieldList[j].Value == "true" ? 0 : 1;
                    }
                    else if (fieldList[j].Type == ComponentFieldType.FT_VECTOR3)
                    {
                        var      vecElement = new Vector3Control();
                        string[] vStr       = fieldList[j].Value.Split(',');
                        Vector3  vec        = new Vector3(Convert.ToSingle(vStr[0]), Convert.ToSingle(vStr[1]), Convert.ToSingle(vStr[2]));
                        vecElement.ValueObject     = vec;
                        vecElement.Margin          = new Thickness(0, 2, 2, 0);
                        vecElement.BorderThickness = new Thickness(0);
                        vecElement.Tag             = fieldList[j];
                        Grid.SetColumn(vecElement, 1);
                        Grid.SetRow(vecElement, _panelParent.RowDefinitions.Count - 1);
                        var template = (ControlTemplate)_View.Resources["validationErrorTemplate"];
                        Validation.SetErrorTemplate(vecElement, template);
                        vecElement.EnterKeyDown += VecElement_EnterKeyDown;
                        _panelParent.Children.Add(vecElement);
                    }
                    else
                    {
                        TextBox tb = createTextBox(false);
                        tb.Tag    = fieldList[j];
                        tb.KeyUp += comTb_KeyUp;
                        tb.Text   = fieldList[j].Value;
                    }
                    gridAddEnd();
                }
            }
        }