text:
#include "../vk_core.h"
#include "../vk_debug.h"
#include "../vk_rendertext.h"
#include "../vk_shader_cache.h"

// vk_dispatchtables.cpp
void InitDeviceTable(VkDevice dev, PFN_vkGetDeviceProcAddr gpa);
void InitInstanceTable(VkInstance inst, PFN_vkGetInstanceProcAddr gpa);

// Init/shutdown order:
//
// On capture, WrappedVulkan is new'd and delete'd before vkCreateInstance() and after
// vkDestroyInstance()
// On replay,  WrappedVulkan is new'd and delete'd before Initialise()       and after Shutdown()
//
// The class constructor and destructor handle only *non-API* work. All API objects must be created
// and
// torn down in the latter functions (vkCreateInstance/vkDestroyInstance during capture, and
// Initialise/Shutdown during replay).
//
// Note that during capture we have vkDestroyDevice before vkDestroyDevice that does most of the
// work.
//
// Also we assume correctness from the application, that all objects are destroyed before the device
// and
// instance are destroyed. We only clean up after our own objects.

static void StripUnwantedLayers(vector<string> &Layers)
{
  for(auto it = Layers.begin(); it != Layers.end();)
  {
    // don't try and create our own layer on replay!
    if(*it == RENDERDOC_VULKAN_LAYER_NAME)
    {
      it = Layers.erase(it);
      continue;
    }

    // don't enable tracing or dumping layers just in case they
    // came along with the application
    if(*it == "VK_LAYER_LUNARG_api_dump" || *it == "VK_LAYER_LUNARG_vktrace")
    {
      it = Layers.erase(it);
      continue;
    }

    // also remove the framerate monitor layer as it's buggy and doesn't do anything
    // in our case
    if(*it == "VK_LAYER_LUNARG_monitor")
    {
      it = Layers.erase(it);
      continue;
    }

    // filter out validation layers
    if(*it == "VK_LAYER_LUNARG_standard_validation" || *it == "VK_LAYER_LUNARG_core_validation" ||
       *it == "VK_LAYER_LUNARG_device_limits" || *it == "VK_LAYER_LUNARG_image" ||
       *it == "VK_LAYER_LUNARG_object_tracker" || *it == "VK_LAYER_LUNARG_parameter_validation" ||
       *it == "VK_LAYER_LUNARG_swapchain" || *it == "VK_LAYER_GOOGLE_threading" ||
       *it == "VK_LAYER_GOOGLE_unique_objects")
    {
      it = Layers.erase(it);
      continue;
    }

    ++it;
  }
}

