Example #1
0
        public void Run(string[] args)
        {
            using (var window = new DisplayWindowBuilder(args)
                                .BackbufferSize(640, 480)
                                .QuitOnClose()
                                .AllowResize()
                                .AutoResizeBackBuffer()
                                .Build())
            {
                window.Resize  += wind_Resize;
                window.Closed  += wind_Closed;
                window.Closing += wind_Closing;

                while (window.IsClosed == false)
                {
                    Display.BeginFrame();
                    Display.Clear(Color.Blue);

                    Font.AgateSans.Size = 12;
                    Font.AgateSans.DrawText(instructionText + count);
                    Font.AgateSans.DrawText(0, Font.AgateSans.FontHeight, text);

                    Display.EndFrame();
                    AgateApp.KeepAlive();
                }

                if (closedEvent == false)
                {
                    System.Windows.Forms.MessageBox.Show(
                        "Closed event did not fire!");
                }
            }
        }
        public void Run(string[] args)
        {
            using (var wind = new DisplayWindowBuilder(args)
                              .BackbufferSize(300, 300)
                              .QuitOnClose()
                              .Title(Name)
                              .Build())
            {
                FrameBuffer buffer = new FrameBuffer(300, 300);

                while (AgateApp.IsAlive)
                {
                    IFont font = Font.AgateSans;
                    font.Size  = 24;
                    font.Color = Color.White;

                    Display.RenderTarget = buffer;
                    Display.BeginFrame();
                    Display.Clear(Color.Gray);

                    font.DrawText(string.Format("Time: {0}", Timing.TotalSeconds.ToString("0.0")));

                    Display.EndFrame();

                    Display.RenderTarget = wind.FrameBuffer;
                    Display.BeginFrame();
                    Display.Clear(Color.Gray);

                    buffer.RenderTarget.Draw();

                    Display.EndFrame();
                    AgateApp.KeepAlive();
                }
            }
        }
Example #3
0
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        public void Run(string[] args)
        {
            // create a random number generation object
            // so that we can make pretty colors.
            Random rand = new Random();

            frm = new DrawingTester();

            frm.btnClear.Click       += btnClear_Click;
            frm.btnDrawLine.Click    += btnDrawLine_Click;
            frm.btnDrawRect.Click    += btnDrawRect_Click;
            frm.btnDrawCircle.Click  += btnDrawCircle_Click;
            frm.btnDrawPolygon.Click += btnDrawPolygon_Click;
            frm.btnFillRect.Click    += btnFillRect_Click;
            frm.btnFillCircle.Click  += btnFillCircle_Click;
            frm.btnFillPolygon.Click += btnFillPolygon_Click;
            frm.Show();

            // This creates the window that we will be drawing in.
            // 640x480 are the dimensions of the screen area that we will write to
            using (var window = new DisplayWindowBuilder(args)
                                .RenderToControl(frm.panel1)
                                .AutoResizeBackBuffer()
                                .Build())
            {
                while (window.IsClosed == false)
                {
                    // Display.BeginFrame must be called before any rendering takes place.
                    Display.BeginFrame();

                    // Clear back buffer
                    Display.Clear();

                    // draw shapes
                    foreach (Shape s in shapes)
                    {
                        s.Draw();
                    }

                    // Display.EndFrame must be called after rendering is done
                    // in order to actually update the display.
                    Display.EndFrame();

                    // AgateApp.KeepAlive() is where we play nice window the OS,
                    // allowing events to be processed and such.
                    // This is also required to process events that happen in our OWN
                    // code (ie. user input), so be sure to call this once a frame.
                    AgateApp.KeepAlive();

                    // This gives a nice 1 second delay between each frame.
                    // Using the Sleep() call causes this application to
                    // relinquish CPU time.
                    System.Threading.Thread.Sleep(10);
                }
            }
        }
 public void Run(string[] args)
 {
     using (var window = new DisplayWindowBuilder(args)
                         .BackbufferSize(800, 600)
                         .QuitOnClose()
                         .Build())
     {
         new SceneStack().Start(this);
     }
 }
Example #5
0
        public void Run(string[] args)
        {
            using (var window = new DisplayWindowBuilder(args)
                                .BackbufferSize(800, 600)
                                .QuitOnClose()
                                .Build())
            {
                Input.Unhandled.KeyDown   += Keyboard_KeyDown;
                Input.Unhandled.MouseDown += Mouse_MouseDown;

                Surface surf = new Surface("Images/jellybean.png")
                {
                    Color = Color.Cyan
                };

                while (AgateApp.IsAlive)
                {
                    Display.BeginFrame();
                    Display.Clear(Color.DarkGreen);

                    switch (ortho)
                    {
                    case 1:
                        AgateBuiltInShaders.Basic2DShader.CoordinateSystem = new Rectangle
                                                                                 (0, 0, surf.SurfaceWidth * 2, surf.SurfaceHeight * 2);
                        break;

                    case 2:
                        AgateBuiltInShaders.Basic2DShader.CoordinateSystem = new Rectangle
                                                                                 (-surf.SurfaceWidth, -surf.SurfaceHeight, surf.SurfaceWidth * 2, surf.SurfaceHeight * 2);
                        break;
                    }

                    AgateBuiltInShaders.Basic2DShader.Activate();

                    Display.Primitives.FillRect(Color.Red, new Rectangle(-2, -2, 4, 4));
                    surf.Draw();

                    Display.FlushDrawBuffer();
                    AgateBuiltInShaders.Basic2DShader.CoordinateSystem =
                        new Rectangle(Point.Zero, Display.CurrentWindow.Size);
                    AgateBuiltInShaders.Basic2DShader.Activate();

                    Font.AgateSans.DrawText("Press space to cycle through coordinate systems.");

                    Display.EndFrame();

                    AgateApp.KeepAlive();
                }
            }
        }
Example #6
0
        public void ApplyCoordinates()
        {
            using (new AgateUnitTestPlatform().Initialize())
            {
                var coordRect = new Rectangle(-10, -25, 200, 300);

                var displayWindow = new DisplayWindowBuilder()
                                    .BackbufferSize(1000, 1000)
                                    .WithCoordinates(new FixedCoordinateSystem(coordRect))
                                    .Build();

                displayWindow.FrameBuffer.CoordinateSystem.RenderTargetSize = new Size(1000, 1000);
                Assert.AreEqual(coordRect, displayWindow.FrameBuffer.CoordinateSystem.Coordinates);
            }
        }
Example #7
0
        public void Run(string[] args)
        {
            using (var wind = new DisplayWindowBuilder(args)
                              .BackbufferSize(800, 600)
                              .QuitOnClose()
                              .Build())
            {
                Input.Unhandled.KeyDown += Keyboard_KeyDown;

                FontState state = new FontState
                {
                    Size  = 14,
                    Style = FontStyles.None,
                };

                FontSurface font = Font.AgateSans.Core.FontSurface(state);

                FontSurface unkerned = ConstructUnkernedFont(font);

                string text = ConstructKerningText(wind, font);

                while (AgateApp.IsAlive)
                {
                    Display.BeginFrame();
                    Display.Clear();

                    FontSurface thisFont = useKerning ? font : unkerned;

                    if (useKerning)
                    {
                        thisFont.DrawText(state, "Using kerning. (space to toggle)");
                    }
                    else
                    {
                        thisFont.DrawText(state, "No kerning used. (space to toggle)");
                    }

                    state.Color = Color.White;
                    thisFont.DrawText(state, new Vector2(0, thisFont.FontHeight(state)), text);

                    Display.EndFrame();
                    AgateApp.KeepAlive();
                }
            }
        }
Example #8
0
        public void Run(string[] args)
        {
            using (var window = new DisplayWindowBuilder(args)
                                .BackbufferSize(800, 600)
                                .QuitOnClose()
                                .Build())
            {
                Input.Unhandled.KeyDown += (sender, e) =>
                {
                    if (e.KeyCode == KeyCode.Escape)
                    {
                        AgateApp.IsAlive = false;
                    }
                };

                new SceneStack().Start(this);
            }
        }
