All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.lwjgl.vulkan.VkFramebufferCreateInfo Maven / Gradle / Ivy

Go to download

A new generation graphics and compute API that provides high-efficiency, cross-platform access to modern GPUs used in a wide variety of devices from PCs and consoles to mobile phones and embedded platforms.

There is a newer version: 3.3.4
Show newest version
/*
 * Copyright LWJGL. All rights reserved.
 * License terms: https://www.lwjgl.org/license
 * MACHINE GENERATED FILE, DO NOT EDIT
 */
package org.lwjgl.vulkan;

import java.nio.*;

import org.lwjgl.*;
import org.lwjgl.system.*;

import static org.lwjgl.system.Checks.*;
import static org.lwjgl.system.MemoryUtil.*;
import static org.lwjgl.system.MemoryStack.*;

/**
 * Structure specifying parameters of a newly created framebuffer.
 * 
 * 
Description
* *

Image subresources used as attachments must not be accessed in any other way for the duration of a render pass instance. For depth/stencil attachments, they can be used as both attachments and non-attachments as long as the layout of the image subresource is {@link KHRMaintenance2#VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR} and the non-attachment usage only accesses the depth aspect, or the layout of the image subresource is {@link KHRMaintenance2#VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR} and the non-attachment usage only accesses the stencil aspect. Use of non-attachment aspects in this case is only well defined if the attachment is used in the subpass where the non-attachment access is being made, or the layout of the image subresource is constant throughout the entire render pass instance, including the {@code initialLayout} and {@code finalLayout}.

* *
Note
* *

These restrictions mean that the render pass has full knowledge of all uses of all of the attachments, so that the implementation is able to make correct decisions about when and how to perform layout transitions, when to overlap execution of subpasses, etc.

*
* *

It is legal for a subpass to use no color or depth/stencil attachments, and rather use shader side effects such as image stores and atomics to produce an output. In this case, the subpass continues to use the {@code width}, {@code height}, and {@code layers} of the framebuffer to define the dimensions of the rendering area, and the {@code rasterizationSamples} from each pipeline's {@link VkPipelineMultisampleStateCreateInfo} to define the number of samples used in rasterization; however, if {@link VkPhysicalDeviceFeatures}{@code ::variableMultisampleRate} is {@link VK10#VK_FALSE FALSE}, then all pipelines to be bound with a given zero-attachment subpass must have the same value for {@link VkPipelineMultisampleStateCreateInfo}{@code ::rasterizationSamples}.

* *
Valid Usage
* *
    *
  • {@code attachmentCount} must be equal to the attachment count specified in {@code renderPass}
  • *
  • Any given element of {@code pAttachments} that is used as a color attachment or resolve attachment by {@code renderPass} must have been created with a {@code usage} value including {@link VK10#VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT IMAGE_USAGE_COLOR_ATTACHMENT_BIT}
  • *
  • Any given element of {@code pAttachments} that is used as a depth/stencil attachment by {@code renderPass} must have been created with a {@code usage} value including {@link VK10#VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT}
  • *
  • Any given element of {@code pAttachments} that is used as an input attachment by {@code renderPass} must have been created with a {@code usage} value including {@link VK10#VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT IMAGE_USAGE_INPUT_ATTACHMENT_BIT}
  • *
  • Any given element of {@code pAttachments} must have been created with an {@code VkFormat} value that matches the {@code VkFormat} specified by the corresponding {@link VkAttachmentDescription} in {@code renderPass}
  • *
  • Any given element of {@code pAttachments} must have been created with a {@code samples} value that matches the {@code samples} value specified by the corresponding {@link VkAttachmentDescription} in {@code renderPass}
  • *
  • Any given element of {@code pAttachments} must have dimensions at least as large as the corresponding framebuffer dimension
  • *
  • Any given element of {@code pAttachments} must only specify a single mip level
  • *
  • Any given element of {@code pAttachments} must have been created with the identity swizzle
  • *
  • {@code width} must be greater than 0.
  • *
  • {@code width} must be less than or equal to {@link VkPhysicalDeviceLimits}{@code ::maxFramebufferWidth}
  • *
  • {@code height} must be greater than 0.
  • *
  • {@code height} must be less than or equal to {@link VkPhysicalDeviceLimits}{@code ::maxFramebufferHeight}
  • *
  • {@code layers} must be greater than 0.
  • *
  • {@code layers} must be less than or equal to {@link VkPhysicalDeviceLimits}{@code ::maxFramebufferLayers}
  • *
  • Any given element of {@code pAttachments} that is a 2D or 2D array image view taken from a 3D image must not be a depth/stencil format
  • *
* *
Valid Usage (Implicit)
* *
    *
  • {@code sType} must be {@link VK10#VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO}
  • *
  • {@code pNext} must be {@code NULL}
  • *
  • {@code flags} must be 0
  • *
  • {@code renderPass} must be a valid {@code VkRenderPass} handle
  • *
  • If {@code attachmentCount} is not 0, {@code pAttachments} must be a pointer to an array of {@code attachmentCount} valid {@code VkImageView} handles
  • *
  • Both of {@code renderPass}, and the elements of {@code pAttachments} that are valid handles must have been created, allocated, or retrieved from the same {@code VkDevice}
  • *
* *
See Also
* *

{@link VK10#vkCreateFramebuffer CreateFramebuffer}

* *

Member documentation

* *
    *
  • {@code sType} – the type of this structure.
  • *
  • {@code pNext} – {@code NULL} or a pointer to an extension-specific structure.
  • *
  • {@code flags} – reserved for future use.
  • *
  • {@code renderPass} – a render pass that defines what render passes the framebuffer will be compatible with. See Render Pass Compatibility for details.
  • *
  • {@code attachmentCount} – the number of attachments.
  • *
  • {@code pAttachments} – an array of {@code VkImageView} handles, each of which will be used as the corresponding attachment in a render pass instance.
  • *
  • {@code width} – {@code width}, {@code height} and {@code layers} define the dimensions of the framebuffer. If the render pass uses multiview, then {@code layers} must be one and each attachment requires a number of layers that is greater than the maximum bit index set in the view mask in the subpasses in which it is used.
  • *
  • {@code height} – see {@code width}
  • *
  • {@code layers} – see {@code width}
  • *
* *

Layout

* *
 * struct VkFramebufferCreateInfo {
 *     VkStructureType sType;
 *     const void * pNext;
 *     VkFramebufferCreateFlags flags;
 *     VkRenderPass renderPass;
 *     uint32_t attachmentCount;
 *     const VkImageView * pAttachments;
 *     uint32_t width;
 *     uint32_t height;
 *     uint32_t layers;
 * }
*/ public class VkFramebufferCreateInfo extends Struct implements NativeResource { /** The struct size in bytes. */ public static final int SIZEOF; public static final int ALIGNOF; /** The struct member offsets. */ public static final int STYPE, PNEXT, FLAGS, RENDERPASS, ATTACHMENTCOUNT, PATTACHMENTS, WIDTH, HEIGHT, LAYERS; static { Layout layout = __struct( __member(4), __member(POINTER_SIZE), __member(4), __member(8), __member(4), __member(POINTER_SIZE), __member(4), __member(4), __member(4) ); SIZEOF = layout.getSize(); ALIGNOF = layout.getAlignment(); STYPE = layout.offsetof(0); PNEXT = layout.offsetof(1); FLAGS = layout.offsetof(2); RENDERPASS = layout.offsetof(3); ATTACHMENTCOUNT = layout.offsetof(4); PATTACHMENTS = layout.offsetof(5); WIDTH = layout.offsetof(6); HEIGHT = layout.offsetof(7); LAYERS = layout.offsetof(8); } VkFramebufferCreateInfo(long address, ByteBuffer container) { super(address, container); } /** * Creates a {@link VkFramebufferCreateInfo} instance at the current position of the specified {@link ByteBuffer} container. Changes to the buffer's content will be * visible to the struct instance and vice versa. * *

The created instance holds a strong reference to the container object.

*/ public VkFramebufferCreateInfo(ByteBuffer container) { this(memAddress(container), checkContainer(container, SIZEOF)); } @Override public int sizeof() { return SIZEOF; } /** Returns the value of the {@code sType} field. */ @NativeType("VkStructureType") public int sType() { return nsType(address()); } /** Returns the value of the {@code pNext} field. */ @NativeType("const void *") public long pNext() { return npNext(address()); } /** Returns the value of the {@code flags} field. */ @NativeType("VkFramebufferCreateFlags") public int flags() { return nflags(address()); } /** Returns the value of the {@code renderPass} field. */ @NativeType("VkRenderPass") public long renderPass() { return nrenderPass(address()); } /** Returns the value of the {@code attachmentCount} field. */ @NativeType("uint32_t") public int attachmentCount() { return nattachmentCount(address()); } /** Returns a {@link LongBuffer} view of the data pointed to by the {@code pAttachments} field. */ @NativeType("const VkImageView *") public LongBuffer pAttachments() { return npAttachments(address()); } /** Returns the value of the {@code width} field. */ @NativeType("uint32_t") public int width() { return nwidth(address()); } /** Returns the value of the {@code height} field. */ @NativeType("uint32_t") public int height() { return nheight(address()); } /** Returns the value of the {@code layers} field. */ @NativeType("uint32_t") public int layers() { return nlayers(address()); } /** Sets the specified value to the {@code sType} field. */ public VkFramebufferCreateInfo sType(@NativeType("VkStructureType") int value) { nsType(address(), value); return this; } /** Sets the specified value to the {@code pNext} field. */ public VkFramebufferCreateInfo pNext(@NativeType("const void *") long value) { npNext(address(), value); return this; } /** Sets the specified value to the {@code flags} field. */ public VkFramebufferCreateInfo flags(@NativeType("VkFramebufferCreateFlags") int value) { nflags(address(), value); return this; } /** Sets the specified value to the {@code renderPass} field. */ public VkFramebufferCreateInfo renderPass(@NativeType("VkRenderPass") long value) { nrenderPass(address(), value); return this; } /** Sets the address of the specified {@link LongBuffer} to the {@code pAttachments} field. */ public VkFramebufferCreateInfo pAttachments(@NativeType("const VkImageView *") LongBuffer value) { npAttachments(address(), value); return this; } /** Sets the specified value to the {@code width} field. */ public VkFramebufferCreateInfo width(@NativeType("uint32_t") int value) { nwidth(address(), value); return this; } /** Sets the specified value to the {@code height} field. */ public VkFramebufferCreateInfo height(@NativeType("uint32_t") int value) { nheight(address(), value); return this; } /** Sets the specified value to the {@code layers} field. */ public VkFramebufferCreateInfo layers(@NativeType("uint32_t") int value) { nlayers(address(), value); return this; } /** Initializes this struct with the specified values. */ public VkFramebufferCreateInfo set( int sType, long pNext, int flags, long renderPass, LongBuffer pAttachments, int width, int height, int layers ) { sType(sType); pNext(pNext); flags(flags); renderPass(renderPass); pAttachments(pAttachments); width(width); height(height); layers(layers); return this; } /** * Copies the specified struct data to this struct. * * @param src the source struct * * @return this struct */ public VkFramebufferCreateInfo set(VkFramebufferCreateInfo src) { memCopy(src.address(), address(), SIZEOF); return this; } // ----------------------------------- /** Returns a new {@link VkFramebufferCreateInfo} instance allocated with {@link MemoryUtil#memAlloc memAlloc}. The instance must be explicitly freed. */ public static VkFramebufferCreateInfo malloc() { return create(nmemAlloc(SIZEOF)); } /** Returns a new {@link VkFramebufferCreateInfo} instance allocated with {@link MemoryUtil#memCalloc memCalloc}. The instance must be explicitly freed. */ public static VkFramebufferCreateInfo calloc() { return create(nmemCalloc(1, SIZEOF)); } /** Returns a new {@link VkFramebufferCreateInfo} instance allocated with {@link BufferUtils}. */ public static VkFramebufferCreateInfo create() { return new VkFramebufferCreateInfo(BufferUtils.createByteBuffer(SIZEOF)); } /** Returns a new {@link VkFramebufferCreateInfo} instance for the specified memory address or {@code null} if the address is {@code NULL}. */ public static VkFramebufferCreateInfo create(long address) { return address == NULL ? null : new VkFramebufferCreateInfo(address, null); } /** * Returns a new {@link VkFramebufferCreateInfo.Buffer} instance allocated with {@link MemoryUtil#memAlloc memAlloc}. The instance must be explicitly freed. * * @param capacity the buffer capacity */ public static Buffer malloc(int capacity) { return create(__malloc(capacity, SIZEOF), capacity); } /** * Returns a new {@link VkFramebufferCreateInfo.Buffer} instance allocated with {@link MemoryUtil#memCalloc memCalloc}. The instance must be explicitly freed. * * @param capacity the buffer capacity */ public static Buffer calloc(int capacity) { return create(nmemCalloc(capacity, SIZEOF), capacity); } /** * Returns a new {@link VkFramebufferCreateInfo.Buffer} instance allocated with {@link BufferUtils}. * * @param capacity the buffer capacity */ public static Buffer create(int capacity) { return new Buffer(__create(capacity, SIZEOF)); } /** * Create a {@link VkFramebufferCreateInfo.Buffer} instance at the specified memory. * * @param address the memory address * @param capacity the buffer capacity */ public static Buffer create(long address, int capacity) { return address == NULL ? null : new Buffer(address, null, -1, 0, capacity, capacity); } // ----------------------------------- /** Returns a new {@link VkFramebufferCreateInfo} instance allocated on the thread-local {@link MemoryStack}. */ public static VkFramebufferCreateInfo mallocStack() { return mallocStack(stackGet()); } /** Returns a new {@link VkFramebufferCreateInfo} instance allocated on the thread-local {@link MemoryStack} and initializes all its bits to zero. */ public static VkFramebufferCreateInfo callocStack() { return callocStack(stackGet()); } /** * Returns a new {@link VkFramebufferCreateInfo} instance allocated on the specified {@link MemoryStack}. * * @param stack the stack from which to allocate */ public static VkFramebufferCreateInfo mallocStack(MemoryStack stack) { return create(stack.nmalloc(ALIGNOF, SIZEOF)); } /** * Returns a new {@link VkFramebufferCreateInfo} instance allocated on the specified {@link MemoryStack} and initializes all its bits to zero. * * @param stack the stack from which to allocate */ public static VkFramebufferCreateInfo callocStack(MemoryStack stack) { return create(stack.ncalloc(ALIGNOF, 1, SIZEOF)); } /** * Returns a new {@link VkFramebufferCreateInfo.Buffer} instance allocated on the thread-local {@link MemoryStack}. * * @param capacity the buffer capacity */ public static Buffer mallocStack(int capacity) { return mallocStack(capacity, stackGet()); } /** * Returns a new {@link VkFramebufferCreateInfo.Buffer} instance allocated on the thread-local {@link MemoryStack} and initializes all its bits to zero. * * @param capacity the buffer capacity */ public static Buffer callocStack(int capacity) { return callocStack(capacity, stackGet()); } /** * Returns a new {@link VkFramebufferCreateInfo.Buffer} instance allocated on the specified {@link MemoryStack}. * * @param stack the stack from which to allocate * @param capacity the buffer capacity */ public static Buffer mallocStack(int capacity, MemoryStack stack) { return create(stack.nmalloc(ALIGNOF, capacity * SIZEOF), capacity); } /** * Returns a new {@link VkFramebufferCreateInfo.Buffer} instance allocated on the specified {@link MemoryStack} and initializes all its bits to zero. * * @param stack the stack from which to allocate * @param capacity the buffer capacity */ public static Buffer callocStack(int capacity, MemoryStack stack) { return create(stack.ncalloc(ALIGNOF, capacity, SIZEOF), capacity); } // ----------------------------------- /** Unsafe version of {@link #sType}. */ public static int nsType(long struct) { return memGetInt(struct + VkFramebufferCreateInfo.STYPE); } /** Unsafe version of {@link #pNext}. */ public static long npNext(long struct) { return memGetAddress(struct + VkFramebufferCreateInfo.PNEXT); } /** Unsafe version of {@link #flags}. */ public static int nflags(long struct) { return memGetInt(struct + VkFramebufferCreateInfo.FLAGS); } /** Unsafe version of {@link #renderPass}. */ public static long nrenderPass(long struct) { return memGetLong(struct + VkFramebufferCreateInfo.RENDERPASS); } /** Unsafe version of {@link #attachmentCount}. */ public static int nattachmentCount(long struct) { return memGetInt(struct + VkFramebufferCreateInfo.ATTACHMENTCOUNT); } /** Unsafe version of {@link #pAttachments() pAttachments}. */ public static LongBuffer npAttachments(long struct) { return memLongBuffer(memGetAddress(struct + VkFramebufferCreateInfo.PATTACHMENTS), nattachmentCount(struct)); } /** Unsafe version of {@link #width}. */ public static int nwidth(long struct) { return memGetInt(struct + VkFramebufferCreateInfo.WIDTH); } /** Unsafe version of {@link #height}. */ public static int nheight(long struct) { return memGetInt(struct + VkFramebufferCreateInfo.HEIGHT); } /** Unsafe version of {@link #layers}. */ public static int nlayers(long struct) { return memGetInt(struct + VkFramebufferCreateInfo.LAYERS); } /** Unsafe version of {@link #sType(int) sType}. */ public static void nsType(long struct, int value) { memPutInt(struct + VkFramebufferCreateInfo.STYPE, value); } /** Unsafe version of {@link #pNext(long) pNext}. */ public static void npNext(long struct, long value) { memPutAddress(struct + VkFramebufferCreateInfo.PNEXT, value); } /** Unsafe version of {@link #flags(int) flags}. */ public static void nflags(long struct, int value) { memPutInt(struct + VkFramebufferCreateInfo.FLAGS, value); } /** Unsafe version of {@link #renderPass(long) renderPass}. */ public static void nrenderPass(long struct, long value) { memPutLong(struct + VkFramebufferCreateInfo.RENDERPASS, value); } /** Sets the specified value to the {@code attachmentCount} field of the specified {@code struct}. */ public static void nattachmentCount(long struct, int value) { memPutInt(struct + VkFramebufferCreateInfo.ATTACHMENTCOUNT, value); } /** Unsafe version of {@link #pAttachments(LongBuffer) pAttachments}. */ public static void npAttachments(long struct, LongBuffer value) { memPutAddress(struct + VkFramebufferCreateInfo.PATTACHMENTS, memAddressSafe(value)); nattachmentCount(struct, value == null ? 0 : value.remaining()); } /** Unsafe version of {@link #width(int) width}. */ public static void nwidth(long struct, int value) { memPutInt(struct + VkFramebufferCreateInfo.WIDTH, value); } /** Unsafe version of {@link #height(int) height}. */ public static void nheight(long struct, int value) { memPutInt(struct + VkFramebufferCreateInfo.HEIGHT, value); } /** Unsafe version of {@link #layers(int) layers}. */ public static void nlayers(long struct, int value) { memPutInt(struct + VkFramebufferCreateInfo.LAYERS, value); } /** * Validates pointer members that should not be {@code NULL}. * * @param struct the struct to validate */ public static void validate(long struct) { if (nattachmentCount(struct) != 0) { check(memGetAddress(struct + VkFramebufferCreateInfo.PATTACHMENTS)); } } /** * Calls {@link #validate(long)} for each struct contained in the specified struct array. * * @param array the struct array to validate * @param count the number of structs in {@code array} */ public static void validate(long array, int count) { for (int i = 0; i < count; i++) { validate(array + i * SIZEOF); } } // ----------------------------------- /** An array of {@link VkFramebufferCreateInfo} structs. */ public static class Buffer extends StructBuffer implements NativeResource { /** * Creates a new {@link VkFramebufferCreateInfo.Buffer} instance backed by the specified container. * * Changes to the container's content will be visible to the struct buffer instance and vice versa. The two buffers' position, limit, and mark values * will be independent. The new buffer's position will be zero, its capacity and its limit will be the number of bytes remaining in this buffer divided * by {@link VkFramebufferCreateInfo#SIZEOF}, and its mark will be undefined. * *

The created buffer instance holds a strong reference to the container object.

*/ public Buffer(ByteBuffer container) { super(container, container.remaining() / SIZEOF); } Buffer(long address, ByteBuffer container, int mark, int pos, int lim, int cap) { super(address, container, mark, pos, lim, cap); } @Override protected Buffer self() { return this; } @Override protected Buffer newBufferInstance(long address, ByteBuffer container, int mark, int pos, int lim, int cap) { return new Buffer(address, container, mark, pos, lim, cap); } @Override protected VkFramebufferCreateInfo newInstance(long address) { return new VkFramebufferCreateInfo(address, container); } @Override public int sizeof() { return SIZEOF; } /** Returns the value of the {@code sType} field. */ @NativeType("VkStructureType") public int sType() { return VkFramebufferCreateInfo.nsType(address()); } /** Returns the value of the {@code pNext} field. */ @NativeType("const void *") public long pNext() { return VkFramebufferCreateInfo.npNext(address()); } /** Returns the value of the {@code flags} field. */ @NativeType("VkFramebufferCreateFlags") public int flags() { return VkFramebufferCreateInfo.nflags(address()); } /** Returns the value of the {@code renderPass} field. */ @NativeType("VkRenderPass") public long renderPass() { return VkFramebufferCreateInfo.nrenderPass(address()); } /** Returns the value of the {@code attachmentCount} field. */ @NativeType("uint32_t") public int attachmentCount() { return VkFramebufferCreateInfo.nattachmentCount(address()); } /** Returns a {@link LongBuffer} view of the data pointed to by the {@code pAttachments} field. */ @NativeType("const VkImageView *") public LongBuffer pAttachments() { return VkFramebufferCreateInfo.npAttachments(address()); } /** Returns the value of the {@code width} field. */ @NativeType("uint32_t") public int width() { return VkFramebufferCreateInfo.nwidth(address()); } /** Returns the value of the {@code height} field. */ @NativeType("uint32_t") public int height() { return VkFramebufferCreateInfo.nheight(address()); } /** Returns the value of the {@code layers} field. */ @NativeType("uint32_t") public int layers() { return VkFramebufferCreateInfo.nlayers(address()); } /** Sets the specified value to the {@code sType} field. */ public VkFramebufferCreateInfo.Buffer sType(@NativeType("VkStructureType") int value) { VkFramebufferCreateInfo.nsType(address(), value); return this; } /** Sets the specified value to the {@code pNext} field. */ public VkFramebufferCreateInfo.Buffer pNext(@NativeType("const void *") long value) { VkFramebufferCreateInfo.npNext(address(), value); return this; } /** Sets the specified value to the {@code flags} field. */ public VkFramebufferCreateInfo.Buffer flags(@NativeType("VkFramebufferCreateFlags") int value) { VkFramebufferCreateInfo.nflags(address(), value); return this; } /** Sets the specified value to the {@code renderPass} field. */ public VkFramebufferCreateInfo.Buffer renderPass(@NativeType("VkRenderPass") long value) { VkFramebufferCreateInfo.nrenderPass(address(), value); return this; } /** Sets the address of the specified {@link LongBuffer} to the {@code pAttachments} field. */ public VkFramebufferCreateInfo.Buffer pAttachments(@NativeType("const VkImageView *") LongBuffer value) { VkFramebufferCreateInfo.npAttachments(address(), value); return this; } /** Sets the specified value to the {@code width} field. */ public VkFramebufferCreateInfo.Buffer width(@NativeType("uint32_t") int value) { VkFramebufferCreateInfo.nwidth(address(), value); return this; } /** Sets the specified value to the {@code height} field. */ public VkFramebufferCreateInfo.Buffer height(@NativeType("uint32_t") int value) { VkFramebufferCreateInfo.nheight(address(), value); return this; } /** Sets the specified value to the {@code layers} field. */ public VkFramebufferCreateInfo.Buffer layers(@NativeType("uint32_t") int value) { VkFramebufferCreateInfo.nlayers(address(), value); return this; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy