By William Lew
A basic understanding of Vulkan is recommended; this tutorial focuses specifically on the VK_KHR_ray_tracing extension for Vulkan. The tutorial will not cover in depth the general topics of Vulkan, but will describe all the procedures involving ray tracing; there are many great online resources for learning Vulkan so rather than rewriting their information, I will just provide the links to their websites.
https://vulkan-tutorial.com/
Unlike the other tutorials on the ray tracing extension, this tutorial implements the ray tracing extension in a single file with minimal abstraction. The other tutorials do an amazing job of encapsulating procedures, but sometimes it is easier to learn from a minimal implementation.
Here are two amazing resources for Vulkan ray tracing:
https://nvpro-samples.github.io/vk_raytracing_tutorial_KHR/
https://github.com/SaschaWillems/Vulkan/blob/master/examples/raytracingbasic/raytracingbasic.cpp
Here is the link to the Github repository for the tutorial:
https://github.com/WilliamLewww/vulkan_ray_tracing_minimal_abstraction
There are two parts of this tutorial that will describe a different method for Vulkan ray tracing. You should view the code on github while reading the tutorial; the majority of the code in this tutorial is heavily truncated for simplicity.
The first approach is to use the ray tracing pipeline in which we will launch rays from the the ray generation shader and depending on the intersection, either a ray hit shader or a ray miss shader will handle the ray. This is a pure ray tracing approach in which the graphics pipeline is completely ignored; instead of using the graphics pipeline to rasterize primitives, the ray tracing pipeline will launch rays for each pixel of an image and resolve the pixel's color from the ray's payload.
The second approach is to use ray querying in which we can launch rays from the shader stages in the graphics pipeline. This is a hybrid approach because the graphics pipeline is still involved. For example, we can have a hybrid renderer by rasterizing primitives and launching rays from the rasterized primitives. In the fragment shader, we can grab the interpolated position of the rasterized primitive and then cast a ray from the position to test for shadows.
Currently (9 September 2020), the VK_KHR_ray_tracing extension is only available with the Vulkan beta drivers. Even if your device is compatible with the extension, your driver may not have the extension available.
Here is the link to download the Vulkan beta drivers:
https://developer.nvidia.com/vulkan-driver
After installing the Vulkan SDK, you must check to see if the VK_KHR_ray_tracing extension is compatible with your GPU. To see if the extension is available with your device, you can use the vulkaninfo program. The vulkaninfo program may not display VK_KHR_ray_tracing if you are using incompatible drivers.
Here is an example of using the vulkaninfo program in linux:
$ vulkaninfo | grep VK_KHR_ray_tracing
ERROR: [Loader Message] Code 0 : /usr/lib32/amdvlk32.so: wrong ELF class: ELFCLASS32
VK_KHR_ray_tracing : extension revision 8
VK_KHR_ray_tracing : extension revision 8
We first need to make sure we include the correct headers. Since we are using a beta extension we need to define VK_ENABLE_BETA_EXTENSIONS. We are also using tinyobjloader-c to load .obj models so we also need to include its header file.
(main.c: 1)
#define VK_ENABLE_BETA_EXTENSIONS
#include <vulkan/vulkan.h>
#include <GLFW/glfw3.h>
#define TINYOBJ_LOADER_C_IMPLEMENTATION
#include "tinyobj_loader_c.h"
int main(void) {
struct VulkanApplication* app = (struct VulkanApplication*)malloc(sizeof(struct VulkanApplication));
struct Scene* scene = (struct Scene*)malloc(sizeof(struct Scene));
struct Camera* camera = &(struct Camera) {
.position = {
0, 0, 0, 1
},
.right = {
1, 0, 0, 1
},
.up = {
0, 1, 0, 1
},
.forward = {
0, 0, 1, 1
},
.frameCount = 0,
};
initializeScene(scene, "res/cube_scene.obj");
initializeVulkanContext(app);
pickPhysicalDevice(app);
createLogicalConnection(app);
createSwapchain(app);
createCommandPool(app);
createVertexBuffer(app, scene);
createIndexBuffer(app, scene);
createMaterialBuffers(app, scene);
createTextures(app);
createAccelerationStructure(app, scene);
bindAccelerationStructure(app);
buildAccelerationStructure(app, scene);
createTopLevelAccelerationStructure(app);
createUniformBuffer(app);
createDescriptorSets(app);
createRayTracePipeline(app);
createShaderBindingTable(app);
createCommandBuffers(app);
createSynchronizationObjects(app);
runMainLoop(app, camera);
cleanUp(app, scene);
free(app);
free(scene);
return 0;
}
struct VulkanApplication* app = (struct VulkanApplication*)malloc(sizeof(struct VulkanApplication));
struct Scene* scene = (struct Scene*)malloc(sizeof(struct Scene));
struct Camera* camera = &(struct Camera) {
.position = {
0, 0, 0, 1
},
.right = {
1, 0, 0, 1
},
.up = {
0, 1, 0, 1
},
.forward = {
0, 0, 1, 1
},
.frameCount = 0,
};
initializeScene(scene, "res/cube_scene.obj");
extensionNames[glfwExtensionCount] = "VK_KHR_get_physical_device_properties2";
deviceEnabledExtensionNames[0] = VK_KHR_SWAPCHAIN_EXTENSION_NAME;
deviceEnabledExtensionNames[1] = "VK_KHR_ray_tracing";
deviceEnabledExtensionNames[2] = "VK_KHR_get_memory_requirements2";
deviceEnabledExtensionNames[3] = "VK_EXT_descriptor_indexing";
deviceEnabledExtensionNames[4] = "VK_KHR_buffer_device_address";
deviceEnabledExtensionNames[5] = "VK_KHR_deferred_host_operations";
deviceEnabledExtensionNames[6] = "VK_KHR_pipeline_library";
deviceEnabledExtensionNames[7] = "VK_KHR_maintenance3";
VkPhysicalDeviceBufferDeviceAddressFeaturesEXT bufferDeviceAddressFeatures = {};
bufferDeviceAddressFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT;
bufferDeviceAddressFeatures.bufferDeviceAddress = VK_TRUE;
VkPhysicalDeviceRayTracingFeaturesKHR rayTracingFeatures = {};
rayTracingFeatures.pNext = &bufferDeviceAddressFeatures;
rayTracingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_FEATURES_KHR;
rayTracingFeatures.rayTracing = VK_TRUE;
rayTracingFeatures.rayQuery = VK_TRUE;
swapchainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
void* positionData;
vkMapMemory(app->logicalDevice, positionStagingBufferMemory, 0, positionBufferSize, 0, &positionData);
memcpy(positionData, scene->attributes.vertices, positionBufferSize);
vkUnmapMemory(app->logicalDevice, positionStagingBufferMemory);
uint32_t* positionIndices = (uint32_t*)malloc(bufferSize);
for (int x = 0; x < scene->attributes.num_faces; x++) {
positionIndices[x] = scene->attributes.faces[x].v_idx;
}
struct Material* materials = (struct Material*)malloc(materialBufferSize);
for (int x = 0; x < scene->numMaterials; x++) {
memcpy(materials[x].ambient, scene->materials[x].ambient, sizeof(float) * 3);
memcpy(materials[x].diffuse, scene->materials[x].diffuse, sizeof(float) * 3);
memcpy(materials[x].specular, scene->materials[x].specular, sizeof(float) * 3);
memcpy(materials[x].emission, scene->materials[x].emission, sizeof(float) * 3);
}
createImage(
app,
800,
600,
app->swapchainImageFormat,
VK_IMAGE_TILING_OPTIMAL,
VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_STORAGE_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
&app->rayTraceImage,
&app->rayTraceImageMemory
);
VkAccelerationStructureCreateGeometryTypeInfoKHR geometryInfos = {};
geometryInfos.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_GEOMETRY_TYPE_INFO_KHR;
geometryInfos.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_KHR;
geometryInfos.maxPrimitiveCount = scene->attributes.num_face_num_verts;
geometryInfos.indexType = VK_INDEX_TYPE_UINT32;
geometryInfos.maxVertexCount = scene->attributes.num_vertices;
geometryInfos.vertexFormat = VK_FORMAT_R32G32B32_SFLOAT;
geometryInfos.allowsTransforms = VK_FALSE;
VkBufferDeviceAddressInfo vertexBufferDeviceAddressInfo = {};
vertexBufferDeviceAddressInfo.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO;
vertexBufferDeviceAddressInfo.buffer = app->vertexPositionBuffer;
VkDeviceAddress vertexBufferAddress = pvkGetBufferDeviceAddressKHR(app->logicalDevice, &vertexBufferDeviceAddressInfo);
VkDeviceOrHostAddressConstKHR vertexDeviceOrHostAddressConst = {};
vertexDeviceOrHostAddressConst.deviceAddress = vertexBufferAddress;
VkBufferDeviceAddressInfo indexBufferDeviceAddressInfo = {};
indexBufferDeviceAddressInfo.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO;
indexBufferDeviceAddressInfo.buffer = app->indexBuffer;
VkDeviceAddress indexBufferAddress = pvkGetBufferDeviceAddressKHR(app->logicalDevice, &indexBufferDeviceAddressInfo);
VkDeviceOrHostAddressConstKHR indexDeviceOrHostAddressConst = {};
indexDeviceOrHostAddressConst.deviceAddress = indexBufferAddress;
VkAccelerationStructureGeometryTrianglesDataKHR trianglesData = {};
trianglesData.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR;
trianglesData.pNext = NULL;
trianglesData.vertexFormat = VK_FORMAT_R32G32B32_SFLOAT;
trianglesData.vertexData = vertexDeviceOrHostAddressConst;
trianglesData.vertexStride = sizeof(float) * 3;
trianglesData.indexType = VK_INDEX_TYPE_UINT32;
trianglesData.indexData = indexDeviceOrHostAddressConst;
trianglesData.transformData = (VkDeviceOrHostAddressConstKHR){};
VkBuffer scratchBuffer;
VkDeviceMemory scratchBufferMemory;
createBuffer(app, scratchSize, VK_BUFFER_USAGE_RAY_TRACING_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &scratchBuffer, &scratchBufferMemory);
VkBufferDeviceAddressInfo scratchBufferDeviceAddressInfo = {};
scratchBufferDeviceAddressInfo.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO;
scratchBufferDeviceAddressInfo.buffer = scratchBuffer;
VkDeviceAddress scratchBufferAddress = pvkGetBufferDeviceAddressKHR(app->logicalDevice, &scratchBufferDeviceAddressInfo);
VkDeviceOrHostAddressKHR scratchDeviceOrHostAddress = {};
scratchDeviceOrHostAddress.deviceAddress = scratchBufferAddress;
const VkAccelerationStructureBuildGeometryInfoKHR* buildGeometryInfo = &(VkAccelerationStructureBuildGeometryInfoKHR){
.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR,
.pNext = NULL,
.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR,
.flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR,
.update = VK_FALSE,
.srcAccelerationStructure = VK_NULL_HANDLE,
.dstAccelerationStructure = app->bottomLevelAccelerationStructure,
.geometryArrayOfPointers = VK_TRUE,
.geometryCount = 1,
.ppGeometries = geometries,
.scratchData = scratchDeviceOrHostAddress
};
const VkAccelerationStructureBuildOffsetInfoKHR* buildOffsetInfoPtr = &(VkAccelerationStructureBuildOffsetInfoKHR){
.primitiveCount = scene->attributes.num_face_num_verts,
.primitiveOffset = 0,
.firstVertex = 0,
.transformOffset = 0
};
const VkAccelerationStructureBuildOffsetInfoKHR** buildOffsetInfos = &buildOffsetInfoPtr;
vkBeginCommandBuffer(commandBuffer, &commandBufferBeginInfo);
pvkCmdBuildAccelerationStructureKHR(commandBuffer, 1, buildGeometryInfo, buildOffsetInfos);
vkEndCommandBuffer(commandBuffer);
VkAccelerationStructureCreateGeometryTypeInfoKHR geometryInfos = {};
geometryInfos.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_GEOMETRY_TYPE_INFO_KHR;
geometryInfos.geometryType = VK_GEOMETRY_TYPE_INSTANCES_KHR;
geometryInfos.maxPrimitiveCount = 1;
geometryInfos.allowsTransforms = VK_TRUE;
VkAccelerationStructureDeviceAddressInfoKHR accelerationStructureDeviceAddressInfo = {};
accelerationStructureDeviceAddressInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR;
accelerationStructureDeviceAddressInfo.accelerationStructure = app->bottomLevelAccelerationStructure;
VkDeviceAddress accelerationStructureDeviceAddress = pvkGetAccelerationStructureDeviceAddressKHR(app->logicalDevice, &accelerationStructureDeviceAddressInfo);
VkAccelerationStructureInstanceKHR geometryInstance = {};
geometryInstance.transform = transformMatrix;
geometryInstance.instanceCustomIndex = 0;
geometryInstance.mask = 0xFF;
geometryInstance.instanceShaderBindingTableRecordOffset = 0;
geometryInstance.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
geometryInstance.accelerationStructureReference = accelerationStructureDeviceAddress;
VkBuffer geometryInstanceStagingBuffer;
VkDeviceMemory geometryInstanceStagingBufferMemory;
createBuffer(app, geometryInstanceBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &geometryInstanceStagingBuffer, &geometryInstanceStagingBufferMemory);
void* geometryInstanceData;
vkMapMemory(app->logicalDevice, geometryInstanceStagingBufferMemory, 0, geometryInstanceBufferSize, 0, &geometryInstanceData);
memcpy(geometryInstanceData, &geometryInstance, geometryInstanceBufferSize);
vkUnmapMemory(app->logicalDevice, geometryInstanceStagingBufferMemory);
VkBuffer geometryInstanceBuffer;
VkDeviceMemory geometryInstanceBufferMemory;
createBuffer(app, geometryInstanceBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_RAY_TRACING_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &geometryInstanceBuffer, &geometryInstanceBufferMemory);
copyBuffer(app, geometryInstanceStagingBuffer, geometryInstanceBuffer, geometryInstanceBufferSize);
vkDestroyBuffer(app->logicalDevice, geometryInstanceStagingBuffer, NULL);
vkFreeMemory(app->logicalDevice, geometryInstanceStagingBufferMemory, NULL);
VkBufferDeviceAddressInfo geometryInstanceBufferDeviceAddressInfo = {};
geometryInstanceBufferDeviceAddressInfo.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO;
geometryInstanceBufferDeviceAddressInfo.buffer = geometryInstanceBuffer;
VkDeviceAddress geometryInstanceBufferAddress = pvkGetBufferDeviceAddressKHR(app->logicalDevice, &geometryInstanceBufferDeviceAddressInfo);
VkDeviceOrHostAddressConstKHR geometryInstanceDeviceOrHostAddressConst = {};
geometryInstanceDeviceOrHostAddressConst.deviceAddress = geometryInstanceBufferAddress;
VkAccelerationStructureGeometryInstancesDataKHR instancesData = {};
instancesData.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR;
instancesData.pNext = NULL;
instancesData.arrayOfPointers = VK_FALSE;
instancesData.data = geometryInstanceDeviceOrHostAddressConst;
VkBuffer scratchBuffer;
VkDeviceMemory scratchBufferMemory;
createBuffer(app, scratchSize, VK_BUFFER_USAGE_RAY_TRACING_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &scratchBuffer, &scratchBufferMemory);
VkBufferDeviceAddressInfo scratchBufferDeviceAddressInfo = {};
scratchBufferDeviceAddressInfo.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO;
scratchBufferDeviceAddressInfo.buffer = scratchBuffer;
VkDeviceAddress scratchBufferAddress = pvkGetBufferDeviceAddressKHR(app->logicalDevice, &scratchBufferDeviceAddressInfo);
VkDeviceOrHostAddressKHR scratchDeviceOrHostAddress = {};
scratchDeviceOrHostAddress.deviceAddress = scratchBufferAddress;
const VkAccelerationStructureBuildGeometryInfoKHR* buildGeometryInfo = &(VkAccelerationStructureBuildGeometryInfoKHR){
.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR,
.pNext = NULL,
.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR,
.flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR,
.update = VK_FALSE,
.srcAccelerationStructure = VK_NULL_HANDLE,
.dstAccelerationStructure = app->topLevelAccelerationStructure,
.geometryArrayOfPointers = VK_TRUE,
.geometryCount = 1,
.ppGeometries = geometries,
.scratchData = scratchDeviceOrHostAddress
};
const VkAccelerationStructureBuildOffsetInfoKHR* buildOffsetInfoPtr = &(VkAccelerationStructureBuildOffsetInfoKHR){
.primitiveCount = 1,
.primitiveOffset = 0,
.firstVertex = 0,
.transformOffset = 0
};
const VkAccelerationStructureBuildOffsetInfoKHR** buildOffsetInfos = &buildOffsetInfoPtr;
vkBeginCommandBuffer(commandBuffer, &commandBufferBeginInfo);
pvkCmdBuildAccelerationStructureKHR(commandBuffer, 1, buildGeometryInfo, buildOffsetInfos);
vkEndCommandBuffer(commandBuffer);
VkDescriptorPoolSize descriptorPoolSizes[4];
descriptorPoolSizes[0].type = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR;
descriptorPoolSizes[0].descriptorCount = 1;
descriptorPoolSizes[1].type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
descriptorPoolSizes[1].descriptorCount = 1;
descriptorPoolSizes[2].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
descriptorPoolSizes[2].descriptorCount = 1;
descriptorPoolSizes[3].type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
descriptorPoolSizes[3].descriptorCount = 4;
VkDescriptorPoolCreateInfo descriptorPoolCreateInfo = {};
descriptorPoolCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
descriptorPoolCreateInfo.poolSizeCount = 4;
descriptorPoolCreateInfo.pPoolSizes = descriptorPoolSizes;
descriptorPoolCreateInfo.maxSets = 2;
if (vkCreateDescriptorPool(app->logicalDevice, &descriptorPoolCreateInfo, NULL, &app->descriptorPool) == VK_SUCCESS) {
printf("\033[22;32m%s\033[0m\n", "created descriptor pool");
}
VkDescriptorSetLayoutBinding descriptorSetLayoutBindings[5];
descriptorSetLayoutBindings[0].binding = 0;
descriptorSetLayoutBindings[0].descriptorCount = 1;
descriptorSetLayoutBindings[0].descriptorType = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR;
descriptorSetLayoutBindings[0].pImmutableSamplers = NULL;
descriptorSetLayoutBindings[0].stageFlags = VK_SHADER_STAGE_RAYGEN_BIT_KHR | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;
descriptorSetLayoutBindings[1].binding = 1;
descriptorSetLayoutBindings[1].descriptorCount = 1;
descriptorSetLayoutBindings[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
descriptorSetLayoutBindings[1].pImmutableSamplers = NULL;
descriptorSetLayoutBindings[1].stageFlags = VK_SHADER_STAGE_RAYGEN_BIT_KHR | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;
...
VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = {};
descriptorSetLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
descriptorSetLayoutCreateInfo.bindingCount = 5;
descriptorSetLayoutCreateInfo.pBindings = descriptorSetLayoutBindings;
if (vkCreateDescriptorSetLayout(app->logicalDevice, &descriptorSetLayoutCreateInfo, NULL, &app->rayTraceDescriptorSetLayouts[0]) == VK_SUCCESS) {
printf("\033[22;32m%s\033[0m\n", "created descriptor set layout");
}
VkWriteDescriptorSet writeDescriptorSets[5];
VkWriteDescriptorSetAccelerationStructureKHR descriptorSetAccelerationStructure = {};
descriptorSetAccelerationStructure.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR;
descriptorSetAccelerationStructure.pNext = NULL;
descriptorSetAccelerationStructure.accelerationStructureCount = 1;
descriptorSetAccelerationStructure.pAccelerationStructures = &app->topLevelAccelerationStructure;
writeDescriptorSets[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writeDescriptorSets[0].pNext = &descriptorSetAccelerationStructure;
writeDescriptorSets[0].dstSet = app->rayTraceDescriptorSet;
writeDescriptorSets[0].dstBinding = 0;
writeDescriptorSets[0].dstArrayElement = 0;
writeDescriptorSets[0].descriptorCount = 1;
writeDescriptorSets[0].descriptorType = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR;
writeDescriptorSets[0].pImageInfo = NULL;
writeDescriptorSets[0].pBufferInfo = NULL;
writeDescriptorSets[0].pTexelBufferView = NULL;
...
VkDescriptorBufferInfo vertexBufferInfo = {};
vertexBufferInfo.buffer = app->vertexPositionBuffer;
vertexBufferInfo.offset = 0;
vertexBufferInfo.range = VK_WHOLE_SIZE;
writeDescriptorSets[4].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writeDescriptorSets[4].pNext = NULL;
writeDescriptorSets[4].dstSet = app->rayTraceDescriptorSet;
writeDescriptorSets[4].dstBinding = 4;
writeDescriptorSets[4].dstArrayElement = 0;
writeDescriptorSets[4].descriptorCount = 1;
writeDescriptorSets[4].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
writeDescriptorSets[4].pImageInfo = NULL;
writeDescriptorSets[4].pBufferInfo = &vertexBufferInfo;
writeDescriptorSets[4].pTexelBufferView = NULL;
vkUpdateDescriptorSets(app->logicalDevice, 5, writeDescriptorSets, 0, NULL);
VkPipelineShaderStageCreateInfo rgenShaderStageInfo = {};
rgenShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
rgenShaderStageInfo.stage = VK_SHADER_STAGE_RAYGEN_BIT_KHR;
rgenShaderStageInfo.module = rgenShaderModule;
rgenShaderStageInfo.pName = "main";
VkPipelineShaderStageCreateInfo rmissShaderStageInfo = {};
rmissShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
rmissShaderStageInfo.stage = VK_SHADER_STAGE_MISS_BIT_KHR;
rmissShaderStageInfo.module = rmissShaderModule;
rmissShaderStageInfo.pName = "main";
VkPipelineShaderStageCreateInfo rmissShadowShaderStageInfo = {};
rmissShadowShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
rmissShadowShaderStageInfo.stage = VK_SHADER_STAGE_MISS_BIT_KHR;
rmissShadowShaderStageInfo.module = rmissShadowShaderModule;
rmissShadowShaderStageInfo.pName = "main";
VkPipelineShaderStageCreateInfo rchitShaderStageInfo = {};
rchitShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
rchitShaderStageInfo.stage = VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;
rchitShaderStageInfo.module = rchitShaderModule;
rchitShaderStageInfo.pName = "main";
VkPipelineShaderStageCreateInfo shaderStages[4] = {rgenShaderStageInfo, rmissShaderStageInfo, rmissShadowShaderStageInfo, rchitShaderStageInfo};
VkRayTracingShaderGroupCreateInfoKHR shaderGroupCreateInfos[4];
shaderGroupCreateInfos[0].sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR;
shaderGroupCreateInfos[0].pNext = NULL;
shaderGroupCreateInfos[0].type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR;
shaderGroupCreateInfos[0].generalShader = 0;
shaderGroupCreateInfos[0].closestHitShader = VK_SHADER_UNUSED_KHR;
shaderGroupCreateInfos[0].anyHitShader = VK_SHADER_UNUSED_KHR;
shaderGroupCreateInfos[0].intersectionShader = VK_SHADER_UNUSED_KHR;
shaderGroupCreateInfos[0].pShaderGroupCaptureReplayHandle = NULL;
...
shaderGroupCreateInfos[3].sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR;
shaderGroupCreateInfos[3].pNext = NULL;
shaderGroupCreateInfos[3].type = VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR;
shaderGroupCreateInfos[3].generalShader = VK_SHADER_UNUSED_KHR;
shaderGroupCreateInfos[3].closestHitShader = 3;
shaderGroupCreateInfos[3].anyHitShader = VK_SHADER_UNUSED_KHR;
shaderGroupCreateInfos[3].intersectionShader = VK_SHADER_UNUSED_KHR;
shaderGroupCreateInfos[3].pShaderGroupCaptureReplayHandle = NULL;
VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = {};
pipelineLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
pipelineLayoutCreateInfo.setLayoutCount = 2;
pipelineLayoutCreateInfo.pSetLayouts = app->rayTraceDescriptorSetLayouts;
pipelineLayoutCreateInfo.pushConstantRangeCount = 0;
if (vkCreatePipelineLayout(app->logicalDevice, &pipelineLayoutCreateInfo, NULL, &app->rayTracePipelineLayout) == VK_SUCCESS) {
printf("created ray trace pipline layout\n");
}
VkPipelineLibraryCreateInfoKHR pipelineLibraryCreateInfo = {};
pipelineLibraryCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR;
pipelineLibraryCreateInfo.pNext = NULL;
pipelineLibraryCreateInfo.libraryCount = 0;
pipelineLibraryCreateInfo.pLibraries = NULL;
VkRayTracingPipelineCreateInfoKHR rayPipelineCreateInfo = {};
rayPipelineCreateInfo.sType = VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_KHR;
rayPipelineCreateInfo.pNext = NULL;
rayPipelineCreateInfo.flags = 0;
rayPipelineCreateInfo.stageCount = 4;
rayPipelineCreateInfo.pStages = shaderStages;
rayPipelineCreateInfo.groupCount = 4;
rayPipelineCreateInfo.pGroups = shaderGroupCreateInfos;
rayPipelineCreateInfo.maxRecursionDepth = 16;
rayPipelineCreateInfo.libraries = pipelineLibraryCreateInfo;
rayPipelineCreateInfo.pLibraryInterface = NULL;
rayPipelineCreateInfo.layout = app->rayTracePipelineLayout;
rayPipelineCreateInfo.basePipelineHandle = VK_NULL_HANDLE;
rayPipelineCreateInfo.basePipelineIndex = -1;
if (pvkCreateRayTracingPipelinesKHR(app->logicalDevice, VK_NULL_HANDLE, 1, &rayPipelineCreateInfo, NULL, &app->rayTracePipeline) == VK_SUCCESS) {
printf("created ray trace pipeline\n");
}
VkDeviceSize shaderBindingTableSize = app->rayTracingProperties.shaderGroupHandleSize * 4;
app->shaderBindingTableBufferMemory;
createBuffer(app, shaderBindingTableSize, VK_BUFFER_USAGE_RAY_TRACING_BIT_KHR, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &app->shaderBindingTableBuffer, &app->shaderBindingTableBufferMemory);
void* shaderHandleStorage = (void*)malloc(sizeof(uint8_t) * shaderBindingTableSize);
if (pvkGetRayTracingShaderGroupHandlesKHR(app->logicalDevice, app->rayTracePipeline, 0, 4, shaderBindingTableSize, shaderHandleStorage) == VK_SUCCESS) {
printf("got ray tracing shader group handles\n");
}
void* data;
vkMapMemory(app->logicalDevice, app->shaderBindingTableBufferMemory, 0, shaderBindingTableSize, 0, &data);
for (int x = 0; x < 4; x++) {
memcpy(data, (uint8_t*)shaderHandleStorage + x * app->rayTracingProperties.shaderGroupHandleSize, app->rayTracingProperties.shaderGroupHandleSize);
data += app->rayTracingProperties.shaderGroupBaseAlignment;
}
vkUnmapMemory(app->logicalDevice, app->shaderBindingTableBufferMemory);
free(shaderHandleStorage);
VkDeviceSize progSize = app->rayTracingProperties.shaderGroupBaseAlignment;
VkDeviceSize rayGenOffset = 0u * progSize;
VkDeviceSize missOffset = 1u * progSize;
VkDeviceSize hitGroupOffset = 3u * progSize;
VkDeviceSize sbtSize = progSize * (VkDeviceSize)4;
const VkStridedBufferRegionKHR rgenShaderBindingTable = {
.buffer = app->shaderBindingTableBuffer,
.offset = rayGenOffset,
.stride = progSize,
.size = sbtSize
};
const VkStridedBufferRegionKHR rmissShaderBindingTable = {
.buffer = app->shaderBindingTableBuffer,
.offset = missOffset,
.stride = progSize,
.size = sbtSize
};
const VkStridedBufferRegionKHR rchitShaderBindingTable = {
.buffer = app->shaderBindingTableBuffer,
.offset = hitGroupOffset,
.stride = progSize,
.size = sbtSize
};
if (vkBeginCommandBuffer(app->commandBuffers[x], &commandBufferBeginCreateInfo) == VK_SUCCESS) {
printf("\033[22;32m%s%d\033[0m\n", "began recording command buffer for image #", x);
}
vkCmdBindPipeline(app->commandBuffers[x], VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, app->rayTracePipeline);
vkCmdBindDescriptorSets(app->commandBuffers[x], VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, app->rayTracePipelineLayout, 0, 1, &app->rayTraceDescriptorSet, 0, 0);
vkCmdBindDescriptorSets(app->commandBuffers[x], VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, app->rayTracePipelineLayout, 1, 1, &app->materialDescriptorSet, 0, 0);
pvkCmdTraceRaysKHR(app->commandBuffers[x], &rgenShaderBindingTable, &rmissShaderBindingTable, &rchitShaderBindingTable, &callableShaderBindingTable, 800, 600, 1);
{
VkImageMemoryBarrier imageMemoryBarrier = {};
imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
imageMemoryBarrier.pNext = NULL;
imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
imageMemoryBarrier.image = app->rayTraceImage;
imageMemoryBarrier.subresourceRange = subresourceRange;
imageMemoryBarrier.srcAccessMask = 0;
imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
vkCmdPipelineBarrier(app->commandBuffers[x], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, NULL, 0, NULL, 1, &imageMemoryBarrier);
}
{
VkImageMemoryBarrier imageMemoryBarrier = {};
imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
imageMemoryBarrier.pNext = NULL;
imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
imageMemoryBarrier.image = app->swapchainImages[x];
imageMemoryBarrier.subresourceRange = subresourceRange;
imageMemoryBarrier.srcAccessMask = 0;
imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
vkCmdPipelineBarrier(app->commandBuffers[x], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, NULL, 0, NULL, 1, &imageMemoryBarrier);
}
{
VkImageSubresourceLayers subresourceLayers = {};
subresourceLayers.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
subresourceLayers.mipLevel = 0;
subresourceLayers.baseArrayLayer = 0;
subresourceLayers.layerCount = 1;
VkOffset3D offset = {};
offset.x = 0;
offset.y = 0;
offset.z = 0;
VkExtent3D extent = {};
extent.width = 800;
extent.height = 600;
extent.depth = 1;
VkImageCopy imageCopy = {};
imageCopy.srcSubresource = subresourceLayers;
imageCopy.srcOffset = offset;
imageCopy.dstSubresource = subresourceLayers;
imageCopy.dstOffset = offset;
imageCopy.extent = extent;
vkCmdCopyImage(app->commandBuffers[x], app->rayTraceImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, app->swapchainImages[x], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &imageCopy);
}


Dockerizing an Angular App
Docker is a containerization tool used to streamline application development and deployment workflows across various environments.
This tutorial shows how to Dockerize an Angular app, built with the Angular CLI, using Docker along with Docker Compose and Docker Machine for both development and production. We’ll specifically focus on-
- Setting up an image for development with code hot-reloading that includes an instance of Chrome for Karma and Protractor testing
- Configuring a lean, production-ready image using multistage builds
Updates:
- May 2019:
- Updated to the latest versions of Docker, Node, Angular, and Nginx.
- Added explanations for various Docker commands and flags.
- Added a number of notes based on reader comments and feedback.
- Fixed the running of Protractor e2e tests.
We will be using:
- Docker v18.09.2
- Angular CLI v7.3.9
- Node v12.2.0
Contents
Project Setup
Install the Angular CLI globally:
$ npm install -g<EMAIL_ADDRESS>Generate a new app:
$ ng new example
$ cd example
Docker
Add a Dockerfile to the project root:
# base image
FROM node:12.2.0
# install chrome for protractor tests
RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -
RUN sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
RUN apt-get update && apt-get install -yq google-chrome-stable
# set working directory
WORKDIR /app
# add `/app/node_modules/.bin` to $PATH
ENV PATH /app/node_modules/.bin:$PATH
# install and cache app dependencies
COPY package.json /app/package.json
RUN npm install
RUN npm install -g<EMAIL_ADDRESS># add app
COPY . /app
# start app
CMD ng serve --host <IP_ADDRESS>
Add a .dockerignore as well:
node_modules
.git
.gitignore
This will speed up the Docker build process as our local dependencies and git repo will not be sent to the Docker daemon.
Build and tag the Docker image:
$ docker build -t example:dev .
If
RUN npm install -g<EMAIL_ADDRESS>results in an infinite loop, you may need to add an--unsafe
flag:RUN npm install -g<EMAIL_ADDRESS>--unsafe
Review this issue for more info.
Then, spin up the container once the build is done:
$ docker run -v ${PWD}:/app -v /app/node_modules -p 4201:4200 --rm example:dev
What’s happening here?
- The docker run command creates a new container instance, from the image we just created, and runs it.
-
-v ${PWD}:/app
mounts the code into the container at “/app”.{PWD}
may not work on Windows. See this Stack Overflow question for more info. - Since we want to use the container version of the “node_modules” folder, we configured another volume:
-v /app/node_modules
. You should now be able to remove the local “node_modules” flavor. -
-p 4201:4200
exposes port 4200 to other Docker containers on the same network (for inter-container communication) and port 4201 to the host.For more, review this Stack Overflow question.
- Finally,
--rm
removes the container and volumes after the container exits.
Open your browser to http://localhost:4201 and you should see the app. Try making a change to the AppComponent
’s template (src/app/app.component.html) within your code editor. You should see the app hot-reload. Kill the server once done.
What happens when you add
-it
?$ docker run -it -v ${PWD}:/app -v /app/node_modules -p 4201:4200 --rm example:dev
Check your understanding and look this up on your own.
Use the -d
flag to run the container in the background:
$ docker run -d -v ${PWD}:/app -v /app/node_modules -p 4201:4200 --name foo --rm example:dev
Once up, update the Karma and Protractor config files to run Chrome in headless mode.
src/karma.conf.js:
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '@angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage-istanbul-reporter'),
require('@angular-devkit/build-angular/plugins/karma')
],
client: {
clearContext: false
},
coverageIstanbulReporter: {
dir: require('path').join(__dirname, '../coverage/example'),
reports: ['html', 'lcovonly', 'text-summary'],
fixWebpackSourcePaths: true
},
reporters: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
// updated
browsers: ['ChromeHeadless'],
// new
customLaunchers: {
'ChromeHeadless': {
base: 'Chrome',
flags: [
'--no-sandbox',
'--headless',
'--disable-gpu',
'--remote-debugging-port=9222'
]
}
},
singleRun: false,
restartOnFileChange: true
});
};
e2e/protractor.conf.js:
const { SpecReporter } = require('jasmine-spec-reporter');
exports.config = {
allScriptsTimeout: 11000,
specs: [
'./src/**/*.e2e-spec.ts'
],
capabilities: {
'browserName': 'chrome',
// new
'chromeOptions': {
'args': [
'--no-sandbox',
'--headless',
'--window-size=1024,768'
]
}
},
directConnect: true,
baseUrl: 'http://localhost:4200/',
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000,
print: function() {}
},
onPrepare() {
require('ts-node').register({
project: require('path').join(__dirname, './tsconfig.e2e.json')
});
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
}
};
Run the unit and e2e tests:
$ docker exec -it foo ng test --watch=false
$ docker exec -it foo ng e2e --port 4202
Stop the container once done:
$ docker stop foo
Want to use Docker Compose? Add a docker-compose.yml file to the project root:
version: '3.7'
services:
example:
container_name: example
build:
context: .
dockerfile: Dockerfile
volumes:
- '.:/app'
- '/app/node_modules'
ports:
- '4201:4200'
Take note of the volumes. Without the anonymous volume ('/app/node_modules'
), the node_modules directory would be overwritten by the mounting of the host directory at runtime. In other words, this would happen:
- Build - The
node_modules
directory is created in the image. - Run - The current directory is mounted into the container, overwriting the
node_modules
that were installed during the build.
Build the image and fire up the container:
$ docker-compose up -d --build
Ensure the app is running in the browser and test hot-reloading again. Try both the unit and e2e tests as well:
$ docker-compose exec example ng test --watch=false
$ docker-compose exec example ng e2e --port 4202
Stop the container before moving on:
$ docker-compose stop
Windows Users: Having problems getting the volumes to work properly? Review the following resources:
You also may need to add
COMPOSE_CONVERT_WINDOWS_PATHS=1
to the environment portion of your Docker Compose file. Review the Declare default environment variables in file guide for more info.
Docker Machine
To get hot-reloading to work with Docker Machine and VirtualBox you’ll need to enable a polling mechanism via chokidar (which wraps fs.watch
, fs.watchFile
, and fsevents
).
Create a new Machine:
$ docker-machine create -d virtualbox clever
$ docker-machine env clever
$ eval $(docker-machine env clever)
Grab the IP address:
$ docker-machine ip clever
Then, build the images:
$ docker build -t example:dev .
And run the container:
$ docker run -it -v ${PWD}:/app -v /app/node_modules -p 4201:4200 --rm example:dev
Test the app again in the browser at http://DOCKER_MACHINE_IP:4201 (make sure to replace DOCKER_MACHINE_IP
with the actual IP address of the Docker Machine). Also, confirm that auto reload is not working. You can try with Docker Compose as well, but the result will be the same.
To get hot-reload working, we need to add an environment variable: CHOKIDAR_USEPOLLING=true
.
$ docker run -it -v ${PWD}:/app -v /app/node_modules -p 4201:4200 -e CHOKIDAR_USEPOLLING=true --rm example:dev
Test it out again. Then, kill the server and add the environment variable to the docker-compose.yml file:
version: '3.7'
services:
example:
container_name: example
build:
context: .
dockerfile: Dockerfile
volumes:
- '.:/app'
- '/app/node_modules'
ports:
- '4201:4200'
environment:
- CHOKIDAR_USEPOLLING=true
Spin up the container. Run the unit tests and e2e tests.
Production
Let’s create a separate Dockerfile for use in production called Dockerfile-prod:
#############
### build ###
#############
# base image
FROM node:12.2.0 as build
# install chrome for protractor tests
RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -
RUN sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
RUN apt-get update && apt-get install -yq google-chrome-stable
# set working directory
WORKDIR /app
# add `/app/node_modules/.bin` to $PATH
ENV PATH /app/node_modules/.bin:$PATH
# install and cache app dependencies
COPY package.json /app/package.json
RUN npm install
RUN npm install -g<EMAIL_ADDRESS># add app
COPY . /app
# run tests
RUN ng test --watch=false
RUN ng e2e --port 4202
# generate build
RUN ng build --output-path=dist
############
### prod ###
############
# base image
FROM nginx:1.16.0-alpine
# copy artifact build from the 'build environment'
COPY --from=build /app/dist /usr/share/nginx/html
# expose port 80
EXPOSE 80
# run nginx
CMD ["nginx", "-g", "daemon off;"]
Two important things to note:
-
First, we take advantage of the multistage build pattern to create a temporary image used for building the artifact – the production-ready Angular static files – that is then copied over to the production image. The temporary build image is discarded along with the original files, folders, and dependencies associated with the image. This produces a lean, production-ready image.
In other words, the only thing kept from the first image is the compiled distribution code.
Check out the Builder pattern vs. Multi-stage builds in Docker blog post for more info on multistage builds.
-
Next, the unit and e2e tests are run in the build process, so the build will fail if the tests do not succeed.
Using the production Dockerfile, build and tag the Docker image:
$ docker build -f Dockerfile-prod -t example:prod .
Spin up the container:
$ docker run -it -p 80:80 --rm example:prod
Assuming you are still using the same Docker Machine, navigate to http://DOCKER_MACHINE_IP/ in your browser.
Test with a new Docker Compose file as well called docker-compose-prod.yml:
version: '3.7'
services:
example-prod:
container_name: example-prod
build:
context: .
dockerfile: Dockerfile-prod
ports:
- '80:80'
Fire up the container:
$ docker-compose -f docker-compose-prod.yml up -d --build
Test it out once more in your browser. Then, break a test in src/app/app.component.spec.ts and re-build. It should fail:
ERROR: Service 'example-prod' failed to build:
The command '/bin/sh -c ng test --watch=false' returned a non-zero code: 1
If you’re done, go ahead and destroy the Machine:
$ eval $(docker-machine env -u)
$ docker-machine rm clever
Cheers!


Easy if you know
On click of:
- Copies HTML code
- Downloads CSS file
for the respective spinner.
Download spinner CSS
Link this CSS to your HTML file.
HTML USAGE
Syntax
Example
Suggestions?
Thank you for visiting my page. Please let me know if you have any suggestions regarding mk spinners here.
Developer's Bio
Masoom Ulhaq S, UX Engineer & Frontend Developer. checkout my work


About the data
To compile this database on executives’ personal use of company planes, the Financial Times manually inspected nearly a thousand company filings to the US Securities and Exchange Commission. We looked at annual proxy filings (also known as DEF 14A filings) of S&P 500 companies across two financial years (2013 and 2014).
Where a DEF 14A filing was not available (for example because of mergers and acquisitions activity), we looked for other proxy statements filed by the company that contained the information, such as PRE 14A statements.
To ease the process of finding all the filings, we used the SEC’s file transfer protocol server for its Edgar electronic filing system to download an index of all the filings in the time period we were looking for. We then used R, the statistical programming language, to filter that index and compile a list of URLs for the filings we were interested in. For our analysis, we included only the 465 companies that were in the S&P 500 from January 1, 2014 to December 31, 2015 (the period during which the proxy statements we examined were filed). As SEC regulations do not require companies to disclose the value of personal use of corporate aircraft by a named executive if it is less than $25,000, we discarded any voluntary disclosure of aircraft benefits that were below that threshold.
That left us with 322 executives across 184 companies.
We entered the data into a Google spreadsheet and wrote a script using R to conduct our analysis. This identified the top spenders in 2013 and 2014, as well as the fact that the distribution of jet spending was skewed, with a handful of companies accounting for a large proportion of total spending. The script also compared spending in 2013 with 2014, looked at the data by industry, gender of the executive and geographic location of companies’ headquarters.
We delved deeper into the spending history of the top 10 companies by looking at their filings going back a decade to 2006. Read the companies’ responses to our findings on this project's Github page.


I have been living in Portland for just about a year now. One of the big draws
of Portland was how close it was to Mount Hood and we envisioned heading to
this place every weekend. In reality we didn’t even go once the entire year. I
wanted to start the year off differently though and celebrate it with a snow
boarding trip. Despite the cost and the fear of it being extremely crowded
given the fresh snow and weekend it turned out to be fantastic.
All the pictures taken for this post were made with my iphone. While I would
have loved to have used my DSLR there, some times the best camera is the one
you have with you. I use an app called AutoStitch which creates a panorama
from a bunch of pictures. Most of the panoramas that I take use anywhere from
three to nine pictures.
My girlfriend and I learned how to board together a few years ago. We go very
sporadicly, so every time it feels like we have to learn the basics over
again. By the time we are finish we feel like we know what we are doing but
then the process repeats itself.
We don’t own a 4wd vehicle so we used a bus service to get to Mount Hood. This
involves parking our car some place, then sleeping on the bus for 2 hours
while the driver deals with parking and the snow. Once there we rented the
boards and boots.
On my very first run my worst fear happened: I had no idea how to interpret
the route signs and some how stumbled upon a run that was way above my level.
I quickly lost momentum and found myself surrounded by trees in fresh, deep
snow. When I tried to move myself I would sink into the snow. The weather was
absolutely perfect though and I didn’t really care. At one point I found
myself at the top of a very steep hill that looked very dangerous. I butt slid
around and eventually realized that I was surrounded by similar tracks.
Apparently I wasn’t the only person to recently be in the same situation.
Eventually I pushed and hiked my way through the snow until I got to a clear
hill and was on my way again.
After spending some time around the newbie coarse I eventually became more
comfortable riding the snow board and decided to make my way up the mountain.
After taking the above picture I was entranced by the beauty of the mountain,
only to realize shortly afterwards that I was no longer holding my glove. I
glanced over my shoulder just as it hit the snow. I spent the rest of the trip
trying to memorize a route to my glove and planning how the heck I would get
down there without my glove. I opted to use my inner fleece as a glove (which
worked horribly) and had to make frequent stops to warm my hand. Shortly
before reaching it though another boarder had picked it up and deposited it at
the entrance. Thanks man!
Despite worrying about my glove I couldn’t help but snap the above panorama at
Cascade Express.
Throughout the day I couldn’t help but appreciate just how lucky I was to be
where I was - perfect weather and snow, tearing down a beautiful mountain. It
was an amazing way to celebrate the end of an awesome year and the beginning
of a new one.


Selector Component
Introduction
The selector is a DropDown component with a few simple goals
- Data bound - Easy to bind to an array or observable source
- Styleable - Replaceable and customizeable CSS classes for everything
- Filterable - Let the user search available items
- Lazy loading - Show X items and load more items if requested
- Reactive Forms - Works with reactive forms
- Mobile - should be useable on mobile devices
- Multi select - use should be able to select multiple items
Data Bound


Produced using SpotBugs 3.1.7.
Project:
Metrics145 lines of code analysed, in 2 classes, in 1 packages.
(* Defects per thousand lines of non-commenting source statements)
|
Summary
|
Click on each warning link to see a full description of the issue, and details of how to resolve it.


Thank you
You have submitted your request.
Your request will be assessed by NHSBSA. If successful it will then be assessed by Capita.
If the request is unsuccessful you will be contacted with an explanation on how to improve it. This will require you to resubmit the request.
How to contact us about your request
Attend the workshop in GR3 on Wednesday at 11.00
Email us at<EMAIL_ADDRESS>Call us on: 0191 203 5268
Make another request


Container for drawable objects. This class allows you to group sf::Drawable elements such as sf::Sprite. The container keeps pointers to the objects, so your drawable objects should be kept alive while using the render layer.
More...
#include <RenderLayer.hpp>
|
|
| RenderLayer (bool visible=true) |
| | Constructs an empty layer.
|
| |
|
virtual void | draw (sf::RenderTarget &target, sf::RenderStates states) const |
| | Draws all contained objects if the layer is visible.
|
| |
|
void | addDrawable (sf::Drawable &item) |
| | Adds a drawable.
|
| |
| bool | removeDrawable (sf::Drawable &item) |
| | Removes a drawable if it exists. More...
|
| |
|
void | setVisible (bool visible) |
| | Sets the visibility.
|
| |
|
bool | isVisible () const |
| |
|
int | getZ () const |
| |
|
void | setZ (int z) |
| |
|
unsigned int | count () const |
| |
|
bool | isEmpty () const |
| |
| bool | operator< (zt::RenderLayer &other) const |
| |
|
|
bool | visible |
| | If it's false the contained objects won't be drawn.
|
| |
|
std::vector< sf::Drawable * > | drawableItems |
| | Vector que contiene un puntero a los dibujables de esta capa.
|
| |
Container for drawable objects. This class allows you to group sf::Drawable elements such as sf::Sprite. The container keeps pointers to the objects, so your drawable objects should be kept alive while using the render layer.
◆ operator<()
Compares the depth of the layer.
- Parameters
-
- Returns
◆ removeDrawable()
| bool zt::RenderLayer::removeDrawable |
( |
sf::Drawable & |
item | ) |
|
Removes a drawable if it exists.
- Parameters
-
| item | Drawable you cant to remove. |
- Returns
- True if it was removed.
The documentation for this class was generated from the following file:


intervention children school schools study activity physical obesity using childhood healthy outcomes {border-style analysis BMI Health primary px;} #ffffff;} programme sample baseline prevention size trial WAVES cluster follow-up Research level evaluation health outcome undertaken Public University body data difference measures pupils time Med Trial effectiveness measured methods review used Year advised cost delivered family information parents percentage staff term weight (Professor School aged cost-effectiveness design development effects estimate measure months participating power px; range research year young z-score {font-family South West assessment clinical controlled correlation detect eligible font-size implementation including life longer obese opportunities process relevant Asian Birmingham Data Pallan Quality Schools Villa aim allow arm assess based differences double; ethnic food interventions lifestyle population provided quality targeting trials use years (with Adab Child Clin Eating Life Medical Parry Physical Study adjust assessed border-color border-width change clinically completed completion. complex component components control day dietary energy increase messages minutes model monitor number period preventing pupil randomized related session sex, solid; status usual vigorous {font-style {font-weight (including -month BMC Black Body Cade Childhood Component Council Department Development Diet Ekelund Midlands National Nutr Prev Website activities analyses bold calculations child class collected compared contributed courier; day, delivery designed eating education effect em; environment explore factors focus following framework funded given heart home include included index interactive leisure measurement mix moderate multi-ethnic outcomes. overweight post practice previous proportion pt;} randomised receive recruitment report school. secondary set skills spent values years) years). z-score,


It will make your life super easy!
You can either manually control your appliance or set the app to control it automatically. It will learn from your control history.


I wanted to create a way to sort all the top songs around the world that people are listening to. I used machine learning to find a way to cluster all these tracks and present them to you in the form of playlists that you can choose to download and listen to on your own.
Copyright © Pranav Maddali, 2021


BudgetCtrl
Home
(current)
Add Entry
From
To
Total
€ 123.45
Add/Edit Entry
×
Date
Category
Description
Value


My bio starts a bit early - at the age of 13, I was accepted into the Distance Learning Center's STEMPREP Project. Before entering high school, I spent a summer in Philadelphia taking college-level Biology, Chemistry, Statistics, and English (with a focus on research writing).
My four high school summers were thus spent working on biomedical internships. Two summers were spent at Drexel University assisting with HIV research, one at the NIMH assisting with cancer and chromaffin cell research, and one at a private lab in Seattle assisting with yeast research.
This led to a scholarship-funded education at Southern Methodist University, where I quickly changed paths and obtained two B.A.s in Geology and Creative Computing. These different fields led me to receive the Engaged Learning research grant for a project on earthquake data visualization.
While doing all of this, I taught myself how to play the pipe organ, and became the first self-taught student to perform at the university's Meadows School of the Arts.
Post-graduation, I began work with the USGS at the Cascades Volcano Observatory. Here, I build reliable web applications to handle volcanic data, and assist with geological work in the field.
In my free time, I've been working on sewing, weightlifting, and building two digital pipe organs.


Binotto: Rivals used cheating accusations "to put us under pressure"
by Nicolás Quarles van UffordFerrari team principal Mattia Binotto thinks the accusations of his team cheating around the United States Grand Prix was a mere ploy to increase the pressure on the Italian side.
Max Verstappen was the only one to actually call out Ferrari for cheating, with the Dutchman saying the SF90's poor performance in Austin was "what you get when you stop cheating".
Aston Martin Red Bull Racing had reportedly asked the FIA in Austin to make it clear what is and isn't allowed when it comes to fuel flow into the engine. Although they didn't ask the FIA to investigate Ferrari, the Italians coincidentally struggled to keep up with Red Bull and Mercedes all weekend. Their straight-line speed had also decreased significantly.
Speaking to Auto Motor und Sport, Binotto explained that this was indeed a coincidence, as Ferrari just ran a more downforce-heavy set-up at the Circuit of the Americas.
"It's true our advantage has decreased since the new FIA guidelines, but teams draw the wrong conclusions. We didn't change anything about the engines. We increased drag to have more downforce. That's why we're quicker in the corners now, but slower on the straights."
The 50-year-old also understood rivals took advantage of the cheating claims just to rattle the chains at Ferrari.
"I'm not sure they actually doubt our integrity," he continued. "They use the circumstances to put pressure on us. That pressure is distracting. It's part of the Formula 1 game to unsettle your opponents. It's not just about sportive and technical competitiveness - everything that damages your rivals is good for you. Everyone plays the game that way."


{{controller.thisNode}}
Create Game
Active Games
Use the "Create Game" button to create a new game.
Game against {{game.playerO}}
Player X: You
Player O: {{game.playerO}}
Who played last: {{game.whoseTurn}}
View
Game against {{game.playerX}}
Player X: {{game.playerX}}
Player O: You
Who played last: {{game.whoseTurn}}
View
Past Games
You have no finished games yet
Game against {{game.playerO}}
Player X: You
Player O: {{game.playerO}}
Outcome: {{game.outcome}}
Game against {{game.playerX}}
Player X: {{game.playerX}}
Player O: You
Outcome: {{game.outcome}}


Dear Friend, I am Honourable Barrister Emmanuel Okafor, the personal attorney to the President Federal Republic of Nigeria,Chief Olusegun Obasanjo. I have specifically been mandated by His Excellency to source for a foreign business partner for a joint business venture. His Excellency would be vacating the seat of power come may 2007 and therefore,he has a certain amount of USD$300,000.000.00(Three hundred million dollars) which he wants to invest overseas with a reliable foreign partners,hence I am contacting you. As a matter of fact,I have already told Mr.President that I knew someone in oversea, a business mogul whom I trusted and believed that could handle these arrangement successfully. Though,His excellency is looking at the area of setting up a private oil refinery or Real Estate,but that does not mean that any other viable and lucrative business is a bad idea. If you are interested and capable of handling this arrangement please,kindly write and indicate your capability and furnish me with your present line of business. Let me also know your country of origin and your proposed country of the said investment. More details would be given to you upon my receipt of your urgent response. Please send your response only to this email address as stated here<EMAIL_ADDRESS>Sincerely, Hon.Barrister Emmanuel Okafor.


The World of Ettania
The Premier Clothing Box
Homepage
The World
Homebrew Rules
Notable Characters
General Info
Ettania is a world.
new players
Games
The world is a dangerous place!
Back to top


Mrs. Wright, seventh grade math teacher, I suppose gave the class this problem for the holidays:
Now I did know about programming, or rather coding, then, but I haven't gotten to this problem until now. The results and answers are below.
The numbers in order, top-down and left-to-right, are as follows:
Which is correct! See figure 2.
To see the code, press (for Mac) COMMAND-OPTION-I or (for PC) CTRL-OPTION-I and the code should show in the defaulted tab called "elements". The script tag contains the mini "algorithm".


Company profile - Canadian Company Capabilities
Third-Party Information Liability Disclaimer
Some of the information on this Web page has been provided by external sources. The Government of Canada is not responsible for the accuracy, reliability or currency of the information supplied by external sources. Users wishing to rely upon this information should consult directly with the source of the information. Content provided by external sources is not subject to official languages, privacy and accessibility requirements.
EMCA - Emerging Markets Capital Advisory Inc.
Legal/Operating Name:
EMCA - Emerging Markets Capital Advisory Inc.
Mailing Address:
First Canadian Place5700-100 King St W
TORONTO, Ontario
M5X 1C7
Location Address:
First Canadian Place5700-100 King St W
TORONTO, Ontario
M5X 1C7
Tel.:<PHONE_NUMBER>
Fax:
Company Profile
We specialize in establishing Canadian companies in Turkey.
Although trade between Canada and Turkey has been increasing steadily over the past five years, many Canadian corporations are still not positioned to compete against their more aggressive European counterparts as they capture market share throughout the region. EMCA understands and fully respects the way Canadian companies have traditionally been risk averse and we know that expanding into these new markets need not be an exercise in unreasonable risk taking. A methodical and well thought out plan is the first step and when coupled with expert guidance, opportunities become more realistic and risk becomes more manageable.
You need a partner who speaks the language, has access to the right information, and knows the right people to make sense of complex business issues, manage risk, and fully represent and protect your interests.
EMCA guides your investment in Turkish opportunities through unsurpassed experience in local capital markets, investment strategy, and management consulting. We are a partner that provides Canadian investors and corporations with opportunities in Turkey through our connections and understanding of both Canadian and Turkish markets.
Our aim is to build, compliment, verify and ultimately execute your expansion strategies. Contact us and let us show you how we can represent and protect your interests in Turkey.
Full profile
Full profile
Contact information
Company description
Product / Service / Licensing
Why should you have physical representation in Turkey?
- Canada and Turkey share a unique competitive advantage - both countries represent a springboard for corporations and investors to access a broader region: Canada for North America through the NAFTA agreement and Turkey for the Balkans, Eurasia and the Middle East.
- With a rapidly growing consumer base of 74 million strong, Turkey has become a critical channel of revenue growth for many international corporations in an environment of stagnation across much of the developed world.
- Turkish economic, business, social and political influence is strengthening throughout the region. Companies need proper representation in an increasingly competitive landscape.
Why and how should you make a strategic acquisition in Turkey?
- Strategic acquisitions have become the dominant expansion strategy into Turkey (and ultimately the wider region) for many international companies.
- Expanding through a co-investment with local private equity firms can ensure that the company you are buying is positioned for rapid growth.
- Identifying the right acquisition target is only part of the solution. EMCA can help you secure your acquisition at the right valuation.
- With over 60 private equity firms operating in Turkey, EMCA has direct access to many of the leading general partners and their current/target acquisition portfolio.
Why should you consider a JV structure in Turkey?
- Joint ventures and strategic partnerships between Canadian and Turkish businesses can offer tremendous benefits to both parties, including knowledge/technology transfer, new market exposure and extensive project financing opportunities.
- A successful JV structure may lead to financing opportunities from Canadian as well as Turkish institutional investors.
Why should you consider investing into the Turkish capital markets?
- MSCI index performance over four years for EM Asia, EM Latin America and Turkey suggest a level of correlation between those markets.
- Market correlation represents relative predictability in the bull/bear cycles and therefore the movement of funds in/out of emerging markets by foreign institutions.
- Value can be created two ways: investing into the cycle or acquiring access to intimate local information in order to identify valuation and pricing discrepancies in specific stocks regardless of market cycles.
- EMCA has partnerships with leading securities research houses as well as institutional traders who have access to the right information to make the most informed investment decisions.
Third-Party Information Liability Disclaimer
Some of the information on this Web page has been provided by external sources. The Government of Canada is not responsible for the accuracy, reliability or currency of the information supplied by external sources. Users wishing to rely upon this information should consult directly with the source of the information. Content provided by external sources is not subject to official languages, privacy and accessibility requirements.
Contacts
Contact information
Description
Company description
Products, services and licensing
Product / Service / Licensing
Why should you have physical representation in Turkey?
- Canada and Turkey share a unique competitive advantage - both countries represent a springboard for corporations and investors to access a broader region: Canada for North America through the NAFTA agreement and Turkey for the Balkans, Eurasia and the Middle East.
- With a rapidly growing consumer base of 74 million strong, Turkey has become a critical channel of revenue growth for many international corporations in an environment of stagnation across much of the developed world.
- Turkish economic, business, social and political influence is strengthening throughout the region. Companies need proper representation in an increasingly competitive landscape.
Why and how should you make a strategic acquisition in Turkey?
- Strategic acquisitions have become the dominant expansion strategy into Turkey (and ultimately the wider region) for many international companies.
- Expanding through a co-investment with local private equity firms can ensure that the company you are buying is positioned for rapid growth.
- Identifying the right acquisition target is only part of the solution. EMCA can help you secure your acquisition at the right valuation.
- With over 60 private equity firms operating in Turkey, EMCA has direct access to many of the leading general partners and their current/target acquisition portfolio.
Why should you consider a JV structure in Turkey?
- Joint ventures and strategic partnerships between Canadian and Turkish businesses can offer tremendous benefits to both parties, including knowledge/technology transfer, new market exposure and extensive project financing opportunities.
- A successful JV structure may lead to financing opportunities from Canadian as well as Turkish institutional investors.
Why should you consider investing into the Turkish capital markets?
- MSCI index performance over four years for EM Asia, EM Latin America and Turkey suggest a level of correlation between those markets.
- Market correlation represents relative predictability in the bull/bear cycles and therefore the movement of funds in/out of emerging markets by foreign institutions.
- Value can be created two ways: investing into the cycle or acquiring access to intimate local information in order to identify valuation and pricing discrepancies in specific stocks regardless of market cycles.
- EMCA has partnerships with leading securities research houses as well as institutional traders who have access to the right information to make the most informed investment decisions.


Highlighting, auto-complete, realtime code feedback and more.
Tuples, Closures, Lambdas, Generics and more for Jass.
Focus on content - common packages are already provided.
Frequent open source updates and blog posts.


Coaching is like a gym for the brain. It brings new perspective to a situation and supports people to find their own solutions and take action.
As a previously full –time carer myself, I found that I had a lot of time to think, but felt that I couldn’t change anything about my situation. As a consequence, my thinking became more and more negative and brought me down.
This situation helped neither me nor the person I was caring for.
A friend introduced me to coaching and I found that it opened the door to a new way of thinking. Coaching uses skilful questions to break up negative patterns of thinking, challenge assumptions and dispel the myths we tell ourselves about ‘I can’t…..’
Coaching focuses, not on the situation we are in, but on our perspective on that situation. When we explore our core values and find out what we are really committed to, then we re-discover the reasons why we are doing what we do.
What are your top 3 values? (Take out any values that you feel you ‘should’ have or you adopted because parents or an authority figure told you to).
How do you express these values in your life? Who and what are you committed to? How do you measure your success? Is it in relation to your commitments or to other people’s expectations? What do you do that is not aligned to your values, and how much does this cost you in energy?
How much energy would be available to you if you lived a life aligned with your values ? How would your view of your current life change if your perspective came from the values at the heart of who you are?

Go to the Contacts page to sign up or to get in touch with me.