Example #9
0
        public void Run(string[] args)
        {
            using (var window = new DisplayWindowBuilder(args)
                                .BackbufferSize(800, 600)
                                .QuitOnClose()
                                .Build())
            {
                LoopingStream sa = new LoopingStream();
                sa.Frequency = 100;

                StreamingSoundBuffer buf = new StreamingSoundBuffer(sa, SoundFormat.Pcm16(44100), 100);

                buf.Play();

                Stopwatch w = new Stopwatch();
                w.Start();

                var font = Font.AgateSans;

                while (AgateApp.IsAlive)
                {
                    Display.BeginFrame();
                    Display.Clear();

                    font.Color = Color.White;
                    font.DrawText(0, 0, string.Format("Frequency: {0}", sa.Frequency));

                    Display.EndFrame();
                    AgateApp.KeepAlive();

                    if (w.ElapsedMilliseconds > 500)
                    {
                        sa.Frequency += 50;
                        w.Reset();
                        w.Start();
                    }
                }

                buf.Stop();
            }
        }
        public void Run(string[] args)
        {
            using (var window = new DisplayWindowBuilder(args)
                                .BackbufferSize(800, 600)
                                .QuitOnClose()
                                .Build())
            {
                AgateConsole.CommandLibraries.Add(new LibraryVocabulary(this));

                while (AgateApp.IsAlive)
                {
                    Display.BeginFrame();
                    Display.Clear(Color.LightBlue);

                    Font.AgateSans.Color = Color.Black;
                    Font.AgateSans.DrawText("Press ~ key to open console.");

                    Display.EndFrame();
                    AgateApp.KeepAlive();
                }
            }
        }
Example #11
0
        public void Run(string[] args)
        {
            using (var window = new DisplayWindowBuilder(args)
                                .BackbufferSize(800, 600)
                                .QuitOnClose()
                                .Build())
            {
                snda = new SoundBuffer("snda.wav");
                sndb = new SoundBuffer("sndb.wav");

                IFont font = Font.AgateSans;

                Input.Unhandled.KeyDown   += Keyboard_KeyDown;
                Input.Unhandled.MouseDown += Mouse_MouseDown;

                while (AgateApp.IsAlive)
                {
                    Display.BeginFrame();
                    Display.Clear();

                    font.Size  = 14;
                    font.Color = Color.White;
                    font.DrawText("Press a for first sound, b for second sound.");

                    if (snda.IsPlaying)
                    {
                        font.DrawText(0, 30, "first sound is playing");
                    }
                    if (sndb.IsPlaying)
                    {
                        font.DrawText(0, 60, "second sound is playing");
                    }

                    Display.EndFrame();
                    AgateApp.KeepAlive();
                }
            }
        }
Example #12
0
        public void Run(string[] args)
        {
            MultipleRenderTargetExample myForm = new MultipleRenderTargetExample();

            myForm.Show();

            // create three display windows
            DisplayWindow wnd_1 = new DisplayWindowBuilder()
                                  .RenderToControl(myForm.pictureBox1)
                                  .AutoResizeBackBuffer()
                                  .Build();

            DisplayWindow wnd_2 = new DisplayWindowBuilder()
                                  .RenderToControl(myForm.pictureBox2)
                                  .AutoResizeBackBuffer()
                                  .Build();

            DisplayWindow wnd_3 = new DisplayWindowBuilder()
                                  .RenderToControl(myForm.pictureBox3)
                                  .AutoResizeBackBuffer()
                                  .Build();

            myForm.pictureBox3.Resize += wnd_3_Resize;

            // this is the code that will be called when the button is pressed
            myForm.btnDraw.Click         += btnDraw_Click;
            myForm.btnClearSurface.Click += btnClear_Click;
            myForm.btnDrawText.Click     += btnDrawText_Click;

            Surface image1 = new Surface("Images/jellybean.png");
            Surface image2 = new Surface("Images/9ball.png");

            image1.DisplayWidth  = 40;
            image1.DisplayHeight = (int)(image1.DisplayWidth * image1.SurfaceHeight / (double)image1.SurfaceWidth);
            image2.DisplayWidth  = 40;
            image2.DisplayHeight = (int)(image2.DisplayWidth * image2.SurfaceHeight / (double)image2.SurfaceWidth);

            double time = 0;

            frameBuffer = new FrameBuffer(wnd_3.Width, wnd_3.Height);
            ClearFrameBuffer();

            while (myForm.Visible)
            {
                // Render targets must be set before the call to BeginFrame,
                // and may not be changed between BeginFrame and EndFrame.
                // Use the FrameBuffer property of each DisplayWindow object
                // to set the Display.RenderTarget value.
                Display.RenderTarget = wnd_1.FrameBuffer;

                Display.BeginFrame();
                Display.Clear(Color.Red);
                Display.Primitives.FillRect(Color.Blue, new Rectangle(20, 20, 40, 30));
                image1.Draw(120 + (int)(30 * Math.Sin(time)), 20);

                Display.EndFrame();

                // now do the second window.
                Display.RenderTarget = wnd_2.FrameBuffer;

                Display.BeginFrame();
                Display.Clear(Color.Green);
                Display.Primitives.FillRect(Color.Yellow, new Rectangle(20, 20, 40, 30));
                image2.Draw(120 + (int)(30 * Math.Cos(time)), 20);

                Display.EndFrame();

                // draw the third window from the surface
                Display.RenderTarget = wnd_3.FrameBuffer;

                surf = frameBuffer.RenderTarget;

                Display.BeginFrame();
                Display.Clear(Color.Gray);
                surf.Draw(0, 0);
                Display.EndFrame();

                AgateApp.KeepAlive();
                time = Timing.TotalSeconds;
            }
        }