ReplayStatus WrappedVulkan::Initialise(VkInitParams &params, uint64_t sectionVersion)
{
  m_InitParams = params;
  m_SectionVersion = sectionVersion;

  params.AppName = string("RenderDoc @ ") + params.AppName;
  params.EngineName = string("RenderDoc @ ") + params.EngineName;

  // PORTABILITY verify that layers/extensions are available
  StripUnwantedLayers(params.Layers);

#if ENABLED(FORCE_VALIDATION_LAYERS) && DISABLED(RDOC_ANDROID)
  params.Layers.push_back("VK_LAYER_LUNARG_standard_validation");
#endif

  // strip out any WSI/direct display extensions. We'll add the ones we want for creating windows
  // on the current platforms below, and we don't replay any of the WSI functionality
  // directly so these extensions aren't needed
  for(auto it = params.Extensions.begin(); it != params.Extensions.end();)
  {
    if(*it == "VK_KHR_xlib_surface" || *it == "VK_KHR_xcb_surface" ||
       *it == "VK_KHR_wayland_surface" || *it == "VK_KHR_mir_surface" ||
       *it == "VK_KHR_android_surface" || *it == "VK_KHR_win32_surface" ||
       *it == "VK_KHR_display" || *it == "VK_EXT_direct_mode_display" ||
       *it == "VK_EXT_acquire_xlib_display" || *it == "VK_EXT_display_surface_counter")
    {
      it = params.Extensions.erase(it);
    }
    else
    {
      ++it;
    }
  }

  RDCEraseEl(m_ExtensionsEnabled);

  std::set<string> supportedExtensions;

  for(size_t i = 0; i <= params.Layers.size(); i++)
  {
    const char *pLayerName = (i == 0 ? NULL : params.Layers[i - 1].c_str());

    uint32_t count = 0;
    GetInstanceDispatchTable(NULL)->EnumerateInstanceExtensionProperties(pLayerName, &count, NULL);

    VkExtensionProperties *props = new VkExtensionProperties[count];
    GetInstanceDispatchTable(NULL)->EnumerateInstanceExtensionProperties(pLayerName, &count, props);

    for(uint32_t e = 0; e < count; e++)
      supportedExtensions.insert(props[e].extensionName);

    SAFE_DELETE_ARRAY(props);
  }

  std::set<string> supportedLayers;

  {
    uint32_t count = 0;
    GetInstanceDispatchTable(NULL)->EnumerateInstanceLayerProperties(&count, NULL);

    VkLayerProperties *props = new VkLayerProperties[count];
    GetInstanceDispatchTable(NULL)->EnumerateInstanceLayerProperties(&count, props);

    for(uint32_t e = 0; e < count; e++)
      supportedLayers.insert(props[e].layerName);

    SAFE_DELETE_ARRAY(props);
  }

  AddRequiredExtensions(true, params.Extensions, supportedExtensions);

  if(supportedExtensions.find(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME) ==
     supportedExtensions.end())
  {
    RDCWARN("Unsupported required instance extension for AMD performance counters '%s'",
            VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
  }
  else
  {
    if(std::find(params.Extensions.begin(), params.Extensions.end(),
                 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME) == params.Extensions.end())
      params.Extensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
  }

  // verify that extensions & layers are supported
  for(size_t i = 0; i < params.Layers.size(); i++)
  {
    if(supportedLayers.find(params.Layers[i]) == supportedLayers.end())
    {
      RDCERR("Log requires layer '%s' which is not supported", params.Layers[i].c_str());
      return ReplayStatus::APIHardwareUnsupported;
    }
  }

  for(size_t i = 0; i < params.Extensions.size(); i++)
  {
    if(supportedExtensions.find(params.Extensions[i]) == supportedExtensions.end())
    {
      RDCERR("Log requires extension '%s' which is not supported", params.Extensions[i].c_str());
      return ReplayStatus::APIHardwareUnsupported;
    }
  }

  // we always want this extension if it's available, and not already enabled
  if(supportedExtensions.find(VK_EXT_DEBUG_REPORT_EXTENSION_NAME) != supportedExtensions.end() &&
     std::find(params.Extensions.begin(), params.Extensions.end(),
               VK_EXT_DEBUG_REPORT_EXTENSION_NAME) == params.Extensions.end())
  {
    RDCLOG("Enabling VK_EXT_debug_report");
    params.Extensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
  }

  const char **layerscstr = new const char *[params.Layers.size()];
  for(size_t i = 0; i < params.Layers.size(); i++)
    layerscstr[i] = params.Layers[i].c_str();

  const char **extscstr = new const char *[params.Extensions.size()];
  for(size_t i = 0; i < params.Extensions.size(); i++)
    extscstr[i] = params.Extensions[i].c_str();

  VkApplicationInfo appinfo = {
      VK_STRUCTURE_TYPE_APPLICATION_INFO,
      NULL,
      params.AppName.c_str(),
      params.AppVersion,
      params.EngineName.c_str(),
      params.EngineVersion,
      VK_API_VERSION_1_0,
  };

  VkInstanceCreateInfo instinfo = {
      VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
      NULL,
      0,
      &appinfo,
      (uint32_t)params.Layers.size(),
      layerscstr,
      (uint32_t)params.Extensions.size(),
      extscstr,
  };

  m_Instance = VK_NULL_HANDLE;

  VkResult ret = GetInstanceDispatchTable(NULL)->CreateInstance(&instinfo, NULL, &m_Instance);

  InstanceDeviceInfo extInfo;

#undef CheckExt
#define CheckExt(name)                                    \
  if(!strcmp(instinfo.ppEnabledExtensionNames[i], #name)) \
  {                                                       \
    extInfo.ext_##name = true;                            \
  }

  for(uint32_t i = 0; i < instinfo.enabledExtensionCount; i++)
  {
    CheckInstanceExts();
  }

  SAFE_DELETE_ARRAY(layerscstr);
  SAFE_DELETE_ARRAY(extscstr);

  if(ret != VK_SUCCESS)
    return ReplayStatus::APIHardwareUnsupported;

  RDCASSERTEQUAL(ret, VK_SUCCESS);

  GetResourceManager()->WrapResource(m_Instance, m_Instance);
  GetResourceManager()->AddLiveResource(params.InstanceID, m_Instance);

  // we'll add the chunk later when we re-process it.
  AddResource(params.InstanceID, ResourceType::Device, "Instance");
  GetReplay()->GetResourceDesc(params.InstanceID).initialisationChunks.clear();

  InitInstanceExtensionTables(m_Instance, &extInfo);

  m_DbgMsgCallback = VK_NULL_HANDLE;
  m_PhysicalDevice = VK_NULL_HANDLE;
  m_Device = VK_NULL_HANDLE;
  m_QueueFamilyIdx = ~0U;
  m_Queue = VK_NULL_HANDLE;
  m_InternalCmds.Reset();

  if(ObjDisp(m_Instance)->CreateDebugReportCallbackEXT)
  {
    VkDebugReportCallbackCreateInfoEXT debugInfo = {};
    debugInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
    debugInfo.pNext = NULL;
    debugInfo.pfnCallback = &DebugCallbackStatic;
    debugInfo.pUserData = this;
    debugInfo.flags = VK_DEBUG_REPORT_WARNING_BIT_EXT |
                      VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT | VK_DEBUG_REPORT_ERROR_BIT_EXT;

    ObjDisp(m_Instance)
        ->CreateDebugReportCallbackEXT(Unwrap(m_Instance), &debugInfo, NULL, &m_DbgMsgCallback);
  }

  uint32_t count = 0;

  VkResult vkr = ObjDisp(m_Instance)->EnumeratePhysicalDevices(Unwrap(m_Instance), &count, NULL);
  RDCASSERTEQUAL(vkr, VK_SUCCESS);

  m_ReplayPhysicalDevices.resize(count);
  m_ReplayPhysicalDevicesUsed.resize(count);
  m_OriginalPhysicalDevices.resize(count);
  m_MemIdxMaps.resize(count);

  vkr = ObjDisp(m_Instance)
            ->EnumeratePhysicalDevices(Unwrap(m_Instance), &count, &m_ReplayPhysicalDevices[0]);
  RDCASSERTEQUAL(vkr, VK_SUCCESS);

  for(uint32_t i = 0; i < count; i++)
    GetResourceManager()->WrapResource(m_Instance, m_ReplayPhysicalDevices[i]);

  return ReplayStatus::Succeeded;
}

VkResult WrappedVulkan::vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo,
                                         const VkAllocationCallbacks *pAllocator,
                                         VkInstance *pInstance)
{
  RDCASSERT(pCreateInfo);

  // don't support any extensions for this createinfo
  RDCASSERT(pCreateInfo->pApplicationInfo == NULL || pCreateInfo->pApplicationInfo->pNext == NULL);

  VkLayerInstanceCreateInfo *layerCreateInfo = (VkLayerInstanceCreateInfo *)pCreateInfo->pNext;

  // step through the chain of pNext until we get to the link info
  while(layerCreateInfo && (layerCreateInfo->sType != VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO ||
                            layerCreateInfo->function != VK_LAYER_LINK_INFO))
  {
    layerCreateInfo = (VkLayerInstanceCreateInfo *)layerCreateInfo->pNext;
  }
  RDCASSERT(layerCreateInfo);

  if(layerCreateInfo == NULL)
  {
    RDCERR("Couldn't find loader instance create info, which is required. Incompatible loader?");
    return VK_ERROR_INITIALIZATION_FAILED;
  }

  PFN_vkGetInstanceProcAddr gpa = layerCreateInfo->u.pLayerInfo->pfnNextGetInstanceProcAddr;
  // move chain on for next layer
  layerCreateInfo->u.pLayerInfo = layerCreateInfo->u.pLayerInfo->pNext;

  PFN_vkCreateInstance createFunc = (PFN_vkCreateInstance)gpa(VK_NULL_HANDLE, "vkCreateInstance");

  VkInstanceCreateInfo modifiedCreateInfo;
  modifiedCreateInfo = *pCreateInfo;

  for(uint32_t i = 0; i < modifiedCreateInfo.enabledExtensionCount; i++)
  {
    if(!IsSupportedExtension(modifiedCreateInfo.ppEnabledExtensionNames[i]))
    {
      RDCERR("RenderDoc does not support instance extension '%s'.",
             modifiedCreateInfo.ppEnabledExtensionNames[i]);
      RDCERR("File an issue on github to request support: https://github.com/baldurk/renderdoc");

      // see if any debug report callbacks were passed in the pNext chain
      VkDebugReportCallbackCreateInfoEXT *report =
          (VkDebugReportCallbackCreateInfoEXT *)pCreateInfo->pNext;

      while(report)
      {
        if(report && report->sType == VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT)
          report->pfnCallback(VK_DEBUG_REPORT_ERROR_BIT_EXT,
                              VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, 0, 1, 1, "RDOC",
                              "RenderDoc does not support a requested instance extension.",
                              report->pUserData);

        report = (VkDebugReportCallbackCreateInfoEXT *)report->pNext;
      }

      return VK_ERROR_EXTENSION_NOT_PRESENT;
    }
  }

  const char **addedExts = new const char *[modifiedCreateInfo.enabledExtensionCount + 1];

  bool hasDebugReport = false;

  for(uint32_t i = 0; i < modifiedCreateInfo.enabledExtensionCount; i++)
  {
    addedExts[i] = modifiedCreateInfo.ppEnabledExtensionNames[i];
    if(!strcmp(addedExts[i], VK_EXT_DEBUG_REPORT_EXTENSION_NAME))
      hasDebugReport = true;
  }

  // enumerate what instance extensions are available
  void *module = Process::LoadModule(VulkanLibraryName);
  PFN_vkEnumerateInstanceExtensionProperties enumInstExts =
      (PFN_vkEnumerateInstanceExtensionProperties)Process::GetFunctionAddress(
          module, "vkEnumerateInstanceExtensionProperties");

  uint32_t numSupportedExts = 0;
  enumInstExts(NULL, &numSupportedExts, NULL);

  std::vector<VkExtensionProperties> supportedExts(numSupportedExts);
  enumInstExts(NULL, &numSupportedExts, &supportedExts[0]);

  // always enable debug report, if it's available
  if(!hasDebugReport)
  {
    for(const VkExtensionProperties &ext : supportedExts)
    {
      if(!strcmp(ext.extensionName, VK_EXT_DEBUG_REPORT_EXTENSION_NAME))
      {
        addedExts[modifiedCreateInfo.enabledExtensionCount++] = VK_EXT_DEBUG_REPORT_EXTENSION_NAME;
        break;
      }
    }
  }

  modifiedCreateInfo.ppEnabledExtensionNames = addedExts;

  VkResult ret = createFunc(&modifiedCreateInfo, pAllocator, pInstance);

  m_Instance = *pInstance;

  InitInstanceTable(m_Instance, gpa);

  GetResourceManager()->WrapResource(m_Instance, m_Instance);

  *pInstance = m_Instance;

  // should only be called during capture
  RDCASSERT(IsCaptureMode(m_State));

  m_InitParams.Set(pCreateInfo, GetResID(m_Instance));
  VkResourceRecord *record = GetResourceManager()->AddResourceRecord(m_Instance);

  record->instDevInfo = new InstanceDeviceInfo();

#undef CheckExt
#define CheckExt(name)                                              \
  if(!strcmp(modifiedCreateInfo.ppEnabledExtensionNames[i], #name)) \
  {                                                                 \
    record->instDevInfo->ext_##name = true;                         \
  }

  for(uint32_t i = 0; i < modifiedCreateInfo.enabledExtensionCount; i++)
  {
    CheckInstanceExts();
  }

  delete[] addedExts;

  InitInstanceExtensionTables(m_Instance, record->instDevInfo);

  RenderDoc::Inst().AddDeviceFrameCapturer(LayerDisp(m_Instance), this);

  m_DbgMsgCallback = VK_NULL_HANDLE;
  m_PhysicalDevice = VK_NULL_HANDLE;
  m_Device = VK_NULL_HANDLE;
  m_QueueFamilyIdx = ~0U;
  m_Queue = VK_NULL_HANDLE;
  m_InternalCmds.Reset();

  if(ObjDisp(m_Instance)->CreateDebugReportCallbackEXT)
  {
    VkDebugReportCallbackCreateInfoEXT debugInfo = {};
    debugInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
    debugInfo.pNext = NULL;
    debugInfo.pfnCallback = &DebugCallbackStatic;
    debugInfo.pUserData = this;
    debugInfo.flags = VK_DEBUG_REPORT_WARNING_BIT_EXT |
                      VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT | VK_DEBUG_REPORT_ERROR_BIT_EXT;

    ObjDisp(m_Instance)
        ->CreateDebugReportCallbackEXT(Unwrap(m_Instance), &debugInfo, NULL, &m_DbgMsgCallback);
  }

  if(ret == VK_SUCCESS)
  {
    RDCLOG("Initialised capture layer in Vulkan instance.");
  }

  return ret;
}

void WrappedVulkan::Shutdown()
{
  // flush out any pending commands/semaphores
  SubmitCmds();
  SubmitSemaphores();
  FlushQ();

  // destroy any events we created for waiting on
  for(size_t i = 0; i < m_PersistentEvents.size(); i++)
    ObjDisp(GetDev())->DestroyEvent(Unwrap(GetDev()), m_PersistentEvents[i], NULL);

  m_PersistentEvents.clear();

  // since we didn't create proper registered resources for our command buffers,
  // they won't be taken down properly with the pool. So we release them (just our
  // data) here.
  for(size_t i = 0; i < m_InternalCmds.freecmds.size(); i++)
    GetResourceManager()->ReleaseWrappedResource(m_InternalCmds.freecmds[i]);

  // destroy the pool
  ObjDisp(m_Device)->DestroyCommandPool(Unwrap(m_Device), Unwrap(m_InternalCmds.cmdpool), NULL);
  GetResourceManager()->ReleaseWrappedResource(m_InternalCmds.cmdpool);

  for(size_t i = 0; i < m_InternalCmds.freesems.size(); i++)
  {
    ObjDisp(m_Device)->DestroySemaphore(Unwrap(m_Device), Unwrap(m_InternalCmds.freesems[i]), NULL);
    GetResourceManager()->ReleaseWrappedResource(m_InternalCmds.freesems[i]);
  }

  FreeAllMemory(MemoryScope::InitialContents);

  // we do more in Shutdown than the equivalent vkDestroyInstance since on replay there's
  // no explicit vkDestroyDevice, we destroy the device here then the instance

  // destroy the physical devices manually because due to remapping the may have leftover
  // refcounts
  for(size_t i = 0; i < m_ReplayPhysicalDevices.size(); i++)
    GetResourceManager()->ReleaseWrappedResource(m_ReplayPhysicalDevices[i]);

  m_Replay.DestroyResources();

  // destroy debug manager and any objects it created
  SAFE_DELETE(m_DebugManager);
  SAFE_DELETE(m_ShaderCache);

  if(ObjDisp(m_Instance)->DestroyDebugReportCallbackEXT && m_DbgMsgCallback != VK_NULL_HANDLE)
    ObjDisp(m_Instance)->DestroyDebugReportCallbackEXT(Unwrap(m_Instance), m_DbgMsgCallback, NULL);

  // need to store the unwrapped device and instance to destroy the
  // API object after resource manager shutdown
  VkInstance inst = Unwrap(m_Instance);
  VkDevice dev = Unwrap(m_Device);

  const VkLayerDispatchTable *vt = ObjDisp(m_Device);
  const VkLayerInstanceDispatchTable *vit = ObjDisp(m_Instance);

  // this destroys the wrapped objects for the devices and instances
  m_ResourceManager->Shutdown();

  delete GetWrapped(m_Device);
  delete GetWrapped(m_Instance);

  m_PhysicalDevice = VK_NULL_HANDLE;
  m_Device = VK_NULL_HANDLE;
  m_Instance = VK_NULL_HANDLE;

  m_ReplayPhysicalDevices.clear();
  m_PhysicalDevices.clear();

  for(size_t i = 0; i < m_QueueFamilies.size(); i++)
    delete[] m_QueueFamilies[i];

  m_QueueFamilies.clear();

  // finally destroy device then instance
  vt->DestroyDevice(dev, NULL);
  vit->DestroyInstance(inst, NULL);
}

void WrappedVulkan::vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator)
{
  RDCASSERT(m_Instance == instance);

  if(ObjDisp(m_Instance)->DestroyDebugReportCallbackEXT && m_DbgMsgCallback != VK_NULL_HANDLE)
    ObjDisp(m_Instance)->DestroyDebugReportCallbackEXT(Unwrap(m_Instance), m_DbgMsgCallback, NULL);

  // the device should already have been destroyed, assuming that the
  // application is well behaved. If not, we just leak.

  ObjDisp(m_Instance)->DestroyInstance(Unwrap(m_Instance), NULL);
  GetResourceManager()->ReleaseWrappedResource(m_Instance);

  RenderDoc::Inst().RemoveDeviceFrameCapturer(LayerDisp(m_Instance));

  m_Instance = VK_NULL_HANDLE;
}

template <typename SerialiserType>
bool WrappedVulkan::Serialise_vkEnumeratePhysicalDevices(SerialiserType &ser, VkInstance instance,
                                                         uint32_t *pPhysicalDeviceCount,
                                                         VkPhysicalDevice *pPhysicalDevices)
{
  SERIALISE_ELEMENT(instance);
  SERIALISE_ELEMENT_LOCAL(PhysicalDeviceIndex, *pPhysicalDeviceCount);
  SERIALISE_ELEMENT_LOCAL(PhysicalDevice, GetResID(*pPhysicalDevices)).TypedAs("VkPhysicalDevice");

  uint32_t memIdxMap[VK_MAX_MEMORY_TYPES] = {0};
  // not used at the moment but useful for reference and might be used
  // in the future
  VkPhysicalDeviceProperties physProps;
  VkPhysicalDeviceMemoryProperties memProps;
  VkPhysicalDeviceFeatures physFeatures;
  uint32_t queueCount = 0;
  VkQueueFamilyProperties queueProps[16];

  if(ser.IsWriting())
  {
    memcpy(memIdxMap, GetRecord(*pPhysicalDevices)->memIdxMap, sizeof(memIdxMap));

    ObjDisp(instance)->GetPhysicalDeviceProperties(Unwrap(*pPhysicalDevices), &physProps);
    ObjDisp(instance)->GetPhysicalDeviceMemoryProperties(Unwrap(*pPhysicalDevices), &memProps);
    ObjDisp(instance)->GetPhysicalDeviceFeatures(Unwrap(*pPhysicalDevices), &physFeatures);

    ObjDisp(instance)->GetPhysicalDeviceQueueFamilyProperties(Unwrap(*pPhysicalDevices),
                                                              &queueCount, NULL);

    if(queueCount > 16)
    {
      RDCWARN("More than 16 queues");
      queueCount = 16;
    }

    ObjDisp(instance)->GetPhysicalDeviceQueueFamilyProperties(Unwrap(*pPhysicalDevices),
                                                              &queueCount, queueProps);
  }

  SERIALISE_ELEMENT(memIdxMap);
  SERIALISE_ELEMENT(physProps);
  SERIALISE_ELEMENT(memProps);
  SERIALISE_ELEMENT(physFeatures);
  SERIALISE_ELEMENT(queueCount);
  SERIALISE_ELEMENT(queueProps);

  VkPhysicalDevice pd = VK_NULL_HANDLE;

  SERIALISE_CHECK_READ_ERRORS();

  if(IsReplayingAndReading())
  {
    {
      VkDriverInfo capturedVersion(physProps);

      RDCLOG("Captured log describes physical device %u:", PhysicalDeviceIndex);
      RDCLOG("   - %s (ver %u.%u patch 0x%x) - %04x:%04x", physProps.deviceName,
             capturedVersion.Major(), capturedVersion.Minor(), capturedVersion.Patch(),
             physProps.vendorID, physProps.deviceID);

      if(PhysicalDeviceIndex >= m_OriginalPhysicalDevices.size())
        m_OriginalPhysicalDevices.resize(PhysicalDeviceIndex + 1);

      m_OriginalPhysicalDevices[PhysicalDeviceIndex].props = physProps;
      m_OriginalPhysicalDevices[PhysicalDeviceIndex].memProps = memProps;
      m_OriginalPhysicalDevices[PhysicalDeviceIndex].features = physFeatures;
    }

    // match up physical devices to those available on replay as best as possible. In general
    // hopefully the most common case is when there's a precise match, and maybe the order changed.
    //
    // If more GPUs were present on replay than during capture, we map many-to-one which might have
    // bad side-effects as e.g. we have to pick one memidxmap, but this is as good as we can do.

    uint32_t bestIdx = 0;
    VkPhysicalDeviceProperties bestPhysProps;
    VkPhysicalDeviceMemoryProperties bestMemProps;

    pd = m_ReplayPhysicalDevices[bestIdx];

    ObjDisp(pd)->GetPhysicalDeviceProperties(Unwrap(pd), &bestPhysProps);
    ObjDisp(pd)->GetPhysicalDeviceMemoryProperties(Unwrap(pd), &bestMemProps);

    for(uint32_t i = 1; i < (uint32_t)m_ReplayPhysicalDevices.size(); i++)
    {
      VkPhysicalDeviceProperties compPhysProps;
      VkPhysicalDeviceMemoryProperties compMemProps;

      pd = m_ReplayPhysicalDevices[i];

      // find the best possible match for this physical device
      ObjDisp(pd)->GetPhysicalDeviceProperties(Unwrap(pd), &compPhysProps);
      ObjDisp(pd)->GetPhysicalDeviceMemoryProperties(Unwrap(pd), &compMemProps);

      // an exact vendorID match is a better match than not
      if(compPhysProps.vendorID == physProps.vendorID && bestPhysProps.vendorID != physProps.vendorID)
      {
        bestIdx = i;
        bestPhysProps = compPhysProps;
        bestMemProps = compMemProps;
        continue;
      }
      else if(compPhysProps.vendorID != physProps.vendorID)
      {
        continue;
      }

      // ditto deviceID
      if(compPhysProps.deviceID == physProps.deviceID && bestPhysProps.deviceID != physProps.deviceID)
      {
        bestIdx = i;
        bestPhysProps = compPhysProps;
        bestMemProps = compMemProps;
        continue;
      }
      else if(compPhysProps.deviceID != physProps.deviceID)
      {
        continue;
      }

      // if we have multiple identical devices, which isn't uncommon, favour the one
      // that hasn't been assigned
      if(m_ReplayPhysicalDevicesUsed[bestIdx] && !m_ReplayPhysicalDevicesUsed[i])
      {
        bestIdx = i;
        bestPhysProps = compPhysProps;
        bestMemProps = compMemProps;
        continue;
      }

      // this device isn't any better, ignore it
    }

    {
      VkDriverInfo runningVersion(bestPhysProps);

      RDCLOG("Mapping during replay to physical device %u:", bestIdx);
      RDCLOG("   - %s (ver %u.%u patch 0x%x) - %04x:%04x", bestPhysProps.deviceName,
             runningVersion.Major(), runningVersion.Minor(), runningVersion.Patch(),
             bestPhysProps.vendorID, bestPhysProps.deviceID);
    }

    pd = m_ReplayPhysicalDevices[bestIdx];

    if(!m_ReplayPhysicalDevicesUsed[bestIdx])
      GetResourceManager()->AddLiveResource(PhysicalDevice, pd);
    else
      GetResourceManager()->ReplaceResource(PhysicalDevice,
                                            GetResourceManager()->GetOriginalID(GetResID(pd)));

    AddResource(PhysicalDevice, ResourceType::Device, "Physical Device");
    DerivedResource(m_Instance, PhysicalDevice);

    if(PhysicalDeviceIndex >= m_PhysicalDevices.size())
      m_PhysicalDevices.resize(PhysicalDeviceIndex + 1);
    m_PhysicalDevices[PhysicalDeviceIndex] = pd;

    if(m_ReplayPhysicalDevicesUsed[bestIdx])
    {
      // error if we're remapping multiple physical devices to the same best match
      RDCERR(
          "Mapping multiple capture-time physical devices to a single replay-time physical device."
          "This means the HW has changed between capture and replay and may cause bugs.");
    }
    else if(m_MemIdxMaps[bestIdx] == NULL)
    {
      // the first physical device 'wins' for the memory index map
      uint32_t *storedMap = new uint32_t[32];
      memcpy(storedMap, memIdxMap, sizeof(memIdxMap));

      for(uint32_t i = 0; i < 32; i++)
        storedMap[i] = i;

      m_MemIdxMaps[bestIdx] = storedMap;
    }

    m_ReplayPhysicalDevicesUsed[bestIdx] = true;
  }

  return true;
}

VkResult WrappedVulkan::vkEnumeratePhysicalDevices(VkInstance instance,
                                                   uint32_t *pPhysicalDeviceCount,
                                                   VkPhysicalDevice *pPhysicalDevices)
{
  uint32_t count;

  VkResult vkr = ObjDisp(instance)->EnumeratePhysicalDevices(Unwrap(instance), &count, NULL);

  if(vkr != VK_SUCCESS)
    return vkr;

  VkPhysicalDevice *devices = new VkPhysicalDevice[count];

  SERIALISE_TIME_CALL(
      vkr = ObjDisp(instance)->EnumeratePhysicalDevices(Unwrap(instance), &count, devices));
  RDCASSERTEQUAL(vkr, VK_SUCCESS);

  m_PhysicalDevices.resize(count);
  m_SupportedQueueFamilies.resize(count);

  for(uint32_t i = 0; i < count; i++)
  {
    // it's perfectly valid for enumerate type functions to return the same handle
    // each time. If that happens, we will already have a wrapper created so just
    // return the wrapped object to the user and do nothing else
    if(m_PhysicalDevices[i] != VK_NULL_HANDLE)
    {
      GetWrapped(m_PhysicalDevices[i])->RewrapObject(devices[i]);
      devices[i] = m_PhysicalDevices[i];
    }
    else
    {
      GetResourceManager()->WrapResource(instance, devices[i]);

      if(IsCaptureMode(m_State))
      {
        // add the record first since it's used in the serialise function below to fetch
        // the memory indices
        VkResourceRecord *record = GetResourceManager()->AddResourceRecord(devices[i]);
        RDCASSERT(record);

        record->memProps = new VkPhysicalDeviceMemoryProperties();

        ObjDisp(devices[i])->GetPhysicalDeviceMemoryProperties(Unwrap(devices[i]), record->memProps);

        m_PhysicalDevices[i] = devices[i];

        // we remap memory indices to discourage coherent maps as much as possible
        RemapMemoryIndices(record->memProps, &record->memIdxMap);

        {
          CACHE_THREAD_SERIALISER();

          SCOPED_SERIALISE_CHUNK(VulkanChunk::vkEnumeratePhysicalDevices);
          Serialise_vkEnumeratePhysicalDevices(ser, instance, &i, &devices[i]);

          record->AddChunk(scope.Get());
        }

        VkResourceRecord *instrecord = GetRecord(instance);

        instrecord->AddParent(record);

        // treat physical devices as pool members of the instance (ie. freed when the instance dies)
        {
          instrecord->LockChunks();
          instrecord->pooledChildren.push_back(record);
          instrecord->UnlockChunks();
        }
      }
    }

    // find the queue with the most bits set and only report that one

    {
      uint32_t queuecount = 0;
      ObjDisp(m_PhysicalDevices[i])
          ->GetPhysicalDeviceQueueFamilyProperties(Unwrap(m_PhysicalDevices[i]), &queuecount, NULL);

      VkQueueFamilyProperties *props = new VkQueueFamilyProperties[queuecount];
      ObjDisp(m_PhysicalDevices[i])
          ->GetPhysicalDeviceQueueFamilyProperties(Unwrap(m_PhysicalDevices[i]), &queuecount, props);

      uint32_t best = 0;

      // don't need to explicitly check for transfer, because graphics bit
      // implies it. We do have to check for compute bit, because there might
      // be a graphics only queue - it just means we have to keep looking
      // to find the grpahics & compute queue family which is guaranteed.
      for(uint32_t q = 1; q < queuecount; q++)
      {
        // compare current against the known best
        VkQueueFamilyProperties &currentProps = props[q];
        VkQueueFamilyProperties &bestProps = props[best];

        const bool currentGraphics = (currentProps.queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0;
        const bool currentCompute = (currentProps.queueFlags & VK_QUEUE_COMPUTE_BIT) != 0;
        const bool currentSparse = (currentProps.queueFlags & VK_QUEUE_SPARSE_BINDING_BIT) != 0;

        const bool bestGraphics = (bestProps.queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0;
        const bool bestCompute = (bestProps.queueFlags & VK_QUEUE_COMPUTE_BIT) != 0;
        const bool bestSparse = (bestProps.queueFlags & VK_QUEUE_SPARSE_BINDING_BIT) != 0;

        // if one has graphics bit set, but the other doesn't
        if(currentGraphics != bestGraphics)
        {
          // if current has graphics but best doesn't, we have a new best
          if(currentGraphics)
            best = q;
          continue;
        }

        if(currentCompute != bestCompute)
        {
          // if current has compute but best doesn't, we have a new best
          if(currentCompute)
            best = q;
          continue;
        }

        // if we've gotten here, both best and current have graphics and compute. Check
        // to see if the current is somehow better than best (in the case of a tie, we
        // keep the lower index of queue).

        if(currentSparse != bestSparse)
        {
          if(currentSparse)
            best = q;
          continue;
        }

        if(currentProps.timestampValidBits != bestProps.timestampValidBits)
        {
          if(currentProps.timestampValidBits > bestProps.timestampValidBits)
            best = q;
          continue;
        }

        if(currentProps.minImageTransferGranularity.width <
               bestProps.minImageTransferGranularity.width ||
           currentProps.minImageTransferGranularity.height <
               bestProps.minImageTransferGranularity.height ||
           currentProps.minImageTransferGranularity.depth <
               bestProps.minImageTransferGranularity.depth)
        {
          best = q;
          continue;
        }
      }

      // only report a single available queue in this family
      props[best].queueCount = 1;

      m_SupportedQueueFamilies[i] = std::make_pair(best, props[best]);

      SAFE_DELETE_ARRAY(props);
    }
  }

  if(pPhysicalDeviceCount)
    *pPhysicalDeviceCount = count;
  if(pPhysicalDevices)
    memcpy(pPhysicalDevices, devices, count * sizeof(VkPhysicalDevice));

  SAFE_DELETE_ARRAY(devices);

  return VK_SUCCESS;
}

template <typename SerialiserType>
bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevice physicalDevice,
                                             const VkDeviceCreateInfo *pCreateInfo,
                                             const VkAllocationCallbacks *pAllocator,
                                             VkDevice *pDevice)
{
  SERIALISE_ELEMENT(physicalDevice);
  SERIALISE_ELEMENT_LOCAL(CreateInfo, *pCreateInfo);
  SERIALISE_ELEMENT_OPT(pAllocator);
  SERIALISE_ELEMENT_LOCAL(Device, GetResID(*pDevice)).TypedAs("VkDevice");
  SERIALISE_ELEMENT(m_SupportedQueueFamily).Hidden();

  SERIALISE_CHECK_READ_ERRORS();

  if(IsReplayingAndReading())
  {
    // we must make any modifications locally, so the free of pointers
    // in the serialised VkDeviceCreateInfo don't double-free
    VkDeviceCreateInfo createInfo = CreateInfo;

    std::vector<string> Extensions;
    for(uint32_t i = 0; i < createInfo.enabledExtensionCount; i++)
    {
      // don't include the debug marker extension
      if(!strcmp(createInfo.ppEnabledExtensionNames[i], VK_EXT_DEBUG_MARKER_EXTENSION_NAME))
        continue;

      // don't include direct-display WSI extensions
      if(!strcmp(createInfo.ppEnabledExtensionNames[i], VK_KHR_DISPLAY_SWAPCHAIN_EXTENSION_NAME) ||
         !strcmp(createInfo.ppEnabledExtensionNames[i], VK_EXT_DISPLAY_CONTROL_EXTENSION_NAME))
        continue;

      Extensions.push_back(createInfo.ppEnabledExtensionNames[i]);
    }

    if(std::find(Extensions.begin(), Extensions.end(),
                 VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_EXTENSION_NAME) != Extensions.end())
      m_ExtensionsEnabled[VkCheckExt_AMD_neg_viewport] = true;

    std::vector<string> Layers;
    for(uint32_t i = 0; i < createInfo.enabledLayerCount; i++)
      Layers.push_back(createInfo.ppEnabledLayerNames[i]);

    StripUnwantedLayers(Layers);

    std::set<string> supportedExtensions;

    for(size_t i = 0; i <= Layers.size(); i++)
    {
      const char *pLayerName = (i == 0 ? NULL : Layers[i - 1].c_str());

      uint32_t count = 0;
      ObjDisp(physicalDevice)
          ->EnumerateDeviceExtensionProperties(Unwrap(physicalDevice), pLayerName, &count, NULL);

      VkExtensionProperties *props = new VkExtensionProperties[count];
      ObjDisp(physicalDevice)
          ->EnumerateDeviceExtensionProperties(Unwrap(physicalDevice), pLayerName, &count, props);

      for(uint32_t e = 0; e < count; e++)
        supportedExtensions.insert(props[e].extensionName);

      SAFE_DELETE_ARRAY(props);
    }

    AddRequiredExtensions(false, Extensions, supportedExtensions);

    // enable VK_EXT_debug_marker if it's available, to replay markers to the driver/any other
    // layers that might be listening
    if(supportedExtensions.find(VK_EXT_DEBUG_MARKER_EXTENSION_NAME) != supportedExtensions.end())
    {
      Extensions.push_back(VK_EXT_DEBUG_MARKER_EXTENSION_NAME);
      RDCLOG("Enabling VK_EXT_debug_marker");
    }

    // enable VK_EXT_debug_marker if it's available, to fetch shader disassembly
    if(supportedExtensions.find(VK_AMD_SHADER_INFO_EXTENSION_NAME) != supportedExtensions.end())
    {
      Extensions.push_back(VK_AMD_SHADER_INFO_EXTENSION_NAME);
      RDCLOG("Enabling VK_AMD_shader_info");
    }

    createInfo.enabledLayerCount = (uint32_t)Layers.size();

    const char **layerArray = NULL;
    if(!Layers.empty())
    {
      layerArray = new const char *[createInfo.enabledLayerCount];

      for(uint32_t i = 0; i < createInfo.enabledLayerCount; i++)
        layerArray[i] = Layers[i].c_str();

      createInfo.ppEnabledLayerNames = layerArray;
    }

    createInfo.enabledExtensionCount = (uint32_t)Extensions.size();

    const char **extArray = NULL;
    if(!Extensions.empty())
    {
      extArray = new const char *[createInfo.enabledExtensionCount];

      for(uint32_t i = 0; i < createInfo.enabledExtensionCount; i++)
        extArray[i] = Extensions[i].c_str();

      createInfo.ppEnabledExtensionNames = extArray;
    }

    VkDevice device;

    uint32_t qCount = 0;
    ObjDisp(physicalDevice)->GetPhysicalDeviceQueueFamilyProperties(Unwrap(physicalDevice), &qCount, NULL);

    VkQueueFamilyProperties *props = new VkQueueFamilyProperties[qCount];
    ObjDisp(physicalDevice)
        ->GetPhysicalDeviceQueueFamilyProperties(Unwrap(physicalDevice), &qCount, props);

    bool found = false;
    uint32_t qFamilyIdx = 0;
    VkQueueFlags search = (VK_QUEUE_GRAPHICS_BIT);

    // for queue priorities, if we need it
    float one = 1.0f;

    // if we need to change the requested queues, it will point to this
    VkDeviceQueueCreateInfo *modQueues = NULL;

    for(uint32_t i = 0; i < createInfo.queueCreateInfoCount; i++)
    {
      uint32_t idx = createInfo.pQueueCreateInfos[i].queueFamilyIndex;
      RDCASSERT(idx < qCount);

      // this requested queue is one we can use too
      if((props[idx].queueFlags & search) == search && createInfo.pQueueCreateInfos[i].queueCount > 0)
      {
        qFamilyIdx = idx;
        found = true;
        break;
      }
    }

    // if we didn't find it, search for which queue family we should add a request for
    if(!found)
    {
      RDCDEBUG("App didn't request a queue family we can use - adding our own");

      for(uint32_t i = 0; i < qCount; i++)
      {
        if((props[i].queueFlags & search) == search)
        {
          qFamilyIdx = i;
          found = true;
          break;
        }
      }

      if(!found)
      {
        SAFE_DELETE_ARRAY(props);
        RDCERR(
            "Can't add a queue with required properties for RenderDoc! Unsupported configuration");
      }
      else
      {
        // we found the queue family, add it
        modQueues = new VkDeviceQueueCreateInfo[createInfo.queueCreateInfoCount + 1];
        for(uint32_t i = 0; i < createInfo.queueCreateInfoCount; i++)
          modQueues[i] = createInfo.pQueueCreateInfos[i];

        modQueues[createInfo.queueCreateInfoCount].queueFamilyIndex = qFamilyIdx;
        modQueues[createInfo.queueCreateInfoCount].queueCount = 1;
        modQueues[createInfo.queueCreateInfoCount].pQueuePriorities = &one;

        createInfo.pQueueCreateInfos = modQueues;
        createInfo.queueCreateInfoCount++;
      }
    }

    SAFE_DELETE_ARRAY(props);

    VkPhysicalDeviceFeatures enabledFeatures = {0};
    if(createInfo.pEnabledFeatures != NULL)
      enabledFeatures = *createInfo.pEnabledFeatures;
    createInfo.pEnabledFeatures = &enabledFeatures;

    VkPhysicalDeviceFeatures availFeatures = {0};
    ObjDisp(physicalDevice)->GetPhysicalDeviceFeatures(Unwrap(physicalDevice), &availFeatures);

    if(availFeatures.depthClamp)
      enabledFeatures.depthClamp = true;
    else
      RDCWARN(
          "depthClamp = false, overlays like highlight drawcall won't show depth-clipped pixels.");

    if(availFeatures.fillModeNonSolid)
      enabledFeatures.fillModeNonSolid = true;

    // we have a fallback for this case, so no warning

    if(availFeatures.geometryShader)
      enabledFeatures.geometryShader = true;
    else
      RDCWARN(
          "geometryShader = false, lit mesh rendering will not be available if rendering on this "
          "device.");

    if(availFeatures.robustBufferAccess)
      enabledFeatures.robustBufferAccess = true;
    else
      RDCWARN(
          "robustBufferAccess = false, out of bounds access due to bugs in application or "
          "RenderDoc may cause crashes");

    if(availFeatures.shaderStorageImageWriteWithoutFormat)
      enabledFeatures.shaderStorageImageWriteWithoutFormat = true;
    else
      RDCWARN(
          "shaderStorageImageWriteWithoutFormat = false, save/load from 2DMS textures will not be "
          "possible");

    if(availFeatures.shaderStorageImageMultisample)
      enabledFeatures.shaderStorageImageMultisample = true;
    else
      RDCWARN(
          "shaderStorageImageMultisample = false, save/load from 2DMS textures will not be "
          "possible");

    if(availFeatures.sampleRateShading)
      enabledFeatures.sampleRateShading = true;
    else
      RDCWARN(
          "sampleRateShading = false, save/load from depth 2DMS textures will not be "
          "possible");

    uint32_t numExts = 0;

    VkResult vkr =
        ObjDisp(physicalDevice)
            ->EnumerateDeviceExtensionProperties(Unwrap(physicalDevice), NULL, &numExts, NULL);
    RDCASSERTEQUAL(vkr, VK_SUCCESS);

    VkExtensionProperties *exts = new VkExtensionProperties[numExts];

    vkr = ObjDisp(physicalDevice)
              ->EnumerateDeviceExtensionProperties(Unwrap(physicalDevice), NULL, &numExts, exts);
    RDCASSERTEQUAL(vkr, VK_SUCCESS);

    for(uint32_t i = 0; i < numExts; i++)
      RDCLOG("Ext %u: %s (%u)", i, exts[i].extensionName, exts[i].specVersion);

    SAFE_DELETE_ARRAY(exts);

    // PORTABILITY check that extensions and layers supported in capture (from createInfo) are
    // supported in replay

    vkr = GetDeviceDispatchTable(NULL)->CreateDevice(Unwrap(physicalDevice), &createInfo, NULL,
                                                     &device);
    RDCASSERTEQUAL(vkr, VK_SUCCESS);

    GetResourceManager()->WrapResource(device, device);
    GetResourceManager()->AddLiveResource(Device, device);

    AddResource(Device, ResourceType::Device, "Device");
    DerivedResource(physicalDevice, Device);

    InstanceDeviceInfo extInfo;

#undef CheckExt
#define CheckExt(name)                                      \
  if(!strcmp(createInfo.ppEnabledExtensionNames[i], #name)) \
  {                                                         \
    extInfo.ext_##name = true;                              \
  }

    for(uint32_t i = 0; i < createInfo.enabledExtensionCount; i++)
    {
      CheckDeviceExts();
    }

    InitDeviceExtensionTables(device, &extInfo);

    RDCASSERT(m_Device == VK_NULL_HANDLE);    // MULTIDEVICE

    m_PhysicalDevice = physicalDevice;
    m_Device = device;

    m_QueueFamilyIdx = qFamilyIdx;

    if(m_InternalCmds.cmdpool == VK_NULL_HANDLE)
    {
      VkCommandPoolCreateInfo poolInfo = {VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, NULL,
                                          VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
                                          qFamilyIdx};
      vkr = ObjDisp(device)->CreateCommandPool(Unwrap(device), &poolInfo, NULL,
                                               &m_InternalCmds.cmdpool);
      RDCASSERTEQUAL(vkr, VK_SUCCESS);

      GetResourceManager()->WrapResource(Unwrap(device), m_InternalCmds.cmdpool);
    }

    ObjDisp(physicalDevice)
        ->GetPhysicalDeviceProperties(Unwrap(physicalDevice), &m_PhysicalDeviceData.props);

    ObjDisp(physicalDevice)
        ->GetPhysicalDeviceMemoryProperties(Unwrap(physicalDevice), &m_PhysicalDeviceData.memProps);

    ObjDisp(physicalDevice)
        ->GetPhysicalDeviceFeatures(Unwrap(physicalDevice), &m_PhysicalDeviceData.features);

    for(int i = VK_FORMAT_BEGIN_RANGE + 1; i < VK_FORMAT_END_RANGE; i++)
      ObjDisp(physicalDevice)
          ->GetPhysicalDeviceFormatProperties(Unwrap(physicalDevice), VkFormat(i),
                                              &m_PhysicalDeviceData.fmtprops[i]);

    m_PhysicalDeviceData.readbackMemIndex =
        m_PhysicalDeviceData.GetMemoryIndex(~0U, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, 0);
    m_PhysicalDeviceData.uploadMemIndex =
        m_PhysicalDeviceData.GetMemoryIndex(~0U, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, 0);
    m_PhysicalDeviceData.GPULocalMemIndex = m_PhysicalDeviceData.GetMemoryIndex(
        ~0U, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);

    for(size_t i = 0; i < m_PhysicalDevices.size(); i++)
    {
      if(physicalDevice == m_PhysicalDevices[i])
      {
        m_PhysicalDeviceData.memIdxMap = m_MemIdxMaps[i];
        break;
      }
    }

    APIProps.vendor = GetDriverVersion().Vendor();

    m_ShaderCache = new VulkanShaderCache(this);

    m_DebugManager = new VulkanDebugManager(this);

    m_Replay.CreateResources();

    SAFE_DELETE_ARRAY(modQueues);
    SAFE_DELETE_ARRAY(layerArray);
    SAFE_DELETE_ARRAY(extArray);
  }

  return true;
}

VkResult WrappedVulkan::vkCreateDevice(VkPhysicalDevice physicalDevice,
                                       const VkDeviceCreateInfo *pCreateInfo,
                                       const VkAllocationCallbacks *pAllocator, VkDevice *pDevice)
{
  VkDeviceCreateInfo createInfo = *pCreateInfo;

  uint32_t qCount = 0;
  VkResult vkr = VK_SUCCESS;

  ObjDisp(physicalDevice)->GetPhysicalDeviceQueueFamilyProperties(Unwrap(physicalDevice), &qCount, NULL);

  VkQueueFamilyProperties *props = new VkQueueFamilyProperties[qCount];
  ObjDisp(physicalDevice)->GetPhysicalDeviceQueueFamilyProperties(Unwrap(physicalDevice), &qCount, props);

  // find a queue that supports all capabilities, and if one doesn't exist, add it.
  bool found = false;
  uint32_t qFamilyIdx = 0;
  VkQueueFlags search = (VK_QUEUE_GRAPHICS_BIT);

  // for queue priorities, if we need it
  float one = 1.0f;

  // if we need to change the requested queues, it will point to this
  VkDeviceQueueCreateInfo *modQueues = NULL;

  for(uint32_t i = 0; i < createInfo.queueCreateInfoCount; i++)
  {
    uint32_t idx = createInfo.pQueueCreateInfos[i].queueFamilyIndex;
    RDCASSERT(idx < qCount);

    // this requested queue is one we can use too
    if((props[idx].queueFlags & search) == search && createInfo.pQueueCreateInfos[i].queueCount > 0)
    {
      qFamilyIdx = idx;
      found = true;
      break;
    }
  }

  // if we didn't find it, search for which queue family we should add a request for
  if(!found)
  {
    RDCDEBUG("App didn't request a queue family we can use - adding our own");

    for(uint32_t i = 0; i < qCount; i++)
    {
      if((props[i].queueFlags & search) == search)
      {
        qFamilyIdx = i;
        found = true;
        break;
      }
    }

    if(!found)
    {
      SAFE_DELETE_ARRAY(props);
      RDCERR("Can't add a queue with required properties for RenderDoc! Unsupported configuration");
      return VK_ERROR_INITIALIZATION_FAILED;
    }

    // we found the queue family, add it
    modQueues = new VkDeviceQueueCreateInfo[createInfo.queueCreateInfoCount + 1];
    for(uint32_t i = 0; i < createInfo.queueCreateInfoCount; i++)
      modQueues[i] = createInfo.pQueueCreateInfos[i];

    modQueues[createInfo.queueCreateInfoCount].queueFamilyIndex = qFamilyIdx;
    modQueues[createInfo.queueCreateInfoCount].queueCount = 1;
    modQueues[createInfo.queueCreateInfoCount].pQueuePriorities = &one;

    createInfo.pQueueCreateInfos = modQueues;
    createInfo.queueCreateInfoCount++;
  }

  SAFE_DELETE_ARRAY(props);

  m_QueueFamilies.resize(createInfo.queueCreateInfoCount);
  for(size_t i = 0; i < createInfo.queueCreateInfoCount; i++)
  {
    uint32_t family = createInfo.pQueueCreateInfos[i].queueFamilyIndex;
    uint32_t count = createInfo.pQueueCreateInfos[i].queueCount;
    m_QueueFamilies.resize(RDCMAX(m_QueueFamilies.size(), size_t(family + 1)));

    m_QueueFamilies[family] = new VkQueue[count];
    for(uint32_t q = 0; q < count; q++)
      m_QueueFamilies[family][q] = VK_NULL_HANDLE;
  }

  // find the matching physical device
  for(size_t i = 0; i < m_PhysicalDevices.size(); i++)
    if(m_PhysicalDevices[i] == physicalDevice)
      m_SupportedQueueFamily = m_SupportedQueueFamilies[i].first;

  VkLayerDeviceCreateInfo *layerCreateInfo = (VkLayerDeviceCreateInfo *)pCreateInfo->pNext;

  // step through the chain of pNext until we get to the link info
  while(layerCreateInfo && (layerCreateInfo->sType != VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO ||
                            layerCreateInfo->function != VK_LAYER_LINK_INFO))
  {
    layerCreateInfo = (VkLayerDeviceCreateInfo *)layerCreateInfo->pNext;
  }
  RDCASSERT(layerCreateInfo);

  if(layerCreateInfo == NULL)
  {
    RDCERR("Couldn't find loader device create info, which is required. Incompatible loader?");
    return VK_ERROR_INITIALIZATION_FAILED;
  }

  PFN_vkGetDeviceProcAddr gdpa = layerCreateInfo->u.pLayerInfo->pfnNextGetDeviceProcAddr;
  PFN_vkGetInstanceProcAddr gipa = layerCreateInfo->u.pLayerInfo->pfnNextGetInstanceProcAddr;
  // move chain on for next layer
  layerCreateInfo->u.pLayerInfo = layerCreateInfo->u.pLayerInfo->pNext;

  PFN_vkCreateDevice createFunc = (PFN_vkCreateDevice)gipa(VK_NULL_HANDLE, "vkCreateDevice");

  // now search again through for the loader data callback (if it exists)
  layerCreateInfo = (VkLayerDeviceCreateInfo *)pCreateInfo->pNext;

  // step through the chain of pNext
  while(layerCreateInfo && (layerCreateInfo->sType != VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO ||
                            layerCreateInfo->function != VK_LOADER_DATA_CALLBACK))
  {
    layerCreateInfo = (VkLayerDeviceCreateInfo *)layerCreateInfo->pNext;
  }

  // if we found one (we might not - on old loaders), then store the func ptr for
  // use instead of SetDispatchTableOverMagicNumber
  if(layerCreateInfo)
  {
    RDCASSERT(m_SetDeviceLoaderData == layerCreateInfo->u.pfnSetDeviceLoaderData ||
                  m_SetDeviceLoaderData == NULL,
              (void *)m_SetDeviceLoaderData, (void *)layerCreateInfo->u.pfnSetDeviceLoaderData);
    m_SetDeviceLoaderData = layerCreateInfo->u.pfnSetDeviceLoaderData;
  }

  // patch enabled features

  VkPhysicalDeviceFeatures availFeatures;

  ObjDisp(physicalDevice)->GetPhysicalDeviceFeatures(Unwrap(physicalDevice), &availFeatures);

  // default to all off. This is equivalent to createInfo.pEnabledFeatures == NULL
  VkPhysicalDeviceFeatures enabledFeatures = {0};

  // if the user enabled features, of course we want to enable them.
  if(createInfo.pEnabledFeatures)
    enabledFeatures = *createInfo.pEnabledFeatures;

  if(availFeatures.shaderStorageImageWriteWithoutFormat)
    enabledFeatures.shaderStorageImageWriteWithoutFormat = true;
  else
    RDCWARN(
        "shaderStorageImageWriteWithoutFormat = false, save/load from 2DMS textures will not be "
        "possible");

  if(availFeatures.shaderStorageImageMultisample)
    enabledFeatures.shaderStorageImageMultisample = true;
  else
    RDCWARN(
        "shaderStorageImageMultisample = false, save/load from 2DMS textures will not be "
        "possible");

  if(availFeatures.sampleRateShading)
    enabledFeatures.sampleRateShading = true;
  else
    RDCWARN(
        "sampleRateShading = false, save/load from depth 2DMS textures will not be "
        "possible");

  if(availFeatures.occlusionQueryPrecise)
    enabledFeatures.occlusionQueryPrecise = true;
  else
    RDCWARN("occlusionQueryPrecise = false, samples written counter will not work");

  if(availFeatures.pipelineStatisticsQuery)
    enabledFeatures.pipelineStatisticsQuery = true;
  else
    RDCWARN("pipelineStatisticsQuery = false, pipeline counters will not work");

  createInfo.pEnabledFeatures = &enabledFeatures;

  VkResult ret;
  SERIALISE_TIME_CALL(ret = createFunc(Unwrap(physicalDevice), &createInfo, pAllocator, pDevice));

  // don't serialise out any of the pNext stuff for layer initialisation
  // (note that we asserted above that there was nothing else in the chain)
  createInfo.pNext = NULL;

  if(ret == VK_SUCCESS)
  {
    InitDeviceTable(*pDevice, gdpa);

    ResourceId id = GetResourceManager()->WrapResource(*pDevice, *pDevice);

    if(IsCaptureMode(m_State))
    {
      Chunk *chunk = NULL;

      {
        CACHE_THREAD_SERIALISER();

        SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCreateDevice);
        Serialise_vkCreateDevice(ser, physicalDevice, &createInfo, NULL, pDevice);

        chunk = scope.Get();
      }

      VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pDevice);
      RDCASSERT(record);

      record->AddChunk(chunk);

      record->memIdxMap = GetRecord(physicalDevice)->memIdxMap;

      record->instDevInfo = new InstanceDeviceInfo();

#undef CheckExt
#define CheckExt(name) \
  record->instDevInfo->ext_##name = GetRecord(m_Instance)->instDevInfo->ext_##name;

      // inherit extension enablement from instance, that way GetDeviceProcAddress can check
      // for enabled extensions for instance functions
      CheckInstanceExts();

#undef CheckExt
#define CheckExt(name)                                      \
  if(!strcmp(createInfo.ppEnabledExtensionNames[i], #name)) \
  {                                                         \
    record->instDevInfo->ext_##name = true;                 \
  }

      for(uint32_t i = 0; i < createInfo.enabledExtensionCount; i++)
      {
        CheckDeviceExts();
      }

      InitDeviceExtensionTables(*pDevice, record->instDevInfo);
    }
    else
    {
      GetResourceManager()->AddLiveResource(id, *pDevice);
    }

    VkDevice device = *pDevice;

    RDCASSERT(m_Device == VK_NULL_HANDLE);    // MULTIDEVICE

    m_PhysicalDevice = physicalDevice;
    m_Device = device;

    m_QueueFamilyIdx = qFamilyIdx;

    if(m_InternalCmds.cmdpool == VK_NULL_HANDLE)
    {
      VkCommandPoolCreateInfo poolInfo = {VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, NULL,
                                          VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
                                          qFamilyIdx};
      vkr = ObjDisp(device)->CreateCommandPool(Unwrap(device), &poolInfo, NULL,
                                               &m_InternalCmds.cmdpool);
      RDCASSERTEQUAL(vkr, VK_SUCCESS);

      GetResourceManager()->WrapResource(Unwrap(device), m_InternalCmds.cmdpool);
    }

    ObjDisp(physicalDevice)
        ->GetPhysicalDeviceProperties(Unwrap(physicalDevice), &m_PhysicalDeviceData.props);

    ObjDisp(physicalDevice)
        ->GetPhysicalDeviceMemoryProperties(Unwrap(physicalDevice), &m_PhysicalDeviceData.memProps);

    ObjDisp(physicalDevice)
        ->GetPhysicalDeviceFeatures(Unwrap(physicalDevice), &m_PhysicalDeviceData.features);

    for(int i = VK_FORMAT_BEGIN_RANGE + 1; i < VK_FORMAT_END_RANGE; i++)
      ObjDisp(physicalDevice)
          ->GetPhysicalDeviceFormatProperties(Unwrap(physicalDevice), VkFormat(i),
                                              &m_PhysicalDeviceData.fmtprops[i]);

    m_PhysicalDeviceData.readbackMemIndex =
        m_PhysicalDeviceData.GetMemoryIndex(~0U, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, 0);
    m_PhysicalDeviceData.uploadMemIndex =
        m_PhysicalDeviceData.GetMemoryIndex(~0U, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, 0);
    m_PhysicalDeviceData.GPULocalMemIndex = m_PhysicalDeviceData.GetMemoryIndex(
        ~0U, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);

    m_PhysicalDeviceData.fakeMemProps = GetRecord(physicalDevice)->memProps;

    m_ShaderCache = new VulkanShaderCache(this);

    m_TextRenderer = new VulkanTextRenderer(this);

    m_DebugManager = new VulkanDebugManager(this);
  }

  SAFE_DELETE_ARRAY(modQueues);

  return ret;
}

void WrappedVulkan::vkDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator)
{
  // flush out any pending commands/semaphores
  SubmitCmds();
  SubmitSemaphores();
  FlushQ();

  // MULTIDEVICE this function will need to check if the device is the one we
  // used for debugmanager/cmd pool etc, and only remove child queues and
  // resources (instead of doing full resource manager shutdown).
  // Or will we have a debug manager per-device?
  RDCASSERT(m_Device == device);

  // delete all debug manager objects
  SAFE_DELETE(m_DebugManager);
  SAFE_DELETE(m_ShaderCache);
  SAFE_DELETE(m_TextRenderer);

  // since we didn't create proper registered resources for our command buffers,
  // they won't be taken down properly with the pool. So we release them (just our
  // data) here.
  for(size_t i = 0; i < m_InternalCmds.freecmds.size(); i++)
    GetResourceManager()->ReleaseWrappedResource(m_InternalCmds.freecmds[i]);

  // destroy our command pool
  if(m_InternalCmds.cmdpool != VK_NULL_HANDLE)
  {
    ObjDisp(m_Device)->DestroyCommandPool(Unwrap(m_Device), Unwrap(m_InternalCmds.cmdpool), NULL);
    GetResourceManager()->ReleaseWrappedResource(m_InternalCmds.cmdpool);
  }

  for(size_t i = 0; i < m_InternalCmds.freesems.size(); i++)
  {
    ObjDisp(m_Device)->DestroySemaphore(Unwrap(m_Device), Unwrap(m_InternalCmds.freesems[i]), NULL);
    GetResourceManager()->ReleaseWrappedResource(m_InternalCmds.freesems[i]);
  }

  m_InternalCmds.Reset();

  m_QueueFamilyIdx = ~0U;
  m_Queue = VK_NULL_HANDLE;

  // destroy the API device immediately. There should be no more
  // resources left in the resource manager device/physical device/instance.
  // Anything we created should be gone and anything the application created
  // should be deleted by now.
  // If there were any leaks, we will leak them ourselves in vkDestroyInstance
  // rather than try to delete API objects after the device has gone
  ObjDisp(m_Device)->DestroyDevice(Unwrap(m_Device), pAllocator);
  GetResourceManager()->ReleaseWrappedResource(m_Device);
  m_Device = VK_NULL_HANDLE;
  m_PhysicalDevice = VK_NULL_HANDLE;
}

template <typename SerialiserType>
bool WrappedVulkan::Serialise_vkDeviceWaitIdle(SerialiserType &ser, VkDevice device)
{
  SERIALISE_ELEMENT(device);

  SERIALISE_CHECK_READ_ERRORS();

  if(IsReplayingAndReading())
  {
    ObjDisp(device)->DeviceWaitIdle(Unwrap(device));
  }

  return true;
}

VkResult WrappedVulkan::vkDeviceWaitIdle(VkDevice device)
{
  VkResult ret;
  SERIALISE_TIME_CALL(ret = ObjDisp(device)->DeviceWaitIdle(Unwrap(device)));

  if(IsActiveCapturing(m_State))
  {
    CACHE_THREAD_SERIALISER();

    SCOPED_SERIALISE_CHUNK(VulkanChunk::vkDeviceWaitIdle);
    Serialise_vkDeviceWaitIdle(ser, device);

    m_FrameCaptureRecord->AddChunk(scope.Get());
  }

  return ret;
}

INSTANTIATE_FUNCTION_SERIALISED(VkResult, vkEnumeratePhysicalDevices, VkInstance instance,
                                uint32_t *pPhysicalDeviceCount, VkPhysicalDevice *pPhysicalDevices);

INSTANTIATE_FUNCTION_SERIALISED(VkResult, vkCreateDevice, VkPhysicalDevice physicalDevice,
                                const VkDeviceCreateInfo *pCreateInfo,
                                const VkAllocationCallbacks *pAllocator, VkDevice *pDevice);

INSTANTIATE_FUNCTION_SERIALISED(VkResult, vkDeviceWaitIdle, VkDevice device);


text:
package org.scalastyle.scalariform

import org.junit.Test
import org.scalastyle.file.CheckerTest
import org.scalatest.junit.AssertionsForJUnit

class TodoCommentCheckerTest extends AssertionsForJUnit with CheckerTest {
  val key = "todo.comment"
  val text = "TODO|FIXME"
  val classUnderTest = classOf[TodoCommentChecker]

  @Test def testSourceWithoutTodoComments(): Unit = {
    val source =
      """
        |package foobar
        |
        |/**
        | * Todoy is a misspelling of today
        | */
        |class foobar {
        |  var myField = "one"
        |
        |  // This inline comment contains the word todo
        |  def doSomething(): Unit = {}
        |
        |  // Todoy is a misspelling of today
        |  def doSomethingElse() = ???
        |
        |  // To do this is...
        |  def doNothing() = ???
        |
        |  /*
        |   * Todoy, I'm very bad at spelling today
        |   */
        |   def stillDoNothing() = ???
        |}
      """.stripMargin

    assertErrors(List(), source)
  }

  @Test def testSourceWithTodoComments(): Unit = {
    val source =
      """
        |package foobar
        |
        |class foobar {
        |  // TODO make this a val
        |  var myField = "one"
        |
        |  def doSomething(): Unit = {
        |    // Todo add some logic
        |  }
        |
        |  // ToDo implement this
        |  def doSomethingElse() = ???
        |
        |  def doNothing() = ??? // todo implement this too
        |
        |  def stillDoNothing() = ??? // TODO: implement this too
        |
        |  def nothing() = ??? /* TODO */
        |
        |  /**
        |   * TODO Add some more code
        |   * todo: refactor a little
        |   */
        |
        |   /** TODO reformat */
        |   /* TODO removed all these todos */
        |
        |   val x = "// TODO what about in a string?"
        |}
      """.stripMargin

    assertErrors(
      List(
        columnError(5, 2, List(text)),
        columnError(9, 4, List(text)),
        columnError(12, 2, List(text)),
        columnError(15, 24, List(text)),
        columnError(17, 29, List(text)),
        columnError(19, 22, List(text)),
        columnError(21, 2, List(text)),
        columnError(26, 3, List(text)),
        columnError(27, 3, List(text))
      ),
      source)
  }

  @Test def testSourceWithoutFixmeComments(): Unit = {
    val source =
      """
        |package foobar
        |
        |/**
        | * Fix mechanism is a misspelling of fix mechanism
        | */
        |class foobar {
        |  var myField = "one"
        |
        |  // This inline comment contains the word fixme
        |  def doSomething(): Unit = {}
        |
        |  // Fixmechanism is a misspelling of fix mechanism
        |  def doSomethingElse() = ???
        |
        |  // Fix mechanism...
        |  def doNothing() = ???
        |
        |  /*
        |   * Fix mechanism, I'm very bad at spelling fix mechanism
        |   */
        |   def stillDoNothing() = ???
        |}
      """.stripMargin

    assertErrors(List(), source)
  }

  @Test def testSourceWithFixmeComments(): Unit = {
    val source =
      """
        |package foobar
        |
        |class foobar {
        |  // FIXME make this a val
        |  var myField = "one"
        |
        |  def doSomething(): Unit = {
        |    // Fixme add some logic
        |  }
        |
        |  // FixMe implement this
        |  def doSomethingElse() = ???
        |
        |  def doNothing() = ??? // fixme this too
        |
        |  def stillDoNothing() = ??? // FIXME: this too
        |
        |  def nothing() = ??? /* FIXME */
        |
        |  /**
        |   * FIXME Add some more code
        |   * fixme: refactor a little
        |   */
        |
        |   /** FIXME reformat */
        |   /* FIXME removed all these fixmes */
        |}
      """.stripMargin

    assertErrors(
      List(
        columnError(5, 2, List(text)),
        columnError(9, 4, List(text)),
        columnError(12, 2, List(text)),
        columnError(15, 24, List(text)),
        columnError(17, 29, List(text)),
        columnError(19, 22, List(text)),
        columnError(21, 2, List(text)),
        columnError(26, 3, List(text)),
        columnError(27, 3, List(text))
      ),
      source)
  }

  @Test def testSourceWithAlternativeComments(): Unit = {
    val source =
      """
        |package foobar
        |
        |class foobar {
        |  // AFAIRE make this a val
        |  var myField = "one"
        |
        |  def doSomething(): Unit = {
        |    // afaire add some logic
        |  }
        |
        |  // AFaire implement this
        |  def doSomethingElse() = ???
        |
        |  def doNothing() = ??? // TODO this should be ignore
        |
        |   /** FIXME reformat */
        |}
      """.stripMargin

    val words = "fixme|afaire"
    assertErrors(
      List(
        columnError(5, 2, List(words)),
        columnError(9, 4, List(words)),
        columnError(12, 2, List(words)),
        columnError(17, 3, List(words))
      ),
      source, params = Map("words" -> words))
  }
}

redpajama_set_name: RedPajamaGithub


text:
require './views/base'

module Views
  class FormCorporations < Action
    needs :current_player
    needs :game

    def render_action
      company = game.acting.first
      widget EntityOrder, game: game, entities: game.player_companies
      widget Companies, companies: game.acting

      share_prices = game.share_prices.reject do |share_price|
        share_price.corporation || !company.valid_share_price?(share_price)
      end

      render_info_table company, share_prices

      game_form do
        select name: data('corporation') do
          game.available_corporations.each do |corporation|
            option(value: corporation) { text corporation }
          end
        end

        select name: data('price') do
          share_prices.each do |share_price|
            next if ::Corporation.initial_shares_info(
              company,
              share_price.price
            )[:seed] > current_player.cash

            option(value: share_price.price) { text "$#{share_price.price}" }
          end
        end

        input id: 'form_company', type: 'hidden', name: data('company'), value: company.name
        input id: 'form_submit', type: 'submit', value: 'Form Corporation'
      end if game.can_act? current_player

      render_company_descriptions if game.v2?
    end

    def render_info_table company, share_prices
      div style: table_style do
        div style: inline(display: 'table-row', font_weight: 'bold') do
          render_column 'Price'
          render_column 'Shares Issued'
          render_column 'Money Spent'
          render_column 'Treasury'
        end

        share_prices.each do |share_price|
          price = share_price.price
          info = ::Corporation.initial_shares_info company, price

          div style: inline(display: 'table-row') do
            render_column "$#{share_price.price}"
            render_column "#{info[:num_shares] * 2}"
            render_column "$#{info[:seed]}"
            render_column "$#{info[:cash]}"
          end
        end
      end
    end

    def render_company_descriptions
      div style: table_style do
        div style: inline(display: 'table-row', font_weight: 'bold') do
          render_column 'Company'
          render_column 'Shares'
          render_column 'Super Power'
        end

        klass = ::CorporationV2
        corporations =  klass::CORPORATIONS
          .map { |name| [name, klass.starting_shares(name, game.minor_version), klass.super_power(name)] }
          .sort_by { |name, shares| [shares, name] }

        corporations.each do |name, shares, super_power|
          div style: inline(display: 'table-row') do
            render_column name
            render_column shares
            render_column super_power
          end
        end
      end
    end

    def render_column data
      col_style = inline(
        margin: '5px',
        display: 'table-cell',
        text_align: 'right',
      )
      div(style: col_style) { text data }
    end

    def table_style
      table_style = inline(
        display: 'table',
        width: '320px',
        margin: '5px 0 5px',
      )
    end

  end
end


text:
namespace BibleNote.Domain.Entities
{
    public class VerseEntry
    {
        public int Id { get; set; }

        public long VerseId { get; set; }

        public decimal Weight { get; set; }

        public string Suffix { get; set; }

        public int DocumentParagraphId { get; set; }

        public virtual DocumentParagraph DocumentParagraph { get; set; }
    }
}


text:
/*
 * index.js: Top-level include for the OpenStack identity module
 *
 * (C) 2013 Charlie Robbins, Ken Perkins, Ross Kukulinski & the Contributors.
 *
 */

module.exports = require('./identity');
module.exports.serviceCatalog = require('./serviceCatalog');
module.exports.service = require('./service');
module.exports.ServiceCatalog = module.exports.serviceCatalog.ServiceCatalog;
module.exports.Service = module.exports.service.Service;


text:
[Blog Home](https://startbootstrap.com/templates/blog-home/) is a basic blog homepage HTML starter template for [Bootstrap](https://getbootstrap.com/) created by [Start Bootstrap](https://startbootstrap.com/).

## Preview

[![Blog Home Preview](https://startbootstrap.com/assets/img/screenshots/templates/blog-home.png)](https://startbootstrap.github.io/startbootstrap-blog-home/)

**[View Live Preview](https://startbootstrap.github.io/startbootstrap-blog-home/)**

## Status

[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/StartBootstrap/startbootstrap-blog-home/master/LICENSE)
[![npm version](https://img.shields.io/npm/v/startbootstrap-blog-home.svg)](https://www.npmjs.com/package/startbootstrap-blog-home)
[![Build Status](https://travis-ci.org/StartBootstrap/startbootstrap-blog-home.svg?branch=master)](https://travis-ci.org/StartBootstrap/startbootstrap-blog-home)
[![dependencies Status](https://david-dm.org/StartBootstrap/startbootstrap-blog-home/status.svg)](https://david-dm.org/StartBootstrap/startbootstrap-blog-home)
[![devDependencies Status](https://david-dm.org/StartBootstrap/startbootstrap-blog-home/dev-status.svg)](https://david-dm.org/StartBootstrap/startbootstrap-blog-home?type=dev)

## Download and Installation

To begin using this template, choose one of the following options to get started:

* [Download the latest release on Start Bootstrap](https://startbootstrap.com/templates/blog-home/)
* Install via npm: `npm i startbootstrap-blog-home`
* Clone the repo: `git clone https://github.com/StartBootstrap/startbootstrap-blog-home.git`
* [Fork, Clone, or Download on GitHub](https://github.com/StartBootstrap/startbootstrap-blog-home)

## Usage

### Basic Usage

After downloading, simply edit the HTML and CSS files included with the template in your favorite text editor to make changes. These are the only files you need to worry about, you can ignore everything else! To preview the changes you make to the code, you can open the `index.html` file in your web browser.

### Advanced Usage

After installation, run `npm install` and then run `npm start` which will open up a preview of the template in your default browser, watch for changes to core template files, and live reload the browser when changes are saved. You can view the `gulpfile.js` to see which tasks are included with the dev environment.

You must have npm and Gulp installed globally on your machine in order to use these features.

## Bugs and Issues

Have a bug or an issue with this template? [Open a new issue](https://github.com/StartBootstrap/startbootstrap-blog-home/issues) here on GitHub or leave a comment on the [template overview page at Start Bootstrap](https://startbootstrap.com/templates/blog-home/).

## About

Start Bootstrap is an open source library of free Bootstrap templates and themes. All of the free templates and themes on Start Bootstrap are released under the MIT license, which means you can use them for any purpose, even for commercial projects.

* <https://startbootstrap.com>
* <https://twitter.com/SBootstrap>

Start Bootstrap was created by and is maintained by **[David Miller](http://davidmiller.io/)**.

* <http://davidmiller.io>
* <https://twitter.com/davidmillerskt>
* <https://github.com/davidtmiller>

Start Bootstrap is based on the [Bootstrap](https://getbootstrap.com/) framework created by [Mark Otto](https://twitter.com/mdo) and [Jacob Thorton](https://twitter.com/fat).

## Copyright and License

Copyright 2013-2020 Start Bootstrap LLC. Code released under the [MIT](https://github.com/StartBootstrap/startbootstrap-blog-home/blob/gh-pages/LICENSE) license.


text:
class ChangePriceFormatInNote < ActiveRecord::Migration
  def change
  	rename_column :notes, :price, :price_string
    add_column :notes, :price, :integer

    Note.reset_column_information
    Note.find_each { |c| c.update_attribute(:price, c.price_string) }
    remove_column :notes, :price_string
  end

end


text:
package org.apache.causeway.viewer.commons.model.action;

import java.util.Optional;
import java.util.function.Predicate;

import org.apache.causeway.applib.Identifier;
import org.apache.causeway.applib.annotation.ActionLayout;
import org.apache.causeway.applib.annotation.BookmarkPolicy;
import org.apache.causeway.core.metamodel.facets.object.bookmarkpolicy.BookmarkPolicyFacet;
import org.apache.causeway.core.metamodel.interactions.managed.ActionInteractionHead;
import org.apache.causeway.core.metamodel.interactions.managed.ManagedAction;
import org.apache.causeway.core.metamodel.object.ManagedObject;
import org.apache.causeway.core.metamodel.spec.feature.ObjectAction;
import org.apache.causeway.core.metamodel.util.Facets;
import org.apache.causeway.viewer.commons.model.decorators.DisablingDecorator.DisablingDecorationModel;
import org.apache.causeway.viewer.commons.model.decorators.IconDecorator.FontAwesomeDecorationModel;

import lombok.val;

/**
 * UI mixin for {@link ManagedAction}.
 */
public interface HasManagedAction {

    ManagedAction getManagedAction();

    /**
     * Metamodel of the represented {@link ManagedAction}.
     * @apiNote implementing classes may provide this more directly
     *  than having to conjure up a ManagedAction only to provide its metamodel;
     *  in other words: this is not strictly required but provides optimization opportunities
     */
    ObjectAction getAction();

    /**
     * Action's owner.
     *
     * @apiNote for mixins this is not the target to use on mixin actions
     * instead the logic of resolving the target for action invocation is
     * encapsulated within the {@link ActionInteractionHead}
     */
    default ManagedObject getActionOwner() {
        return getManagedAction().getOwner();
    }

    /**
     * Action's friendly (translated) name.
     */
    default String getFriendlyName() {
        return getManagedAction().getFriendlyName();
    }

    default Optional<String> getDescription() {
        return getManagedAction().getDescription();
    }

    default boolean hasParameters() {
        return getAction().getParameterCount() > 0;
    }

    /**
     * Bookmarkable if the {@link ObjectAction action} has a {@link BookmarkPolicyFacet bookmark} policy
     * of {@link BookmarkPolicy#AS_ROOT root}, and has safe {@link ObjectAction#getSemantics() semantics}.
     */
    default boolean isBookmarkable() {
        val action = getAction();

        return action.getSemantics().isSafeInNature()
                && Facets.bookmarkPolicyMatches(BookmarkPolicy.AS_ROOT::equals)
                    .test(action);
    }

    default Identifier getFeatureIdentifier() {
        return getAction().getFeatureIdentifier();
    }

    // -- UI SPECIFICS

    default Optional<FontAwesomeDecorationModel> getFontAwesomeUiModel() {
        val managedAction = getManagedAction();
        return FontAwesomeDecorationModel.of(ObjectAction.Util.cssClassFaFactoryFor(
                managedAction.getAction(),
                managedAction.getOwner()));
    }

    default Optional<String> getAdditionalCssClass() {
        return Facets.cssClass(getAction(), getActionOwner());
    }

    default ActionLayout.Position getPosition() {
        return ObjectAction.Util.actionLayoutPositionOf(getAction());
    }

    public static <T extends HasManagedAction> Predicate<T> isPositionedAt(
            final ActionLayout.Position position) {
        return a -> a.getPosition() == position;
    }

    default Optional<DisablingDecorationModel> getDisableUiModel() {
        return DisablingDecorationModel.of(getManagedAction().checkUsability()) ;
    }

}


text:
@extends('back.template')

@section('head')

@stop

@section('content')

	@include('back.partials.entete', ['title' => trans('back/medias.dashboard'), 'icone' => 'file-image-o', 'fil' => trans('back/medias.medias')])

@endsection


text:
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision: 334762 $ -->
<!--
  Do NOT translate this file
-->
<versions>

 <function name='KTaglib_Mpeg_File' from='0.0.1'/>
 <function name='KTaglib_Mpeg_File::__construct' from='0.0.1'/>
 <function name='KTaglib_Mpeg_File::getAudioProperties' from='0.0.1'/>
 <function name='KTaglib_Mpeg_File::GetId3v1Tag' from='0.0.1'/>
 <function name='KTaglib_Mpeg_File::getId3v2Tag' from='0.0.1'/>

 <function name='KTaglib_Mpeg_AudioProperties' from='0.0.1'/>
 <function name='KTaglib_Mpeg_AudioProperties::getBitrate' from='0.0.1'/>
 <function name='KTaglib_Mpeg_AudioProperties::getChannels' from='0.0.1'/>
 <function name='KTaglib_Mpeg_AudioProperties::getLayer' from='0.0.1'/>
 <function name='KTaglib_Mpeg_AudioProperties::getLength' from='0.0.1'/>
 <function name='KTaglib_Mpeg_AudioProperties::getSampleBitrate' from='0.0.1'/>
 <function name='KTaglib_Mpeg_AudioProperties::getVersion' from='0.0.1'/>
 <function name='KTaglib_Mpeg_AudioProperties::isCopyrighted' from='0.0.1'/>
 <function name='KTaglib_Mpeg_AudioProperties::isOriginal' from='0.0.1'/>
 <function name='KTaglib_Mpeg_AudioProperties::isProtectionEnabled' from='0.0.1'/>

 <function name='KTaglib_Tag' from='0.0.1'/>
 <function name='KTaglib_Tag::getAlbum' from='0.0.1'/>
 <function name='KTaglib_Tag::getArtist' from='0.0.1'/>
 <function name='KTaglib_Tag::getComment' from='0.0.1'/>
 <function name='KTaglib_Tag::getGenre' from='0.0.1'/>
 <function name='KTaglib_Tag::getTitle' from='0.0.1'/>
 <function name='KTaglib_Tag::getTrack' from='0.0.1'/>
 <function name='KTaglib_Tag::getYear' from='0.0.1'/>
 <function name='KTaglib_Tag::isEmpty' from='0.0.1'/>

 <function name='KTaglib_ID3v2_Tag' from='0.0.1'/>
 <function name='KTaglib_ID3v2_Tag::addFrame' from='0.0.1'/>
 <function name='KTaglib_ID3v2_Tag::getFrameList' from='0.0.1'/>

 <function name='KTaglib_ID3v2_Frame' from='0.0.1'/>
 <function name='KTaglib_ID3v2_Frame::getSize' from='0.0.1'/>
 <function name='KTaglib_ID3v2_Frame::__toString' from='0.0.1'/>

 <function name='KTaglib_ID3v2_AttachedPictureFrame' from='0.0.1'/>
 <function name='KTaglib_ID3v2_AttachedPictureFrame::getDescription' from='0.0.1'/>
 <function name='KTaglib_ID3v2_AttachedPictureFrame::getMimeType' from='0.2.0'/>
 <function name='KTaglib_ID3v2_AttachedPictureFrame::getType' from='0.2.0'/>
 <function name='KTaglib_ID3v2_AttachedPictureFrame::savePicture' from='0.0.1'/>
 <function name='KTaglib_ID3v2_AttachedPictureFrame::setMimeType' from='0.2.0'/>
 <function name='KTaglib_ID3v2_AttachedPictureFrame::setPicture' from='0.0.1'/>
 <function name='KTaglib_ID3v2_AttachedPictureFrame::setType' from='0.2.0'/>
</versions>

<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->


text:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0
     epp-1.0.xsd">
  <command>
    <create>
      <contact:create
       xmlns:contact="urn:ietf:params:xml:ns:contact-1.0"
       xsi:schemaLocation="urn:ietf:params:xml:ns:contact-1.0
       contact-1.0.xsd">
        <contact:id>$(id)$</contact:id>
          <contact:postalInfo type="loc">
            <contact:name>$(client_name)$</contact:name>
            <contact:org></contact:org>
            <contact:addr>
                <contact:street>$(client_street_1)$</contact:street>
                <contact:street>$(client_street_2)$</contact:street>
                <contact:city>$(client_city)$</contact:city>
                <contact:sp>$(client_state)$</contact:sp>
                <contact:pc>$(client_zipcode)$</contact:pc>
                <contact:cc>$(client_country)$</contact:cc>
            </contact:addr>
        </contact:postalInfo>
        <contact:voice>$(client_phone)$</contact:voice>
        <contact:email>$(client_email)$</contact:email>
        <contact:authInfo>
          <contact:pw>$(password)$</contact:pw>
        </contact:authInfo>
      </contact:create>
    </create>
    <clTRID>$(clTRID)$</clTRID>
  </command>
</epp>


text:
package de.rwth.idsg.bikeman.ixsi.dto;

import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
import org.joda.time.DateTime;
import org.joda.time.LocalDateTime;

/**
 * @author Sevket Goekay <goekay@dbis.rwth-aachen.de>
 * @since 19.11.2015
 */
@ToString
@EqualsAndHashCode
@Getter
public class BookingDTO {
    private String ixsiBookingId;
    private DateTime reservationStart;

    public BookingDTO(String ixsiBookingId, LocalDateTime reservationStart) {
        this.ixsiBookingId = ixsiBookingId;
        this.reservationStart = reservationStart.toDateTime();
    }

}


text:
package org.smartdata.integration.rest;

import io.restassured.RestAssured;
import io.restassured.path.json.JsonPath;
import io.restassured.response.Response;
import org.hamcrest.Matchers;

import java.util.List;

public class CmdletRestApi extends RestApiBase {

  /**
   * Submit an cmdlet.
   * @param cmdString
   * @return cmdlet id if success
   */
  public static Long submitCmdlet(String cmdString) {
    Response action = RestAssured.with().body(cmdString).post(CMDLETROOT + "/submit");
    //Response action = RestAssured.withArgs(cmdString).post(CMDLETROOT + "/submit");
    action.then().body("status", Matchers.equalTo("CREATED"));
    return new JsonPath(action.asString()).getLong("body");
  }

  public static boolean waitCmdletComplete(long cmdletId) {
    return waitCmdletComplete(cmdletId, Integer.MAX_VALUE);
  }

  /**
   * Wait until the specified cmdlet finishes.
   * @param cmdletId
   * @param secToWait
   * @return
   */
  public static boolean waitCmdletComplete(long cmdletId, int secToWait) {
    do {
      JsonPath path = getCmdletInfo(cmdletId);
      if (path.get("state").equals("DONE")) {
        return true;
      }
      secToWait--;
      if (secToWait < 0) {
        break;
      }
      try {
        Thread.sleep(1000);
      } catch (Exception e) {
        // ignore
      }
    } while (true);
    return false;
  }

  public static JsonPath getCmdletInfo(long cmdletId) {
    Response cmdletInfo = RestAssured.get(CMDLETROOT + "/" + cmdletId + "/info");
    cmdletInfo.then().body("status", Matchers.equalTo("OK"));
    JsonPath path = cmdletInfo.jsonPath().setRoot("body");
    return path;
  }

  public static List<Long> getCmdletActionIds(long cmdletId) {
    return getCmdletInfo(cmdletId).getList("aids", Long.class);
  }
}


text:
module Sheety::Children
  def self.included base
    base.extend ClassMethods
  end

  def _passes_constraint(i_val, c_val)
    case c_val # Good Read: http://ruby.about.com/od/beginningruby/qt/On-Case-And-Class.htm
      when Range
        c_val.include? i_val
      when Array
        c_val.include? i_val
      when Regexp
        c_val =~ i_val
      when String
        c_val == i_val.to_s
      else
        c_val == i_val
    end
  end

  def _get_i_val(item, c_key, accessor=nil)
    if accessor && item.respond_to?(accessor)
      return item.send(accessor, c_key)
    else
      return item.try(c_key)
    end
  end

  module ClassMethods
    # Defines a child relationship with the given name
    # symbol (required): the name of the child
    # options (required): a hash of options
    #   - klass (required): the class to use for the child instances
    #   - link (required): the url to fetch the children from
    #   -
    def atom_children(symbol, options)

      if options.blank?
        raise ArgumentError.new("blank options #{options} are not valid options for atom_children")
      end

      if options[:klass].blank? || options[:klass].class != Class
        raise ArgumentError.new("#{options} must have a :klass that is a Class, not a #{options[:klass].class}")
      end

      if options[:link].blank?
        raise ArgumentError.new("#{options} must have a non-blank :link")
      end

      unless method_defined?(:link)
        raise TypeError.new("#{self} must respond to :link to use atom_children")
      end

      if options[:merge_links] && method_defined?(:add_links) == false
        raise TypeError.new("#{self} must respond to :add_links in atom_children with merge_links=true")
      end

      plural = symbol.to_s
      singular = plural.singularize

      inst_var_sym = :"@#{symbol}"

      get_method = :"#{plural}"
      new_method = :"new_#{singular}"
      enum_method = :"_enumerate_#{plural}_by_method"
      where_method = :"#{plural}_where"
      except_method = :"#{plural}_except"
      except_any_method = :"#{plural}_except_any"
      find_first_method = :"find_#{singular}"

      # Defines a method that instantiates a new child
      define_method(new_method) do |entry=nil|
        options[:klass].new(self, entry)
      end

      # Defines a method that fetches children from Google
      define_method(get_method) do |force_refetch=false|
        if instance_variable_get(inst_var_sym).nil? || force_refetch
          list = Sheety::Api.inst.get_feed(link(options[:link])) # sort of a cyclic dependency, suboptimal

          if list.nil?
            raise Sheety::SheetyFetchError.new, "Fetching #{plural} failed!"
          end

          # TODO: Create a ListFeed Object so the links we get here don't need to be worried about collisions on link ids
          add_links(list['link']) if !list['link'].blank? && options[:merge_links]

          list = (list['entry'] || []).map do |entry|
            method(new_method).call(entry)
          end

          instance_variable_set(inst_var_sym, list)
        end

        return instance_variable_get(inst_var_sym)
      end

      # Defines a helper-method that will iterate over children checking that each item passes all constraints given
      define_method(enum_method) do |constraints, enumeration_method|
        children = method(get_method).()

        if children.nil?
          return []
        end

        return children.send(enumeration_method) do |item|
          constraints.all? do |constraint|
            _passes_constraint(_get_i_val(item, constraint[0], options[:accessor]), constraint[1])
          end
        end
      end

      # Defines a method that selects the children who adhere to all constraints given
      define_method(where_method) do |constraints|
        return method(enum_method).call(constraints, :find_all)
      end

      # Defines a method that selects the first child that passes all constraints given
      define_method(find_first_method) do |constraints|
        return method(enum_method).call(constraints, :detect)
      end

      # Defines a method that selects those children who fail to meet all constraint given
      define_method(except_method) do |constraints|
        return method(enum_method).call(constraints, :reject)
      end

      # Defines a method that selects those children who fail to meet at least one constraint given
      define_method(except_any_method) do |constraints|
        children = method(get_method).()

        if children.nil?
          return []
        end

        return children.reject do |item|
          constraints.any? do |constraint|
            _passes_constraint(_get_i_val(item, constraint[0], options[:accessor]), constraint[1])
          end
        end
      end
    end
  end
end


text:
class AddUserIdToPose < ActiveRecord::Migration
  def change
    add_column :poses, :user_id, :integer
  end
end


text:
package com.vmware.vim25;

/**
* @author Steve Jin (http://www.doublecloud.org)
* @version 5.1
*/

public enum HostActiveDirectoryInfoDomainMembershipStatus {
  unknown ("unknown"),
  ok ("ok"),
  noServers ("noServers"),
  clientTrustBroken ("clientTrustBroken"),
  serverTrustBroken ("serverTrustBroken"),
  inconsistentTrust ("inconsistentTrust"),
  otherProblem ("otherProblem");

  @SuppressWarnings("unused")
  private final String val;
  private HostActiveDirectoryInfoDomainMembershipStatus(String val)
  {
    this.val = val;
  }
}


text:
package com.harreke.easyapp.widget.gridview;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;

import com.harreke.easyapp.util.MathUtil;
import com.harreke.easyapp.util.MetricUtil;
import com.harreke.easyapp.widget.R;
import com.harreke.easyapp.widget.autofitview.AutoFitImageView;

/**
 由 Harreke(harreke@live.cn) 创建于 2015/04/15
 */
public class GridImageView extends AutoFitImageView {
    private boolean mClick = false;
    private float mDownX;
    private float mDownY;
    private int mHeight;
    private int mHeightGap;
    private Drawable mLineDivider;
    private int mLineDividerHeight;
    private int mLineDividerHeightThreshold;
    private int mLineMax;
    private OnGridClickListener mOnGridClickListener = null;
    private Drawable mRowDivider;
    private int mRowDividerWidth;
    private int mRowDividerWidthThreshold;
    private int mRowMax;
    private float mThreshold = MetricUtil.TouchSlop;
    private int mWidth;
    private int mWidthGap;

    public GridImageView(Context context) {
        this(context, null);
    }

    public GridImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray style = context.obtainStyledAttributes(attrs, R.styleable.GridImageView);
        mRowMax = style.getInt(R.styleable.GridImageView_grid_row_max, 2);
        if (mRowMax < 1) {
            mRowMax = 1;
        }
        mRowDivider = style.getDrawable(R.styleable.GridImageView_grid_row_divider);
        mRowDividerWidth = (int) style.getDimension(R.styleable.GridImageView_grid_row_divider_width, MetricUtil.Density);
        mRowDividerWidthThreshold = mRowDividerWidth / 2;
        mLineMax = style.getInt(R.styleable.GridImageView_grid_line_max, 2);
        if (mLineMax < 1) {
            mLineMax = 1;
        }
        mLineDivider = style.getDrawable(R.styleable.GridImageView_grid_line_divider);
        mLineDividerHeight = (int) style.getDimension(R.styleable.GridImageView_grid_line_divider_height, MetricUtil.Density);
        mLineDividerHeightThreshold = mLineDividerHeight / 2;
        style.recycle();

        setClickable(true);
    }

    public Bitmap getBitmap(int row, int line) {
        BitmapDrawable drawable = (BitmapDrawable) getDrawable();
        Bitmap bitmap;
        int widthGap;
        int heightGap;

        if (drawable != null) {
            bitmap = drawable.getBitmap();
            widthGap = bitmap.getWidth() / mRowMax;
            heightGap = bitmap.getHeight() / mLineMax;
            if (widthGap > 0 && heightGap > 0) {
                return Bitmap.createBitmap(bitmap, row * widthGap, line * heightGap, widthGap, heightGap);
            }
        }

        return null;
    }

    //    public Drawable getDrawable(int row, int line) {
    //        Drawable drawable = getDrawable();
    //        Drawable result = null;
    //        Bitmap bitmap;
    //        Canvas canvas;
    //
    //        if (drawable != null) {
    //            drawable.setBounds(0, 0, mWidth, mHeight);
    //            bitmap = Bitmap.createBitmap(mWidth, mHeight,
    //                    drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);
    //            canvas = new Canvas(bitmap);
    //            drawable.draw(canvas);
    //            result = new BitmapDrawable(getResources(),
    //                    Bitmap.createBitmap(bitmap, row * mWidthGap, line * mHeightGap, mWidthGap, mHeightGap));
    //        }
    //
    //        return result;
    //    }

    public int getLineMax() {
        return mLineMax;
    }

    public int getRowMax() {
        return mRowMax;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int i;
        int x;
        int y;

        if (mRowDivider != null) {
            for (i = 1; i < mRowMax; i++) {
                x = mWidthGap * i;
                mRowDivider.setBounds(x - mRowDividerWidthThreshold, 0, x + mRowDividerWidthThreshold, mHeight);
                mRowDivider.draw(canvas);
            }
        }
        if (mLineDivider != null) {
            for (i = 1; i < mLineMax; i++) {
                y = mHeightGap * i;
                mLineDivider.setBounds(0, y - mLineDividerHeightThreshold, mWidth, y + mLineDividerHeightThreshold);
                mLineDivider.draw(canvas);
            }
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        mWidth = getMeasuredWidth();
        mWidthGap = mWidth / mRowMax;
        mHeight = getMeasuredHeight();
        mHeightGap = mHeight / mLineMax;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float nowX = event.getX();
        float nowY = event.getY();

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mDownX = nowX;
                mDownY = nowY;
                mClick = true;
                break;
            case MotionEvent.ACTION_MOVE:
                if (MathUtil.getDistance(nowX, nowY, mDownX, mDownY) > mThreshold) {
                    mClick = false;
                }
                break;
            case MotionEvent.ACTION_UP:
                if (mClick) {
                    if (mOnGridClickListener != null) {
                        mOnGridClickListener.onGridClick((int) (mDownX / mWidthGap), (int) (mDownY / mHeightGap));

                        return true;
                    }
                }
        }

        return super.onTouchEvent(event);
    }

    public void setLineMax(int lineMax) {
        mLineMax = lineMax;
    }

    public void setOnGridClickListener(OnGridClickListener onGridClickListener) {
        mOnGridClickListener = onGridClickListener;
    }

    public void setRowMax(int rowMax) {
        mRowMax = rowMax;
    }

    public interface OnGridClickListener {
        void onGridClick(int row, int line);
    }
}


text:
'use strict';

var mongoose = require('mongoose'),
	uuid = require('node-uuid'),
	Schema = mongoose.Schema;

// jshint -W106
var SimpleApiKeySchema = new Schema({
	_id: String,
	application: { type: String, ref: 'Application' },
	activated_by: { type: String, ref: 'User'},
	updated_at: Date,
	created_at: Date
});

SimpleApiKeySchema.pre('save', function(next){
	this.updated_at = new Date();
	if ( !this.created_at ) {
		this.created_at = new Date();
	}
	if(!this._id) {
		this._id = uuid.v4();
	}
	next();
});
// jshint +W106

mongoose.model('SimpleApiKey', SimpleApiKeySchema);


text:
Package.describe({
  summary: "Code shared beween ddp-client and ddp-server",
  version: '1.2.3',
  documentation: null
});

Package.onUse(function (api) {
  api.use(['check', 'random', 'ejson', 'underscore', 'tracker',
           'retry'],
          ['client', 'server']);

  api.addFiles('namespace.js');

  api.addFiles('heartbeat.js', ['client', 'server']);
  api.addFiles('utils.js', ['client', 'server']);
  api.addFiles('method_invocation.js', ['client', 'server']);
  api.addFiles('random_stream.js', ['client', 'server']);

  api.export('DDPCommon');
});

Package.onTest(function (api) {
  // XXX we should write unit tests for heartbeat
});


text:
package org.locationtech.geomesa.index.view

import org.geotools.data.{DataStore, Query}
import org.geotools.filter.text.ecql.ECQL
import org.junit.runner.RunWith
import org.locationtech.geomesa.utils.geotools.SimpleFeatureTypes
import org.specs2.mock.Mockito
import org.specs2.mutable.Specification
import org.specs2.runner.JUnitRunner

@RunWith(classOf[JUnitRunner])
class RouteSelectorTest extends Specification with Mockito {

  import scala.collection.JavaConverters._

  "RouteSelector" should {
    "route queries based on filter attributes" in {
      val sft = SimpleFeatureTypes.createType("test", "name:String,age:Int,dtg:Date,*geom:Point:srid=4326")

      val configs = Seq.tabulate(3) { i =>
        val map = new java.util.HashMap[String, AnyRef]
        if (i == 0) {
          map.put(RouteSelectorByAttribute.RouteAttributes, Seq("id", Seq.empty.asJava).asJava)
        } else if (i == 1) {
          map.put(RouteSelectorByAttribute.RouteAttributes, Seq(Seq("geom", "dtg").asJava, Seq("geom").asJava).asJava)
        } else if (i == 2) {
          map.put(RouteSelectorByAttribute.RouteAttributes, Seq("name", Seq("age", "dtg").asJava).asJava)
        }
        mock[DataStore] -> map
      }
      val stores = configs.map(_._1)

      val router = new RouteSelectorByAttribute()
      router.init(configs)

      def query(filter: String) = new Query(sft.getTypeName, ECQL.toFilter(filter))

      val s1 = Seq("INCLUDE", "IN ('1', '2')", "foo = 'bar'", "age = 21")
      foreach(s1)(f => router.route(sft, query(f)) must beSome(stores.head))

      val s2 = Seq(
        "bbox(geom,-75,-45,-45,-30)",
        "dtg during 2019-01-01T00:00:00.000Z/2019-01-01T01:00:00.000Z and bbox(geom,-180,-90,180,90)")
      foreach(s2)(f => router.route(sft, query(f)) must beSome(stores(1)))

      val s3 = Seq(
        "name = 'foo'",
        "age = 21 AND dtg during 2019-01-01T00:00:00.000Z/2019-01-01T01:00:00.000Z",
        "name = 'foo' AND dtg during 2019-01-01T00:00:00.000Z/2019-01-01T01:00:00.000Z")
      foreach(s3)(f => router.route(sft, query(f)) must beSome(stores(2)))
    }
  }
}


text:
template<void> struct A                 // { dg-error "not a valid type" }
{
    template<typename> friend struct B;
};

template<typename> struct B {};

B<int> b;


text:
var helpers = require('./helpers');
var Joi = require('joi');
var assert = require('assert');

describe('generate other datatypes', function() {
  var res = { items: null };
  var expected = {
    count: 5,
    schema: Joi.object().keys({
      username: Joi.string().required(),
      email: Joi.string().email().required(),
    }).length(2)
  };

  before(function(done) {
    var schema = {
      username: '{{chance.name()}}',
      email: '{{chance.email()}}'
    };
    var opts = {
      size: 5,
    };
    helpers.generate(schema, opts, function (err, items) {
      if (err) return done(err);
      res.items = items;
      done();
    });
  });

  it('should have the correct size', function () {
    assert.equal(expected.count, res.items.length);
  });

  it('should produce correct schema structure', function () {
    res.items.forEach(function (item) {
      Joi.validate(item, expected.schema, function(err) {
        assert.ifError(err);
      });
    });
  });

  it('should produce entries with random content', function (done) {
    helpers.sampleAndStrip(res.items, 2, function (sample) {
      assert.notDeepEqual(sample[0], sample[1]);
      done();
    });
  });
});


text:
[TOC]

# Introduction

Blog posts can be created with the **Post Composer** or **Open Live Writer**. Posts are either **Published** or in **Drafts**, they are **Categorized** and optionally **Tagged**. For more info visit the offical [docs](https://fanray.com/docs/posts "Fanray Docs").

# Editor Shortcuts

The Post Composer uses a Rich Text editor and these shortcuts will make you productive.

| Shortcuts | Description |
| :-- | :-- |
| # + space | Use one or more # for headings (h1, h2 etc.) |
| > + space | Quote |
| - + space | Unordered list (ul) |
| ``  | Inline code |
| Select text, Ctrl + k | Make text link |
| Shift + enter | Soft break (br) |

# Images

To add images to your post just drag & drop them in. Only png, jpg and gif files are supported. Same with Pages.

# Slug and Post Date

Fanray uses SEO-friendly URLs for blog posts. The post slug and date are part of a post's URL. 💥 Be aware updating an already published post's slug or date may cause issues with search engines.

[[Docs]]
[[Pages]]


text:
<resources>
    <string name="app_name">Jak szybko umiesz liczyć?</string>
    <string name="password">Hasło</string>
    <string name="username">Nazwa użytkownika</string>
    <string name="bestScores">Najlepsze wyniki:</string>
    <string name="backToLogin">Wróć do logowania</string>
</resources>