The Generals Daughter
Starring John Travolta, Madeline Stowe and James Cromwell Directed By Simon West Running Time: 1 hour 56 minutes
(Paramount Pictures)
Every once in a while comes the standard 'run off the mill' movie. It's purpose is to tell a simple story, put in some action and comedy, a little romance and drama, and give the star something to do. The Generals Daughter is 1999's run off the mill movie.  The victim (Leslie Stefanson) happens to be the daughter of a general (Cromwell) who is planning to run for presidency.
Simon West, who brought us the standard action movie in the form of Con Air, moves onto standard thriller with this. All the elements are there: a shifty suspect played a well known character actor, suspenseful music, and naturally a 'thrilling' twist. Unfortunately, The Generals Daughter performs these elements a little lazier than most other films. Although there's action, it's not particularly exciting. The music is way to loud during scenes that should be played quiet. The twist is largely obvious, and James Woods doesn't get nearly enough screen time to make much of a villain. The cliched predictability of it all makes a rather boring time for the audience, which isn't what a thriller should be doing.
The cast go through the motions, looking forward for the pay cheque at the end. Travolta is obviously doing this for the money, and it must be embarrassing to have this film on his C.V along with Get Shorty and Pulp Fiction (and, er, Michael.) He also puts on one of the most atrocious southern accents heard in western cinema. Madeline Stowe, who hasn't had some good work for ages, was obviously getting late for the rent payments, and again just seems to be in this film for the money. James Cromwell delive rs a performance so average, it's impossible to believe this is the same guy from the excellent L.A Confidential. And James Woods is suitably over the top as the suspect, but just disappears from the story. The actors all have that pained, distant look that plagues every 'run off the mill' movie.
The script, written by Christopher Bertolini and, bizarrely, William Goldman, is abysmal, and leads largely to the films downfall. Some of the lines uttered are absolutely hideous, especially during the scene where the two leads are searching through the victims house. The plot chunders on in it's predictable way, pulling off virtually no surprises. The film sometimes gets surprisingly brutal for no apparent reason. And the denouement is so disappointing, it almost made me cry due to it's poorness (and I didn't shed a tear throughout E.T.)
The Generals Daughter is no classic, but it's no Burn Hollywood Burn either. It's slightly boring, deeply flawed, but it's slickly produced. Although not really worth paying for, The Generals Daughter is perfect television entertainment: it fills two hours and won't trouble the brain. But Travolta really should have aimed higher.
RATING=** OUT OF *****
A David Wilcock Review ©1999
DAVID WILCOCK<EMAIL_ADDRESS>Visit the Wilcock Movie Page! http://www.wilcock54.freeserve.co.uk
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


Features
Download
About
Features
Download
About
When you want to integrate Maps into your SharePoint and Office projects
Collaborate & Share
Collect & Analyze
Instant - No installation
Yes, I'd love a copy!
Learn how to quickly and easily integrate GIS into SharePoint in your projects or business!
See your information on Maps covering world wide data!
See
licensing
, you might qualify for free maps!
Geo tag information in all your Microsoft Office 365 projects!
When you want to integrate Maps into your SharePoint and Office projects
Yes, I'd love a copy!
projects
Geo365 for SharePoint
Geo365 for SharePoint Online
Geo365 for Office*
Geo365 Live*
*Under development
About
Licenses
Contact
Privacy document
Social


The chapter resource provides services for getting available book chapters. You can navigate through other services from here. That means you can fetch all available chapters with the URL /chapters or a specific chapter by requesting /chapters/{chapterId}, or even navigating through nested services like /chapters/{chapterId}/verses/{verseId}.
The services you can access from here are listed bellow.
| Name |
|---|
| Chapters list |
| Chapter |
| Verses |
Fetch the chapters list.
| URL | /apirest/chapters |
| Method | GET |
| Content-type | application/xml, application/json |
| Results | 200 OK, XML|JSON |
| Name | Description | Type | Default |
|---|---|---|---|
| start | The first element to return (> 0) | integer | 1 |
| pages | The number of pages to return (> 0 <= 2) | integer | 1 |
| Name | Description | Type | Default |
|---|---|---|---|
| Accept | The content-type that will be acceptable in response | string | application/xml |
Fetch a chapter by id.
| URL | /apirest/chapters/{chapterId} |
| Method | GET |
| Content-type | application/xml, application/json |
| Results | 200 OK, XML|JSON |
| Name | Description | Type | Default |
|---|---|---|---|
| No parameters |
| Name | Description | Type | Default |
|---|---|---|---|
| Accept | The content-type that will be acceptable in response | string | application/xml |
Fetch only verses of a specific chapter.
| URL | /apirest/chapters/{chapterId}/verses |
| Method | GET |
| Content-type | application/xml, application/json |
| Results | 200 OK, XML|JSON |
| Name | Description | Type | Default |
|---|---|---|---|
| start | The first element to return (> 0) | integer | 1 |
| pages | The number of pages to return (> 0 <= 2) | integer | 1 |
| Name | Description | Type | Default |
|---|---|---|---|
| Accept | The content-type that will be acceptable in response | string | application/xml |


{% extends "layout.html" %} {% block content %}
Dynamic page navigation
Ignored by the app navigation


Is this the real life? Is this just fantasy? Caught in a landslide, no escape from reality. Open your eyes, look up to the skies and see.  Any way the wind blows, doesn't really matter to me. To me... Mama, just killed a man.


Woops i did it again! Swapped another #ETH to #KMD using #Atomicdex So easy and worry free! No need to DEPOSIT my crypto in another wallet... My keys my coins.
@KomodoPlatform
@KMDCommunity
#bitcoin #blockchain #DEX #cryptocurrency #technews #cryptotrading #Crypto


Contact US
Home
Administration
Name
Title
Phone
Sally
CEO
123-123-1234
Fred
CIO
435-581-9862
Enter Your Name
Email:
Phone
Comments/Questions
BSCS Info
BSWD Info
BSGD Info
In High school
In Collage
None
Mustang
Camero
Ram-2500


Lately we needed to put a pair of small integers into a single int
variable.

Nothing crazy hard but still, it took some trial and error before we got it
right.
So, if anybody needs it or is just curious, here’s the code:
The code will test all possible tuples and quit if some unpacking gives an unexpected result.
As further reference, check out the classic page Bit Twiddling Hacks, which contains a lot of efficient algorithms for all kinds of bitwise operations!


...
Main Sensor
...
Last Reads
Day Max-Min
Dates Range
Date Time
Temperature
Humidity
Date
Load
From
To
Load


Before you can begin to determine what the composition of a particular paragraph will be, you must first decide on an argument and a working thesis statement for your paper. What is the most important idea that you are trying to convey to your reader? The information in each paragraph must be related to that idea. In other words, your paragraphs should remind your reader that there is a recurrent relationship between your thesis and the information in each paragraph. A working thesis functions like a seed from which your paper, and your ideas, will grow. The whole process is an organic one—a natural progression from a seed to a full-blown paper where there are direct, familial relationships between all of the ideas in the paper. The decision about what to put into your paragraphs begins with the germination of a seed of ideas; this “germination process” is better known as brainstorming. There are many techniques for brainstorming; whichever one you choose, this stage of paragraph development cannot be skipped. Building paragraphs can be like building a skyscraper: there must be a well-planned foundation that supports what you are building. Any cracks, inconsistencies, or other corruptions of the foundation can cause your whole paper to crumble. So, let’s suppose that you have done some brainstorming to develop your thesis. What else should you keep in mind as you begin to create paragraphs? Every paragraph in a paper should be: Unified: All of the sentences in a single paragraph should be related to a single controlling idea (often expressed in the topic sentence of the paragraph). Clearly related to the thesis: The sentences should all refer to the central idea, or thesis, of the paper (Rosen and Behrens 119). Coherent: The sentences should be arranged in a logical manner and should follow a definite plan for development (Rosen and Behrens 119). Well-developed: Every idea discussed in the paragraph should be adequately explained and supported through evidence and details that work together to explain the paragraph’s controlling idea (Rosen and Behrens 119).


Cuba
Cuba is a large island with a variety of different types of cities and landscapes. This is not your typical tropical island getaway where the entire land is made of sand and the point of being there is to drink fruity drinks and lay on the beach while you burn. The country's total length is roughly 1300km full of beautiful landscape and history. Hiking, rock climbing, rafting, diving, boating, tobacco plantations, horseback riding, nightlife, and museums are all activities the Cuban people would love to help you experience. You don't need an official tour. Cubans are extrememly friendly and are passionate about their culture and want to share that with you. People will come up to you on the street and offer to take you places. Listen to them, talk to them and go with them. Don't be afraid of the unknown and you will get to do things you didn't know you wanted to do.


Live Music in Chicago
Home
Saved Listings
Latest Listings
Live Music in Chicago
The Gig Guide from Chicago Reader
Click the button above to get the latest listings


CHRISTMAS
Santa en route to Dundalk's Marshes Shopping Centre
by Tia ClarkeDemocrat sources have revealed that Santa Claus is on his way to the Marshes Shopping Centre in Dundalk on Friday, November 29 at 5pm.
To mark the occasion of his arrival from the North Pole there will be a light show, choirs and Christmas music from LMFM.
This year, Santa’s grotto at Marshes is bigger and better than ever, and of course, Santa’s little helpers will be around to give him a hand.
Mr. Claus will be at Marshes every day until Christmas Eve, giving children the chance to visit the grotto and create unforgettable festive memories.
“I am very pleased to be coming back to beautiful Dundalk to meet all the girls and boys, and hear what they want for Christmas,” said Santa, taking a break from Christmas preparations at the North Pole,
“The boys and girls must let me know whether they have been naughty or nice and whether they will be in bed early on Christmas Eve.”
One of Santa’s elves will also be acting as a photographer to capture every child’s meeting with Santa.
On the following day, Saturday, November 30, Frozen 2 will be the theme for November’s Little Monsters Kids Club at Marshes Food Court between 12 - 4pm.
December’s Little Monsters will take place on Saturday, December 28 between 12 pm-4 pm when children will prepare for New Year’s Eve with balloon modeling, party hat decorating face painting and New Year wishes.
Marshes Christmas Wishes has returned this year. Visitors to Marshes can pick up an entry form in the Centre and drop it into the gift entry box beside Customer Services.
One wish will be granted each week between now and Christmas.


Money Play. How should Red play 54?
pips Red=68 White=114
(CorrectAnswer= 0/0, ErrorScore= 0)
The ultimate pay-me-now, pay-me-later problem. I have seen many such problems over the years and paying later when your opponent has such a strong board is usually correct.
However, Red’s structure is so weak after 6/1, 5/1 that paying now might be correct. If this was Double Match Point 6/1, 5/1 would be tied with 8/4, 8/3. However, the cube is in play and in this version 8/4, 8/3 is best. Why?
Quite simply both plays win the same amount of the time but 8/4, 8/3 wins many more gammons because Red’s bear-off is much faster.
Be honest, did you consider about the gammon factor?
However, Red’s structure is so weak after 6/1, 5/1 that paying now might be correct. If this was Double Match Point 6/1, 5/1 would be tied with 8/4, 8/3. However, the cube is in play and in this version 8/4, 8/3 is best. Why?
Quite simply both plays win the same amount of the time but 8/4, 8/3 wins many more gammons because Red’s bear-off is much faster.
Be honest, did you consider about the gammon factor?
1. Cubeful 2-ply 8/4 8/3 Eq.: +0.202 0.623 0.085 0.003 - 0.377 0.033 0.001 2. Cubeful 2-ply 6/1 5/1 Eq.: +0.125 (-0.078) 0.620 0.044 0.001 - 0.380 0.030 0.000 3. Cubeful 0-ply 8/4 6/1 Eq.: +0.001 (-0.201) 0.559 0.068 0.003 - 0.441 0.038 0.001 4. Cubeful 0-ply 8/3 5/1 Eq.: -0.392 (-0.594) 0.424 0.067 0.003 - 0.576 0.112 0.003


About
The LGSVL Simulator is a simulator that facilitates testing and development of autonomous driving software systems. It enables developers to simulate billions of miles and arbitrary edge case scenarios to speed up algorithm development and system integration.
Our Unity-based, ROS-compatible simulator is fully integrated with the popular open source platforms Baidu Apollo and Tier IV Autoware. Our source code is on Github and free to try.


| Package | Description |
|---|---|
| org.apache.solr.core |
Core classes implementin Solr internals and the management of
SolrCore s |
| org.apache.solr.handler |
Concrete implementations of
SolrRequestHandler |
| org.apache.solr.handler.component |
SearchComponent implementations for
use in SearchHandler |
| org.apache.solr.highlight |
SolrHighlighter API and related implementaions and utilities |
| org.apache.solr.parser |
Solr native variant of the Lucene Classic QueryParser
|
| org.apache.solr.query |
Solr Queries
|
| org.apache.solr.request |
APIs and classes for dealing with Solr requests
|
| org.apache.solr.response |
API and implementations of
QueryResponseWriter for formating Solr request responses |
| org.apache.solr.response.transform |
APIs and implementations of
DocTransformer for modifying documents in Solr request responses |
| org.apache.solr.schema |
IndexSchema and FieldType implementations for powering schema.xml |
| org.apache.solr.search |
APIs and classes for parsing and processing search requests
|
| org.apache.solr.search.facet |
APIs and classes for the JSON Facet API.
|
| org.apache.solr.search.function |
Solr implementations of
ValueSource for function queries. |
| org.apache.solr.search.function.distance |
Solr implementations of
ValueSource for distance based function queries. |
| org.apache.solr.search.grouping |
APIs and classes for implementing result grouping
|
| org.apache.solr.search.grouping.collector |
Grouping related
Collector s |
| org.apache.solr.search.grouping.distributed.command |
Internal classes used to implement distributed result grouping
|
| org.apache.solr.search.grouping.distributed.shardresultserializer |
Internal classes used to implement distributed result grouping
|
| org.apache.solr.search.grouping.endresulttransformer |
APIs and classes for transforming result grouping results into the appropriate response format
|
| org.apache.solr.search.join |
Classes related to joins.
|
| org.apache.solr.search.mlt |
APIs and classes for implementing MoreLikeThis (mlt) QueryParser.
|
| org.apache.solr.search.stats |
APIs and Classes implementing the Stats component used for document frequency
calculations.
|
| org.apache.solr.spelling |
APIs and classes used by the
SpellCheckComponent |
| org.apache.solr.spelling.suggest |
APIs and classes used by the
SpellCheckComponent |
| org.apache.solr.store.blockcache |
An HDFS blockcache implementation.
|
| org.apache.solr.update |
APIs and classes for managing index updates
|
| org.apache.solr.util |
Common utility classes used throughout Solr
|
| Class and Description |
|---|
| CacheConfig
Contains the knowledge of how cache config is
stored in the solrconfig.xml file, and implements a
factory to create caches.
|
| QParserPlugin |
| SolrIndexSearcher
SolrIndexSearcher adds schema awareness and caching functionality
over the lucene IndexSearcher.
|
| ValueSourceParser
A factory that parses user queries to generate ValueSource instances.
|
| Class and Description |
|---|
DocList
DocList represents the result of a query: an ordered list of document ids with optional score. |
| DocListAndSet |
| SolrIndexSearcher
SolrIndexSearcher adds schema awareness and caching functionality
over the lucene IndexSearcher.
|
| Class and Description |
|---|
| CursorMark
An object that encapsulates the basic information about the current Mark Point of a
"Cursor" based request.
|
DocList
DocList represents the result of a query: an ordered list of document ids with optional score. |
| DocListAndSet |
DocSet
DocSet represents an unordered set of Lucene Document Ids. |
| QParser
Note: This API is experimental and may change in non backward-compatible ways in the future
|
| RankQuery
Note: This API is experimental and may change in non backward-compatible ways in the future
|
| SolrIndexSearcher
SolrIndexSearcher adds schema awareness and caching functionality
over the lucene IndexSearcher.
|
| SolrIndexSearcher.QueryCommand
A query request command to avoid having to change the method signatures
if we want to pass additional information to the searcher.
|
| SolrIndexSearcher.QueryResult
The result of a search.
|
| SortSpec
SortSpec encapsulates a Lucene Sort and a count of the number of documents
to return.
|
| SyntaxError
Simple checked exception for parsing errors
|
| Class and Description |
|---|
DocList
DocList represents the result of a query: an ordered list of document ids with optional score. |
| SolrIndexSearcher
SolrIndexSearcher adds schema awareness and caching functionality
over the lucene IndexSearcher.
|
| Class and Description |
|---|
| QParser
Note: This API is experimental and may change in non backward-compatible ways in the future
|
| SyntaxError
Simple checked exception for parsing errors
|
| Class and Description |
|---|
| ExtendedQuery
The ExtendedQuery interface provides extra metadata to a query.
|
| ExtendedQueryBase |
| Class and Description |
|---|
DocSet
DocSet represents an unordered set of Lucene Document Ids. |
| SolrIndexSearcher
SolrIndexSearcher adds schema awareness and caching functionality
over the lucene IndexSearcher.
|
| SyntaxError
Simple checked exception for parsing errors
|
| Class and Description |
|---|
DocList
DocList represents the result of a query: an ordered list of document ids with optional score. |
| ReturnFields
A class representing the return fields
|
| SolrIndexSearcher
SolrIndexSearcher adds schema awareness and caching functionality
over the lucene IndexSearcher.
|
| Class and Description |
|---|
| DocIterator
Simple Iterator of document Ids which may include score information.
|
| QParser
Note: This API is experimental and may change in non backward-compatible ways in the future
|
| SolrIndexSearcher
SolrIndexSearcher adds schema awareness and caching functionality
over the lucene IndexSearcher.
|
| Class and Description |
|---|
| QParser
Note: This API is experimental and may change in non backward-compatible ways in the future
|
| SolrIndexSearcher
SolrIndexSearcher adds schema awareness and caching functionality
over the lucene IndexSearcher.
|
| SpatialOptions |
| Class and Description |
|---|
BitDocSet
BitDocSet represents an unordered set of Lucene Document Ids
using a BitSet. |
| CacheConfig
Contains the knowledge of how cache config is
stored in the solrconfig.xml file, and implements a
factory to create caches.
|
| CacheRegenerator
Implementations of
CacheRegenerator are used in autowarming to populate a new cache
based on an old cache. |
| CollapsingQParserPlugin.GroupHeadSelector
Models all the information about how group head documents should be selected
|
| CollapsingQParserPlugin.GroupHeadSelectorType |
| CursorMark
An object that encapsulates the basic information about the current Mark Point of a
"Cursor" based request.
|
| DelegatingCollector
A simple delegating collector where one can set the delegate after creation
|
| DocIterator
Simple Iterator of document Ids which may include score information.
|
DocList
DocList represents the result of a query: an ordered list of document ids with optional score. |
| DocListAndSet |
DocSet
DocSet represents an unordered set of Lucene Document Ids. |
DocSlice
DocSlice implements DocList as an array of docids and optional scores. |
| ExtendedDismaxQParser.Clause |
| ExtendedDismaxQParser.ExtendedDismaxConfiguration
Simple container for configuration information used when parsing queries
|
| ExtendedDismaxQParser.ExtendedSolrQueryParser
A subclass of SolrQueryParser that supports aliasing fields for
constructing DisjunctionMaxQueries.
|
| ExtendedDismaxQParser.ExtendedSolrQueryParser.Alias
A simple container for storing alias info
|
| ExtendedQuery
The ExtendedQuery interface provides extra metadata to a query.
|
| ExtendedQueryBase |
| FieldParams
A class to hold "phrase slop" and "boost" parameters for pf, pf2, pf3 parameters
|
| FunctionQParser |
| Grouping
Basic Solr Grouping infrastructure.
|
| Grouping.Command
General group command.
|
| Grouping.Format |
| Grouping.TotalCount |
HashDocSet
HashDocSet represents an unordered set of Lucene Document Ids
using a primitive int hash table. |
| LuceneQParser |
| LuceneQParserPlugin
Parse Solr's variant on the Lucene QueryParser syntax.
|
| PostFilter
The PostFilter interface provides a mechanism to further filter documents
after they have already gone through the main query and other filters.
|
| QParser
Note: This API is experimental and may change in non backward-compatible ways in the future
|
| QParserPlugin |
| QueryContext |
| RankQuery
Note: This API is experimental and may change in non backward-compatible ways in the future
|
| ReturnFields
A class representing the return fields
|
| ScoreFilter |
| SolrCache
Primary API for dealing with Solr's internal caches.
|
| SolrCache.State
Enumeration of possible States for cache instances.
|
| SolrCacheBase
Common base class of reusable functionality for SolrCaches
|
| SolrCacheBase.AutoWarmCountRef
Decides how many things to autowarm based on the size of another cache
|
| SolrConstantScoreQuery
A query that wraps a filter and simply returns a constant score equal to the
query boost for every document in the filter.
|
| SolrIndexSearcher
SolrIndexSearcher adds schema awareness and caching functionality
over the lucene IndexSearcher.
|
| SolrIndexSearcher.DocsEnumState |
| SolrIndexSearcher.ProcessedFilter |
| SolrIndexSearcher.QueryCommand
A query request command to avoid having to change the method signatures
if we want to pass additional information to the searcher.
|
| SolrIndexSearcher.QueryResult
The result of a search.
|
| SolrQueryParser
Solr's default query parser, a schema-driven superset of the classic lucene query parser.
|
| SolrQueryTimeoutImpl
Implementation of
QueryTimeout that is used by Solr. |
SortedIntDocSet
SortedIntDocSet represents a sorted set of Lucene Document Ids. |
| SortSpec
SortSpec encapsulates a Lucene Sort and a count of the number of documents
to return.
|
| SpatialFilterQParserPlugin
Creates a spatial Filter based on the type of spatial point used.
|
| StrParser
Simple class to help with parsing a string.
|
| SyntaxError
Simple checked exception for parsing errors
|
| ValueSourceParser
A factory that parses user queries to generate ValueSource instances.
|
| Class and Description |
|---|
BitDocSet
BitDocSet represents an unordered set of Lucene Document Ids
using a BitSet. |
DocSet
DocSet represents an unordered set of Lucene Document Ids. |
| FunctionQParser |
| QParser
Note: This API is experimental and may change in non backward-compatible ways in the future
|
| QueryContext |
| SolrIndexSearcher
SolrIndexSearcher adds schema awareness and caching functionality
over the lucene IndexSearcher.
|
| SyntaxError
Simple checked exception for parsing errors
|
| ValueSourceParser
A factory that parses user queries to generate ValueSource instances.
|
| Class and Description |
|---|
| SolrFilter
A SolrFilter extends the Lucene Filter and adds extra semantics such as passing on
weight context info for function queries.
|
| Class and Description |
|---|
| FunctionQParser |
| SyntaxError
Simple checked exception for parsing errors
|
| ValueSourceParser
A factory that parses user queries to generate ValueSource instances.
|
| Class and Description |
|---|
| Grouping.Format |
| SolrIndexSearcher
SolrIndexSearcher adds schema awareness and caching functionality
over the lucene IndexSearcher.
|
| SolrIndexSearcher.QueryCommand
A query request command to avoid having to change the method signatures
if we want to pass additional information to the searcher.
|
| SolrIndexSearcher.QueryResult
The result of a search.
|
| Class and Description |
|---|
DocSet
DocSet represents an unordered set of Lucene Document Ids. |
| Class and Description |
|---|
DocSet
DocSet represents an unordered set of Lucene Document Ids. |
| SolrIndexSearcher
SolrIndexSearcher adds schema awareness and caching functionality
over the lucene IndexSearcher.
|
| SyntaxError
Simple checked exception for parsing errors
|
| Class and Description |
|---|
| SolrIndexSearcher
SolrIndexSearcher adds schema awareness and caching functionality
over the lucene IndexSearcher.
|
| Class and Description |
|---|
| SolrIndexSearcher
SolrIndexSearcher adds schema awareness and caching functionality
over the lucene IndexSearcher.
|
| Class and Description |
|---|
| QParser
Note: This API is experimental and may change in non backward-compatible ways in the future
|
| QParserPlugin |
| Class and Description |
|---|
| QParser
Note: This API is experimental and may change in non backward-compatible ways in the future
|
| QParserPlugin |
| Class and Description |
|---|
| SolrIndexSearcher
SolrIndexSearcher adds schema awareness and caching functionality
over the lucene IndexSearcher.
|
| Class and Description |
|---|
| SolrIndexSearcher
SolrIndexSearcher adds schema awareness and caching functionality
over the lucene IndexSearcher.
|
| Class and Description |
|---|
| SolrIndexSearcher
SolrIndexSearcher adds schema awareness and caching functionality
over the lucene IndexSearcher.
|
| Class and Description |
|---|
| SolrCacheBase
Common base class of reusable functionality for SolrCaches
|
| Class and Description |
|---|
| SolrIndexSearcher
SolrIndexSearcher adds schema awareness and caching functionality
over the lucene IndexSearcher.
|
| Class and Description |
|---|
| CacheRegenerator
Implementations of
CacheRegenerator are used in autowarming to populate a new cache
based on an old cache. |
DocList
DocList represents the result of a query: an ordered list of document ids with optional score. |
| FieldParams
A class to hold "phrase slop" and "boost" parameters for pf, pf2, pf3 parameters
|
| QParser
Note: This API is experimental and may change in non backward-compatible ways in the future
|
| SolrCache
Primary API for dealing with Solr's internal caches.
|
| SolrIndexSearcher
SolrIndexSearcher adds schema awareness and caching functionality
over the lucene IndexSearcher.
|
| SolrQueryParser
Solr's default query parser, a schema-driven superset of the classic lucene query parser.
|
| SyntaxError
Simple checked exception for parsing errors
|
Copyright © 2000-2016 Apache Software Foundation. All Rights Reserved.


@import helper._ @import org.webjars.play.WebJarsUtil @(message: String, pdfBase64: String)(implicit webJarsUtil: WebJarsUtil) @main("Report saved - Short Format Pre Sentence Report", false) {
Your report has been saved
and uploaded successfully to Delius