Example #13
0
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        public void Run(string[] args)
        {
            using (var wnd = new DisplayWindowBuilder(args)
                             .BackbufferSize(800, 600)
                             .QuitOnClose()
                             .Title(Name)
                             .Build())
            {
                double time = 0;

                Surface[] tiles = new Surface[3];

                tiles[0] = new Surface("Images/tile1.png");
                tiles[1] = tiles[0];
                tiles[2] = new Surface("Images/tile2.png");

                while (AgateApp.IsAlive && tiles.Any(x => x.IsLoaded == false))
                {
                    Display.BeginFrame();
                    Display.Clear(Color.Blue);
                    Display.EndFrame();
                    AgateApp.KeepAlive();
                }

                while (AgateApp.IsAlive)
                {
                    Display.BeginFrame();
                    Display.Clear(Color.FromRgb(
                                      (int)(128 * Math.Abs(Math.Cos(time / 3.5))),
                                      (int)(128 * Math.Abs(Math.Sin(time / 4.5))),
                                      (int)(128 * Math.Abs(Math.Sin(time / 5.0)))));

                    int x = 0, y = 0;

                    foreach (var tile in tiles)
                    {
                        tile.SetScale(1, 1);
                    }

                    y = 0;

                    for (int j = 0; j < 4; j++)
                    {
                        x = 0;
                        for (int i = 0; i < wnd.Width / tiles[0].DisplayWidth; i++)
                        {
                            int index = (i + j) % tiles.Length;

                            tiles[index].Draw(x, y);

                            x += tiles[0].DisplayWidth;
                        }

                        y += tiles[0].DisplayHeight;
                    }
                    y += tiles[0].DisplayHeight;

                    double scale = 1.32;

                    foreach (var tile in tiles)
                    {
                        tile.SetScale(scale, scale);
                    }

                    for (int j = 0; j < 4; j++)
                    {
                        x = 0;
                        for (int i = 0; i < wnd.Width / tiles[0].DisplayWidth; i++)
                        {
                            int index = (i + j) % tiles.Length;

                            tiles[index].Draw(x, y);

                            x += tiles[0].DisplayWidth;
                        }

                        y += tiles[0].DisplayHeight;
                    }

                    Display.EndFrame();
                    AgateApp.KeepAlive();

                    time += AgateApp.GameClock.Elapsed.TotalSeconds;
                }
            }
        }
Example #14
0
        public void Run(string[] args)
        {
            using (var window = new DisplayWindowBuilder(args)
                                .BackbufferSize(800, 600)
                                .QuitOnClose()
                                .Build())
            {
                var resources = new AgateResourceManager("UserInterface/FontAlignment.yaml");
                resources.InitializeContainer(this);

                var fonts = new List <IFont> {
                    Font.AgateSans, Font.AgateSerif, Font.AgateMono,
                };

                Input.Unhandled.KeyDown += Keyboard_KeyDown;

                int[] numbers = new int[] { 0, 0, 1, 11, 22, 33, 44, 99, 100, 111, 222, 333, 444, 555, 666, 777, 888, 999 };

                while (AgateApp.IsAlive)
                {
                    IFont f = fonts[fontIndex];

                    Display.BeginFrame();
                    Display.Clear(Color.Black);

                    var firstLineFont   = fonts.First();
                    var firstLineHeight = firstLineFont.FontHeight;

                    Display.Primitives.FillRect(Color.DarkSlateGray, new Rectangle(0, firstLineHeight, 300, 600));
                    Display.Primitives.FillRect(Color.DarkBlue, new Rectangle(300, firstLineHeight, 300, 600));

                    firstLineFont.DisplayAlignment = OriginAlignment.TopLeft;
                    firstLineFont.Color            = Color.White;
                    firstLineFont.DrawText(0, 0, "Press space to cycle fonts.");

                    f.Color            = Color.White;
                    f.DisplayAlignment = OriginAlignment.TopLeft;
                    f.DrawText(0, firstLineHeight, "Left-aligned numbers");

                    for (int i = 1; i < numbers.Length; i++)
                    {
                        f.DrawText(0, firstLineHeight + i * f.FontHeight, numbers[i].ToString());
                    }

                    f.DisplayAlignment = OriginAlignment.TopRight;
                    f.DrawText(600, firstLineHeight, "Right-aligned numbers");

                    for (int i = 1; i < numbers.Length; i++)
                    {
                        f.DrawText(600.0, firstLineHeight + i * f.FontHeight, numbers[i].ToString());
                    }

                    Display.EndFrame();
                    AgateApp.KeepAlive();

                    if (fontIndex >= fonts.Count)
                    {
                        fontIndex = 0;
                    }
                }
            }
        }
        static void Main(string[] args)
        {
            using (new AgateWinForms(args).Initialize())
                using (DisplayWindowCollection windows = new DisplayWindowBuilder()
                                                         .Title("Full Screen All Monitors")
                                                         .BackbufferSize(500, 400)
                                                         .QuitOnClose()
                                                         .BuildSeparateWindowsForAllScreens())
                {
                    // Register a key press handler. This will terminate the application if the escape key is pressed.
                    Input.Unhandled.KeyDown += (sender, e) =>
                    {
                        if (e.KeyCode == KeyCode.Escape)
                        {
                            AgateApp.IsAlive = false;
                        }
                    };

                    var font = new Font(Font.AgateSerif)
                    {
                        Size          = 14,
                        Style         = FontStyles.Bold,
                        TextAlignment = OriginAlignment.Center
                    };

                    // Run the game loop
                    while (AgateApp.IsAlive)
                    {
                        foreach (var window in windows)
                        {
                            // We need to set the render target before drawing so that we can draw to
                            // each monitor individually.
                            Display.RenderTarget = window.FrameBuffer;
                            Display.BeginFrame();
                            Display.Clear(Color.Gray);

                            Point point = new Point(10, 10);
                            Size  size  = new Size(15, 15);

                            for (int i = 0; i < 36; i++)
                            {
                                Rectangle dest = new Rectangle(point, size);
                                Display.Primitives.FillRect(Color.FromHsv(i * 10, 1, 1), dest);

                                point.X += 10;
                                point.Y += 10;
                            }

                            if (window.Screen.IsPrimary)
                            {
                                font.DrawText(350, 75, "Welcome to\nAgateLib!");
                            }
                            else
                            {
                                font.DrawText(350, 75, window.Screen.Bounds.ToString());
                            }

                            Display.EndFrame();
                        }

                        // A call to Core.KeepAlive is required to process input events and play nice with the OS.
                        AgateApp.KeepAlive();
                    }
                }
        }
Example #16
0
        public void Run(string[] args)
        {
            using (var wind = new DisplayWindowBuilder(args)
                              .BackbufferSize(800, 600)
                              .QuitOnClose()
                              .Build())
            {
                DisplayWindow fullWind = null;

                FontSurface bitmapFontSurface = FontSurface.BitmapMonospace("lotafont.png", new Size(16, 16));
                Font        bitmapFont        = new FontBuilder("lotafont").AddFontSurface(
                    new FontSettings(16, FontStyles.None), bitmapFontSurface).Build();

                int frame = 0;

                while (AgateApp.IsAlive)
                {
                    Display.BeginFrame();
                    Display.Clear(Color.DarkGray);

                    IFont font = Font.AgateSans;
                    font.Size = 12;

                    // test the color changing
                    font.Color = Color.LightGreen;
                    font.DrawText(20, 150, "This is regular green text.");
                    font.Color = Color.White;

                    // test display alignment property
                    Point  textPoint = new Point(100, 50);
                    string text      = string.Format("This text is centered on {0},{1}.", textPoint.X, textPoint.Y);
                    Size   textSize  = font.MeasureString(text);

                    // draw a box around where the text should be displayed.
                    Display.Primitives.DrawRect(Color.Gray,
                                                new Rectangle(textPoint.X - textSize.Width / 2, textPoint.Y - textSize.Height / 2,
                                                              textSize.Width, textSize.Height));

                    font.DisplayAlignment = OriginAlignment.Center;
                    font.DrawText(textPoint, text);
                    font.DisplayAlignment = OriginAlignment.TopLeft;

                    // test text scaling
                    font.Size = 24;
                    text      = "This text is twice as big.";
                    textPoint = new Point(50, 75);
                    textSize  = font.MeasureString(text);

                    // draw a box with the same size the text should appear as
                    Display.Primitives.DrawRect(Color.White, new Rectangle(textPoint, textSize));

                    font.DrawText(textPoint, text);
                    font.Size = 12;

                    // this draws a white background behind the text we want to Display.
                    text  = "F2: Toggle VSync   F5:  Toggle Windowed / Fullscreen      ";
                    text += "FPS: " + Display.FramesPerSecond.ToString("0.00") + "    ";

                    if (AgateApp.IsActive)
                    {
                        text += "Active";
                    }
                    else
                    {
                        text += "Not Active";
                    }

                    // figure out how big the displayed text will be
                    textSize = font.MeasureString(text);

                    // draw the white background
                    Display.Primitives.FillRect(Color.White, new Rectangle(new Point(0, 0), textSize));

                    // draw the text on top of the background
                    font.Color = Color.Black;
                    font.DrawText(text);                     // supplying no position arguments defaults to (0, 0)

                    // draw something which moves to let us know the program is running
                    Display.Primitives.FillRect(Color.Red, new Rectangle(
                                                    10, 200, 70 + (int)(50 * Math.Cos(frame / 10.0)), 50));

                    // do some bitmap font stuff
                    bitmapFont.DrawText(10, 350, "THIS IS BITMAP FONT TEXT.");

                    bitmapFont.Color = Color.Red;
                    bitmapFont.DrawText(10, 366, "THIS IS RED TEXT.");
                    bitmapFont.Color = Color.White;

                    bitmapFont.Size = 32;
                    bitmapFont.DrawText(10, 382, "THIS IS BIGG.");

                    Display.Primitives.FillRect(Color.Blue, new Rectangle(95, 425, 10, 10));
                    bitmapFont.TextAlignment = OriginAlignment.Center;
                    bitmapFont.DrawText(100, 430, "CHECK");
                    bitmapFont.TextAlignment = OriginAlignment.TopLeft;

                    Display.Primitives.FillRect(Color.Green, new Rectangle(-10, -10, 20, 20));

                    // and we're done.
                    Display.EndFrame();
                    AgateApp.KeepAlive();

                    frame++;

                    // toggle full screen if the user pressed F5;
                    if (Input.Unhandled.Keys[KeyCode.F5])
                    {
                        System.Diagnostics.Debug.Print("IsFullscreen: {0}", Display.CurrentWindow.IsFullScreen);

                        if (Display.CurrentWindow.IsFullScreen == false)
                        {
                            fullWind = DisplayWindow.CreateFullScreen("Font Tester", 800, 600);
                        }
                        else
                        {
                            fullWind.Dispose();
                            Display.RenderTarget = wind.FrameBuffer;
                        }

                        Input.Unhandled.Keys.ReleaseAll();
                        System.Diagnostics.Debug.Print("IsFullscreen: {0}", Display.CurrentWindow.IsFullScreen);
                    }
                    else if (Input.Unhandled.Keys[KeyCode.F2])
                    {
                        Display.RenderState.WaitForVerticalBlank = !Display.RenderState.WaitForVerticalBlank;
                        Input.Unhandled.Keys.Release(KeyCode.F2);
                    }
                    else if (Input.Unhandled.Keys[KeyCode.Escape])
                    {
                        Display.Dispose();
                        return;
                    }
                }
            }
        }