Initial commit

This commit is contained in:
alexpete
2021-03-05 11:26:34 -08:00
commit a10351f38d
27091 changed files with 5521199 additions and 0 deletions
+12
View File
@@ -0,0 +1,12 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
add_subdirectory(Code)
+47
View File
@@ -0,0 +1,47 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_SOURCE_DIR}/Source/Platform/${PAL_PLATFORM_NAME})
ly_add_target(
NAME Achievements.Static STATIC
NAMESPACE Gem
PLATFORM_INCLUDE_FILES
${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}.cmake
FILES_CMAKE
achievements_files.cmake
${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake
INCLUDE_DIRECTORIES
PUBLIC
Include
PRIVATE
Source
BUILD_DEPENDENCIES
PUBLIC
AZ::AzCore
AZ::AzFramework
)
ly_add_target(
NAME Achievements ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
NAMESPACE Gem
OUTPUT_NAME Gem.Achievements.6f8d953dd4fc4bb6ad34c9118a7b789f.v0.1.0
FILES_CMAKE
achievements_shared_files.cmake
INCLUDE_DIRECTORIES
PUBLIC
Include
PRIVATE
Source
BUILD_DEPENDENCIES
PRIVATE
Gem::Achievements.Static
)
@@ -0,0 +1,33 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzFramework/Input/User/LocalUserId.h>
#include <AzCore/EBus/EBus.h>
#include <AzCore/std/string/string.h>
namespace Achievements
{
////////////////////////////////////////////////////////////////////////////////////////
// EBUS interface used to listen for achievement unlocked events
class AchievementNotifications
: public AZ::EBusTraits
{
public:
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
virtual void OnAchievementUnlocked(const AZStd::string& achievementId, const AzFramework::LocalUserId& localUserId) = 0;
virtual void OnAchievementUnlockRequested(const AZStd::string& achievementId, const AzFramework::LocalUserId& localUserId) = 0;
virtual void OnAchievementDetailsQueried(const AzFramework::LocalUserId& localUserId, const AchievementDetails& achievementDetails) = 0;
};
using AchievementNotificationBus = AZ::EBus<AchievementNotifications>;
} // namespace Achievements
@@ -0,0 +1,79 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzFramework/Input/User/LocalUserId.h>
#include <AzCore/std/string/string.h>
#include <AzCore/EBus/EBus.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/EditContextConstants.inl>
#include <AzCore/RTTI/BehaviorContext.h>
namespace Achievements
{
////////////////////////////////////////////////////////////////////////////////////////
// Contains achievements details that can be queried through EBUS requests and will contain
// achievement name, description, value, and query result
struct AchievementDetails
{
AZ_TYPE_INFO(AchievementDetails, "{3310A37C-4B91-4529-B893-38C89AD69F82}");
static void Reflect(AZ::ReflectContext* context);
AchievementDetails();
AZ::u32 id; // achievement Id
AZStd::string name; // name of the achievement
AZStd::string desc; // achievement description
int rewardValue; // "gamerscore" value of the achievement
AZ::u32 currentProgress; // current progress towards unlock requirement
bool unlocked; // whether or not achievement is unlocked
bool secret; // is achievement secret or hidden
};
////////////////////////////////////////////////////////////////////////////////////////
// EBUS interface used to make requests for achievement details, unlock status, and unlocking
class AchievementRequests
: public AZ::EBusTraits
{
public:
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
struct UnlockAchievementParams
{
AZ_TYPE_INFO(UnlockAchievementParams, "{9D28BB0F-2531-4371-9A91-1EE9226F2DE7}");
using OnAchievementUnlocked = AZStd::function<void(const AzFramework::LocalUserId&, const AZStd::string&)>;
AzFramework::LocalUserId localUserId = AzFramework::LocalUserIdNone;
AZStd::string achievementId;
AZ::u32 percentage = 0;
OnAchievementUnlocked OnAchievementUnlockCallback = nullptr;
};
struct QueryAchievementParams
{
AZ_TYPE_INFO(QueryAchievementParams, "{04195FE5-DBA9-45DE-BDB2-C2EC2D523BB5}");
using OnAchievementDetailsQueried = AZStd::function<void(const AzFramework::LocalUserId&, const AchievementDetails&)>;
AzFramework::LocalUserId localUserId = AzFramework::LocalUserIdNone;
AZStd::string achievementId;
OnAchievementDetailsQueried OnAchievementDetailsQueriedCallback = nullptr;
};
////////////////////////////////////////////////////////////////////////////////////////
// Unlocks the given achievement for the current player or adds towards progression to unlocking
virtual void UnlockAchievement(const UnlockAchievementParams& params) = 0;
////////////////////////////////////////////////////////////////////////////////////////
// Queries details of an achievements. fills in a structure with the name, description
// and reward value
virtual void QueryAchievementDetails(const QueryAchievementParams& params) = 0;
};
using AchievementRequestBus = AZ::EBus<AchievementRequests>;
} // namespace Achievements
@@ -0,0 +1,51 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzCore/Memory/SystemAllocator.h>
#include <AzCore/Module/Module.h>
#include <AchievementsSystemComponent.h>
namespace Achievements
{
class AchievementsModule
: public AZ::Module
{
public:
AZ_RTTI(AchievementsModule, "{67B7EBC3-69DE-447C-B006-776C2C1A4583}", AZ::Module);
AZ_CLASS_ALLOCATOR(AchievementsModule, AZ::SystemAllocator, 0);
AchievementsModule()
: AZ::Module()
{
// Push results of [MyComponent]::CreateDescriptor() into m_descriptors here.
m_descriptors.insert(m_descriptors.end(), {
AchievementsSystemComponent::CreateDescriptor(),
});
}
/**
* Add required SystemComponents to the SystemEntity.
*/
AZ::ComponentTypeList GetRequiredSystemComponents() const override
{
return AZ::ComponentTypeList{
azrtti_typeid<AchievementsSystemComponent>(),
};
}
};
}
// DO NOT MODIFY THIS LINE UNLESS YOU RENAME THE GEM
// The first parameter should be GemName_GemIdLower
// The second should be the fully qualified name of the class above
AZ_DECLARE_MODULE_CLASS(Gem_Achievements, Achievements::AchievementsModule)
@@ -0,0 +1,225 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AchievementsSystemComponent.h>
#include <Achievements/AchievementNotificationBus.h>
#include <AzCore/Component/TickBus.h>
namespace Achievements
{
class AchievementNotificationBusBehaviorHandler
: public AchievementNotificationBus::Handler
, public AZ::BehaviorEBusHandler
{
public:
////////////////////////////////////////////////////////////////////////////////////////////
AZ_EBUS_BEHAVIOR_BINDER(AchievementNotificationBusBehaviorHandler, "{33DFB6A3-434B-4341-B603-5F387D1CACFE}", AZ::SystemAllocator
, OnAchievementUnlocked
, OnAchievementDetailsQueried
, OnAchievementUnlockRequested
);
////////////////////////////////////////////////////////////////////////////////////////////
void OnAchievementUnlocked(const AZStd::string& achievementId, const AzFramework::LocalUserId& localUserId) override
{
Call(FN_OnAchievementUnlocked, achievementId, localUserId);
}
////////////////////////////////////////////////////////////////////////////////////////////
void OnAchievementUnlockRequested(const AZStd::string& achievementId, const AzFramework::LocalUserId& localUserId) override
{
Call(FN_OnAchievementUnlockRequested, achievementId, localUserId);
}
////////////////////////////////////////////////////////////////////////////////////////////
void OnAchievementDetailsQueried(const AzFramework::LocalUserId& localUserId, const AchievementDetails& achievementDetails) override
{
Call(FN_OnAchievementDetailsQueried, localUserId, achievementDetails);
}
};
////////////////////////////////////////////////////////////////////////////////////////
void AchievementDetails::Reflect(AZ::ReflectContext* context)
{
if (AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context))
{
serialize->Class<AchievementDetails>()
->Version(0);
if (AZ::EditContext* ec = serialize->GetEditContext())
{
ec->Class<AchievementDetails>("AchievementDetails", "Struct to hold platform agnostic achievement details for query results")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System"))
->Attribute(AZ::Edit::Attributes::AutoExpand, true);
}
}
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
{
behaviorContext->Class<AchievementDetails>()
->Constructor<AchievementDetails&>()
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::Preview)
->Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::Value)
->Property("id", BehaviorValueProperty(&AchievementDetails::id))
->Property("name", BehaviorValueProperty(&AchievementDetails::name))
->Property("desc", BehaviorValueProperty(&AchievementDetails::desc))
->Property("rewardValue", BehaviorValueProperty(&AchievementDetails::rewardValue))
->Property("secret", BehaviorValueProperty(&AchievementDetails::secret))
->Property("currentProgress", BehaviorValueProperty(&AchievementDetails::currentProgress))
->Property("unlocked", BehaviorValueProperty(&AchievementDetails::unlocked));
}
}
////////////////////////////////////////////////////////////////////////////////////////
AchievementDetails::AchievementDetails() :
id(0),
name(""),
desc(""),
rewardValue(0),
currentProgress(0),
unlocked(false),
secret(false)
{
}
////////////////////////////////////////////////////////////////////////////////////////
void AchievementsSystemComponent::Reflect(AZ::ReflectContext* context)
{
if (AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context))
{
serialize->Class<AchievementsSystemComponent, AZ::Component>()
->Version(0);
if (AZ::EditContext* ec = serialize->GetEditContext())
{
ec->Class<AchievementsSystemComponent>("Achievements", "Platform agnostic interface for retrieving achievement details and unlocking achievements")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System"))
->Attribute(AZ::Edit::Attributes::AutoExpand, true);
}
}
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
{
behaviorContext->EBus<AchievementNotificationBus>("AchievementNotificationBus")
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
->Handler<AchievementNotificationBusBehaviorHandler>();
using UnlockAchievementParams = AchievementRequests::UnlockAchievementParams;
behaviorContext->Class<UnlockAchievementParams>()
->Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::Value)
->Property("achievementId", BehaviorValueProperty(&UnlockAchievementParams::achievementId))
->Property("localUserId", BehaviorValueProperty(&UnlockAchievementParams::localUserId))
->Property("percentage", BehaviorValueProperty(&UnlockAchievementParams::percentage));
using QueryAchievementParams = AchievementRequests::QueryAchievementParams;
behaviorContext->Class<QueryAchievementParams>()
->Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::Value)
->Property("achievementId", BehaviorValueProperty(&QueryAchievementParams::achievementId))
->Property("localUserId", BehaviorValueProperty(&QueryAchievementParams::localUserId));
behaviorContext->EBus<AchievementRequestBus>("AchievementRequestBus")
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
->Attribute(AZ::Script::Attributes::Category, "Achievements")
->Event("UnlockAchievement", &AchievementRequestBus::Events::UnlockAchievement)
->Event("QueryAchievementDetails", &AchievementRequestBus::Events::QueryAchievementDetails);
}
AchievementDetails::Reflect(context);
}
////////////////////////////////////////////////////////////////////////////////////////
void AchievementsSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
{
provided.push_back(AZ_CRC("AchievementsService"));
}
////////////////////////////////////////////////////////////////////////////////////////
void AchievementsSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
{
incompatible.push_back(AZ_CRC("AchievementsService"));
}
////////////////////////////////////////////////////////////////////////////////////////
void AchievementsSystemComponent::Activate()
{
m_pimpl.reset(Implementation::Create(*this));
AchievementRequestBus::Handler::BusConnect();
}
////////////////////////////////////////////////////////////////////////////////////////
void AchievementsSystemComponent::Deactivate()
{
AchievementRequestBus::Handler::BusDisconnect();
m_pimpl.reset();
}
////////////////////////////////////////////////////////////////////////////////////////
void AchievementsSystemComponent::UnlockAchievement(const UnlockAchievementParams& params)
{
AchievementNotificationBus::Broadcast(&AchievementNotifications::OnAchievementUnlockRequested, params.achievementId, params.localUserId);
AZ_Printf("Achievements", "Unlock Achievement request for localuserId %s, achievement ID %s", AzFramework::LocalUserIdToString(params.localUserId).c_str(), params.achievementId.c_str());
if (m_pimpl)
{
m_pimpl->UnlockAchievement(params);
}
}
////////////////////////////////////////////////////////////////////////////////////////
void AchievementsSystemComponent::QueryAchievementDetails(const QueryAchievementParams& params)
{
AZ_Printf("Achievements", "Query Achievement request for localuserId %s, achievement ID %s", AzFramework::LocalUserIdToString(params.localUserId).c_str(), params.achievementId.c_str());
if (m_pimpl)
{
m_pimpl->QueryAchievementDetails(params);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
AchievementsSystemComponent::Implementation::Implementation(AchievementsSystemComponent& achievementSystemComponent)
: m_achievementsSystemComponent(achievementSystemComponent)
{
}
////////////////////////////////////////////////////////////////////////////////////////////////
AchievementsSystemComponent::Implementation::~Implementation()
{
}
////////////////////////////////////////////////////////////////////////////////////////
void AchievementsSystemComponent::Implementation::OnUnlockAchievementComplete(const UnlockAchievementParams& params)
{
AZ::TickBus::QueueFunction([params]()
{
if (params.OnAchievementUnlockCallback)
{
params.OnAchievementUnlockCallback(params.localUserId, params.achievementId);
}
AchievementNotificationBus::Broadcast(&AchievementNotifications::OnAchievementUnlocked, params.achievementId, params.localUserId);
});
}
////////////////////////////////////////////////////////////////////////////////////////
void AchievementsSystemComponent::Implementation::OnQueryAchievementDetailsComplete(const QueryAchievementParams& params, const AchievementDetails& details)
{
AZ::TickBus::QueueFunction([params, details]()
{
if (params.OnAchievementDetailsQueriedCallback)
{
params.OnAchievementDetailsQueriedCallback(params.localUserId, details);
}
AchievementNotificationBus::Broadcast(&AchievementNotifications::OnAchievementDetailsQueried, params.localUserId, details);
});
}
}
@@ -0,0 +1,80 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/Component/Component.h>
#include <Achievements/AchievementRequestBus.h>
#include <AzCore/std/parallel/atomic.h>
#include <AzCore/std/string/string.h>
#include <AzCore/Component/TickBus.h>
namespace Achievements
{
////////////////////////////////////////////////////////////////////////////////////////
// A system component providing an interface to query and unlock achievements
class AchievementsSystemComponent
: public AZ::Component
, protected AchievementRequestBus::Handler
{
public:
////////////////////////////////////////////////////////////////////////////////////////
// Component setup
AZ_COMPONENT(AchievementsSystemComponent, "{07CFF8FE-668E-476A-95D9-A3B0CCCE2414}");
////////////////////////////////////////////////////////////////////////////////////////
// Component overrides
static void Reflect(AZ::ReflectContext* context);
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
protected:
////////////////////////////////////////////////////////////////////////////////////////
// AZ::Component interface implementation
void Activate() override;
void Deactivate() override;
////////////////////////////////////////////////////////////////////////////////////////
// AchievementsRequestBus interface implementation
void UnlockAchievement(const UnlockAchievementParams& params) override;
void QueryAchievementDetails(const QueryAchievementParams& params);
public:
////////////////////////////////////////////////////////////////////////////////////////
// Base class for platform specific implementations
class Implementation
{
public:
AZ_CLASS_ALLOCATOR(Implementation, AZ::SystemAllocator, 0);
static Implementation* Create(AchievementsSystemComponent& achievementsSystemComponent);
Implementation(AchievementsSystemComponent& achievementsSystemComponent);
AZ_DISABLE_COPY_MOVE(Implementation);
virtual ~Implementation();
virtual void UnlockAchievement(const UnlockAchievementParams& params) = 0;
virtual void QueryAchievementDetails(const QueryAchievementParams& params) = 0;
static void OnUnlockAchievementComplete(const UnlockAchievementParams& params);
static void OnQueryAchievementDetailsComplete(const QueryAchievementParams& params, const AchievementDetails& details);
AchievementsSystemComponent& m_achievementsSystemComponent;
};
private:
////////////////////////////////////////////////////////////////////////////////////////
// Private pointer to the platform specific implementation
AZStd::unique_ptr<Implementation> m_pimpl;
};
}
@@ -0,0 +1,10 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
@@ -0,0 +1,14 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(FILES
../Common/Unimplemented/AchievementsSystemComponent_Unimplemented.cpp
)
@@ -0,0 +1,10 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
@@ -0,0 +1,22 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AchievementsSystemComponent.h>
namespace Achievements
{
////////////////////////////////////////////////////////////////////////////////////////////////
AchievementsSystemComponent::Implementation* AchievementsSystemComponent::Implementation::Create(AchievementsSystemComponent&)
{
return nullptr;
}
}
@@ -0,0 +1,10 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
@@ -0,0 +1,14 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(FILES
../Common/Unimplemented/AchievementsSystemComponent_Unimplemented.cpp
)
@@ -0,0 +1,10 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
@@ -0,0 +1,14 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(FILES
../Common/Unimplemented/AchievementsSystemComponent_Unimplemented.cpp
)
@@ -0,0 +1,10 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
@@ -0,0 +1,14 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(FILES
../Common/Unimplemented/AchievementsSystemComponent_Unimplemented.cpp
)
@@ -0,0 +1,10 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
@@ -0,0 +1,14 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(FILES
../Common/Unimplemented/AchievementsSystemComponent_Unimplemented.cpp
)
@@ -0,0 +1,17 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(FILES
Include/Achievements/AchievementRequestBus.h
Include/Achievements/AchievementNotificationBus.h
Source/AchievementsSystemComponent.cpp
Source/AchievementsSystemComponent.h
)
@@ -0,0 +1,14 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(FILES
Source/AchievementsModule.cpp
)
+15
View File
@@ -0,0 +1,15 @@
{
"GemFormatVersion": 4,
"Uuid": "6f8d953dd4fc4bb6ad34c9118a7b789f",
"Name": "Achievements",
"DisplayName": "Achievements",
"Version": "0.1.0",
"Summary": "Platform agnostic interface for retrieving achievement details and unlocking achievements.",
"Tags": ["Achievement", "Achievements", "Trophy", "Trophies"],
"IconPath": "preview.png",
"Modules": [
{
"Type": "GameModule"
}
]
}
+3
View File
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:cfce328aa178aabcb29d7c09fc5d0c5b0884b13c69d15487c92b74a4d66dd705
size 1013
+12
View File
@@ -0,0 +1,12 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
add_subdirectory(Code)
@@ -0,0 +1,67 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
ly_add_target(
NAME AssetMemoryAnalyzer.Static STATIC
NAMESPACE Gem
FILES_CMAKE
assetmemoryanalyzer_files.cmake
INCLUDE_DIRECTORIES
PRIVATE
Source
PUBLIC
Include
BUILD_DEPENDENCIES
PUBLIC
AZ::AzCore
Legacy::CryCommon
Legacy::CryRender.Headers
Gem::ImGui.Static
)
ly_add_target(
NAME AssetMemoryAnalyzer ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
NAMESPACE Gem
OUTPUT_NAME Gem.AssetMemoryAnalyzer.35414634480a4d4c8412c60fe62f4c81.v0.1.0
FILES_CMAKE
assetmemoryanalyzer_shared_files.cmake
INCLUDE_DIRECTORIES
PRIVATE
Source
PUBLIC
Include
BUILD_DEPENDENCIES
PRIVATE
Gem::AssetMemoryAnalyzer.Static
)
################################################################################
# Tests
################################################################################
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
ly_add_target(
NAME AssetMemoryAnalyzer.Tests ${PAL_TRAIT_TEST_TARGET_TYPE}
NAMESPACE Gem
FILES_CMAKE
assetmemoryanalyzer_tests_files.cmake
INCLUDE_DIRECTORIES
PRIVATE
Source
Tests
BUILD_DEPENDENCIES
PRIVATE
AZ::AzTest
Gem::AssetMemoryAnalyzer.Static
)
ly_add_googletest(
NAME Gem::AssetMemoryAnalyzer.Tests
)
endif()
@@ -0,0 +1,43 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/EBus/EBus.h>
namespace AssetMemoryAnalyzer
{
class FrameAnalysis;
class AssetMemoryAnalyzerRequests
: public AZ::EBusTraits
{
public:
//////////////////////////////////////////////////////////////////////////
// EBusTraits overrides
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
//////////////////////////////////////////////////////////////////////////
// Enables or disables the AssetMemoryAnalyzer.
virtual void SetEnabled(bool enabled = true) = 0;
// Exports a CSV file that may be imported into a spreadsheet. Top-level assets only, due to the limitations of CSV. Path is optional, defaults to @log@/assetmem-<TIMESTAMP>.csv
virtual void ExportCSVFile(const char* path = nullptr) = 0;
// Exports a JSON file that may be viewed by the web viewer. Path is optional, defaults to @log@/assetmem-<TIMESTAMP>.json
virtual void ExportJSONFile(const char* path = nullptr) = 0;
// Retrieves a frame analysis. (Generally used for testing purposes; use of the gem's private headers are required to inspect this.)
virtual AZStd::shared_ptr<FrameAnalysis> GetAnalysis() = 0;
};
using AssetMemoryAnalyzerRequestBus = AZ::EBus<AssetMemoryAnalyzerRequests>;
} // namespace AssetMemoryAnalyzer
@@ -0,0 +1,382 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "AssetMemoryAnalyzer_precompiled.h"
#include "AssetMemoryAnalyzer.h"
#include <AzCore/Memory/MemoryDrillerBus.h>
#include <AzCore/Debug/AssetTrackingTypesImpl.h>
#include <AzCore/Debug/AssetTracking.h>
#include <AzCore/std/smart_ptr/make_shared.h>
///////////////////////////////////////////////////////////////////////////////
// CodePoint hash-table support
///////////////////////////////////////////////////////////////////////////////
template<>
struct AZStd::hash<AssetMemoryAnalyzer::Data::CodePoint>
{
size_t operator()(const AssetMemoryAnalyzer::Data::CodePoint& codePoint) const
{
size_t seed = 0;
AZStd::hash_combine(seed, codePoint.m_file);
AZStd::hash_combine(seed, codePoint.m_line);
return seed;
}
};
namespace AssetMemoryAnalyzer
{
namespace Data
{
inline bool operator==(const CodePoint& lhs, const CodePoint& rhs)
{
return lhs.m_file == rhs.m_file &&
lhs.m_line == rhs.m_line;
}
}
}
///////////////////////////////////////////////////////////////////////////////
// AnalyzerImpl class
///////////////////////////////////////////////////////////////////////////////
namespace AssetMemoryAnalyzer
{
class AnalyzerImpl :
public AZ::Debug::MemoryDrillerBus::Handler,
public Render::Debug::VRAMDrillerBus::Handler
{
public:
AZ_TYPE_INFO(AnalyzerImpl, "{E460E4DE-2160-4171-A4B6-3C2DB6692C32}");
AZ_CLASS_ALLOCATOR(AnalyzerImpl, AZ::Debug::AssetTrackingAllocator, 0);
AnalyzerImpl();
~AnalyzerImpl();
// MemoryDrillerBus
void RegisterAllocator(AZ::IAllocator* allocator) override;
void UnregisterAllocator(AZ::IAllocator* allocator) override;
void DumpAllAllocations() override;
void RegisterAllocation(AZ::IAllocator* allocator, void* address, size_t byteSize, size_t alignment, const char* name, const char* fileName, int lineNum, unsigned int stackSuppressCount) override;
void UnregisterAllocation(AZ::IAllocator* allocator, void* address, size_t byteSize, size_t alignment, AZ::Debug::AllocationInfo* info) override;
void ReallocateAllocation(AZ::IAllocator* allocator, void* prevAddress, void* newAddress, size_t newByteSize, size_t newAlignment) override;
void ResizeAllocation(AZ::IAllocator* allocator, void* address, size_t newSize) override;
// VRAMDrillerBus
void RegisterCategory(Render::Debug::VRAMAllocationCategory category, const char* categoryName, const Render::Debug::VRAMSubCategoryType& subcategories) override;
void UnregisterAllCategories() override;
void RegisterAllocation(void* address, size_t byteSize, const char* allocationName, Render::Debug::VRAMAllocationCategory category, Render::Debug::VRAMAllocationSubcategory subcategories) override;
void UnregisterAllocation(void* address) override;
void GetCurrentVRAMStats(Render::Debug::VRAMAllocationCategory category, Render::Debug::VRAMAllocationSubcategory subcategory, AZStd::string& categoryName, AZStd::string& subcategoryName, size_t& numberBytesAllocated, size_t& numberAllocations) override;
AZStd::shared_ptr<FrameAnalysis> GetAnalysis();
private:
void RegisterAllocationCommon(void* address, size_t byteSize, const char* fileName, int lineNum, Data::AllocationData::CategoryInfo categoryInfo, Data::AllocationCategories category);
void UnregisterAllocationCommon(void* address);
using AssetTree = AZ::Debug::AssetTree<Data::AssetData>;
using AssetTreeNode = typename AssetTree::NodeType;
using AllocationTable = AZ::Debug::AllocationTable<Data::AllocationData>;
using MasterCodePoints = AZStd::unordered_set<Data::CodePoint, AZStd::hash<Data::CodePoint>, AZStd::equal_to<Data::CodePoint>, AZ::Debug::AZStdAssetTrackingAllocator>;
using mutex_type = AZStd::mutex;
using lock_type = AZStd::lock_guard<mutex_type>;
mutex_type m_mutex;
MasterCodePoints m_masterCodePoints;
AssetTree m_assetTree;
AllocationTable m_allocationTable;
AZ::Debug::AssetTracking m_assetTracking;
bool m_captureUncategorizedAllocations = false;
bool m_performingAnalysis = false;
};
///////////////////////////////////////////////////////////////////////////////
// AnalyzerImpl functions
///////////////////////////////////////////////////////////////////////////////
AnalyzerImpl::AnalyzerImpl() :
m_allocationTable(m_mutex),
m_assetTracking(&m_assetTree, &m_allocationTable)
{
AZ::Debug::MemoryDrillerBus::Handler::BusConnect();
Render::Debug::VRAMDrillerBus::Handler::BusConnect();
}
AnalyzerImpl::~AnalyzerImpl()
{
AZ::Debug::MemoryDrillerBus::Handler::BusDisconnect();
Render::Debug::VRAMDrillerBus::Handler::BusDisconnect();
}
void AnalyzerImpl::RegisterAllocator(AZ::IAllocator* allocator)
{
AZ_UNUSED(allocator);
}
void AnalyzerImpl::UnregisterAllocator(AZ::IAllocator* allocator)
{
AZ_UNUSED(allocator);
}
void AnalyzerImpl::DumpAllAllocations()
{
}
void AnalyzerImpl::RegisterAllocation(AZ::IAllocator* allocator, void* address, size_t byteSize, size_t alignment, const char* name, const char* fileName, int lineNum, unsigned int stackSuppressCount)
{
AZ_UNUSED(name);
AZ_UNUSED(alignment);
AZ_UNUSED(stackSuppressCount);
Data::AllocationData::CategoryInfo categoryInfo;
categoryInfo.m_heapInfo.m_allocator = allocator;
RegisterAllocationCommon(address, byteSize, fileName, lineNum, categoryInfo, Data::AllocationCategories::HEAP);
}
void AnalyzerImpl::UnregisterAllocation(AZ::IAllocator* allocator, void* address, size_t byteSize, size_t alignment, AZ::Debug::AllocationInfo* info)
{
AZ_UNUSED(allocator);
AZ_UNUSED(byteSize);
AZ_UNUSED(alignment);
AZ_UNUSED(info);
UnregisterAllocationCommon(address);
}
void AnalyzerImpl::ReallocateAllocation(AZ::IAllocator* allocator, void* prevAddress, void* newAddress, size_t newByteSize, size_t newAlignment)
{
AZ_UNUSED(allocator);
AZ_UNUSED(newAlignment);
if (m_performingAnalysis)
{
return;
}
m_allocationTable.ReallocateAllocation(prevAddress, newAddress, newByteSize);
}
void AnalyzerImpl::ResizeAllocation(AZ::IAllocator* allocator, void* address, size_t newSize)
{
AZ_UNUSED(allocator);
if (m_performingAnalysis)
{
return;
}
m_allocationTable.ResizeAllocation(address, newSize);
}
void AnalyzerImpl::RegisterCategory(Render::Debug::VRAMAllocationCategory category, const char* categoryName, const Render::Debug::VRAMSubCategoryType& subcategories)
{
AZ_UNUSED(category);
AZ_UNUSED(categoryName);
AZ_UNUSED(subcategories);
}
void AnalyzerImpl::UnregisterAllCategories()
{
}
void AnalyzerImpl::RegisterAllocation(void* address, size_t byteSize, const char* allocationName, Render::Debug::VRAMAllocationCategory category, Render::Debug::VRAMAllocationSubcategory subcategories)
{
// Bit-flip address so that it won't collide with heap allocations (calls to the VRAM driller tend to use the same pointers from the heap objects that own the VRAM)
address = (void*)~(size_t)address;
Data::AllocationData::CategoryInfo categoryInfo;
categoryInfo.m_vramInfo.m_category = category;
categoryInfo.m_vramInfo.m_subcategories = subcategories;
RegisterAllocationCommon(address, byteSize, allocationName, 0, categoryInfo, Data::AllocationCategories::VRAM);
}
void AnalyzerImpl::UnregisterAllocation(void* address)
{
address = (void*)~(size_t)address;
UnregisterAllocationCommon(address);
}
void AnalyzerImpl::GetCurrentVRAMStats(Render::Debug::VRAMAllocationCategory category, Render::Debug::VRAMAllocationSubcategory subcategory, AZStd::string& categoryName, AZStd::string& subcategoryName, size_t& numberBytesAllocated, size_t& numberAllocations)
{
AZ_UNUSED(category);
AZ_UNUSED(subcategory);
AZ_UNUSED(categoryName);
AZ_UNUSED(subcategoryName);
AZ_UNUSED(numberBytesAllocated);
AZ_UNUSED(numberAllocations);
}
void AnalyzerImpl::RegisterAllocationCommon(void* address, size_t byteSize, const char* fileName, int lineNum, Data::AllocationData::CategoryInfo categoryInfo, Data::AllocationCategories category)
{
if (m_performingAnalysis)
{
return;
}
AZ::Debug::AssetTreeNodeBase* activeAsset = m_assetTracking.GetCurrentThreadAsset();
if (!activeAsset)
{
if (m_captureUncategorizedAllocations)
{
activeAsset = &m_assetTree.GetRoot();
}
else
{
return;
}
}
{
// Store a record for this allocation, at this code-point
lock_type lock(m_mutex);
auto insertResult = m_masterCodePoints.emplace(Data::CodePoint{ fileName ? fileName : "<unknown>", lineNum, category });
Data::CodePoint* cp = &*insertResult.first;
m_allocationTable.Get().emplace(address, AllocationTable::RecordType{ activeAsset, (uint32_t)byteSize, Data::AllocationData{ cp, categoryInfo } });
static_cast<typename AssetTree::NodeType*>(activeAsset)->m_data.m_totalAllocations[(int)category]++;
}
}
void AnalyzerImpl::UnregisterAllocationCommon(void* address)
{
if (m_performingAnalysis)
{
return;
}
{
// Delete the record of this allocation if it exists
lock_type lock(m_mutex);
auto& table = m_allocationTable.Get();
auto itr = table.find(address);
if (itr != table.end())
{
static_cast<typename AssetTree::NodeType*>(itr->second.m_asset)->m_data.m_totalAllocations[(int)itr->second.m_data.m_codePoint->m_category]--;
table.erase(address);
}
}
}
AZStd::shared_ptr<FrameAnalysis> AnalyzerImpl::GetAnalysis()
{
using namespace Data;
lock_type lock(m_mutex);
m_performingAnalysis = true; // Prevent recursive allocations from disrupting our work
auto result = AZStd::allocate_shared<FrameAnalysis>(AZ::Debug::AZStdAssetTrackingAllocator());
FrameAnalysis* analysis = result.get();
// Walk through all allocations and record their individual contributions to the analysisData for their owning asset
for (auto& allocationInfo : m_allocationTable.Get())
{
auto assetData = &static_cast<typename AssetTree::NodeType*>(allocationInfo.second.m_asset)->m_data;
auto category = allocationInfo.second.m_data.m_codePoint->m_category;
// Update total bytes for this asset
assetData->m_totalBytes[(int)category] += allocationInfo.second.m_size;
// Locate or create a recording of this code point within the analysis for this asset
auto codePointItr = assetData->m_codePointsToAllocations.find(allocationInfo.second.m_data.m_codePoint);
if (codePointItr == assetData->m_codePointsToAllocations.end())
{
codePointItr = assetData->m_codePointsToAllocations.emplace(allocationInfo.second.m_data.m_codePoint, AssetData::CodePointInfo()).first;
codePointItr->second.m_category = category;
}
// Update the code point within the analysis for this asset with information about this allocation
codePointItr->second.m_allocations.emplace_back(AllocationPoint::AllocationInfo{ allocationInfo.second.m_size });
codePointItr->second.m_totalBytes += allocationInfo.second.m_size;
}
// Declare function to recurse through the asset tree, converting the analysisData of every node into matching information in the public API (AssetMemory:: namespace)
AZStd::function<void(AssetInfo*, AssetTreeNode*, int)> recurse;
recurse = [&recurse](AssetInfo* outAsset, AssetTreeNode* inAsset, int depth)
{
outAsset->m_id = inAsset->m_masterInfo ? inAsset->m_masterInfo->m_id->m_id.c_str() : nullptr;
// For every code point in this asset node, record its allocations
for (auto& codePointInfo : inAsset->m_data.m_codePointsToAllocations)
{
outAsset->m_allocationPoints.emplace_back(AllocationPoint());
auto allocationPoint = &outAsset->m_allocationPoints.back();
allocationPoint->m_codePoint = codePointInfo.first;
allocationPoint->m_allocations.swap(codePointInfo.second.m_allocations);
allocationPoint->m_totalAllocatedMemory = codePointInfo.second.m_totalBytes;
// Add these allocations to our total count of allocations for this asset
int categoryIndex = (int)codePointInfo.first->m_category;
outAsset->m_localSummary[categoryIndex].m_allocationCount += (uint32_t)allocationPoint->m_allocations.size();
// Reserve memory for the next frame, as the number of allocations are unlikely to change much over time
codePointInfo.second.m_allocations.reserve(allocationPoint->m_allocations.size());
codePointInfo.second.m_totalBytes = 0; // Reset for next frame
}
// Initialize the local and total summary
for (int categoryIndex = 0; categoryIndex < ALLOCATION_CATEGORY_COUNT; categoryIndex++)
{
outAsset->m_localSummary[categoryIndex].m_allocatedMemory = inAsset->m_data.m_totalBytes[categoryIndex];
outAsset->m_totalSummary[categoryIndex] = outAsset->m_localSummary[categoryIndex];
}
// Recurse over child assets
outAsset->m_childAssets.resize(inAsset->m_children.size());
size_t childIdx = 0;
for (auto& inChildItr : inAsset->m_children)
{
auto outChild = &outAsset->m_childAssets[childIdx++];
recurse(outChild, &inChildItr.second, depth + 1);
// Have child assets contribute to the total summary
for (int categoryIndex = 0; categoryIndex < ALLOCATION_CATEGORY_COUNT; categoryIndex++)
{
outAsset->m_totalSummary[categoryIndex].m_allocatedMemory += outChild->m_totalSummary[categoryIndex].m_allocatedMemory;
outAsset->m_totalSummary[categoryIndex].m_allocationCount += outChild->m_totalSummary[categoryIndex].m_allocationCount;
}
}
// Clear analysis data out for the next frame
AZStd::for_each(inAsset->m_data.m_totalBytes, inAsset->m_data.m_totalBytes + ALLOCATION_CATEGORY_COUNT, [](uint32_t& x) { x = 0; });
};
recurse(&analysis->m_rootAsset, static_cast<typename AssetTree::NodeType*>(&m_assetTree.GetRoot()), 0);
m_performingAnalysis = false;
return result;
}
///////////////////////////////////////////////////////////////////////////////
// Analyzer functions
///////////////////////////////////////////////////////////////////////////////
Analyzer::Analyzer() : m_impl(aznew AnalyzerImpl)
{
}
Analyzer::~Analyzer()
{
}
AZStd::shared_ptr<FrameAnalysis> Analyzer::GetAnalysis()
{
return m_impl->GetAnalysis();
}
}
@@ -0,0 +1,170 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/Debug/AssetTrackingTypes.h>
#include <Common/Memory/VRAMDriller.h>
namespace AssetMemoryAnalyzer
{
class AnalyzerImpl;
namespace Data
{
enum class AllocationCategories
{
HEAP,
VRAM,
COUNT
};
constexpr int ALLOCATION_CATEGORY_COUNT = (int)AllocationCategories::COUNT;
// A location in code
struct CodePoint
{
const char* m_file;
int m_line;
AllocationCategories m_category;
};
// Meta-information to attach to an individual allocation
struct AllocationData
{
union CategoryInfo
{
struct
{
AZ::IAllocator* m_allocator;
}
m_heapInfo;
struct
{
Render::Debug::VRAMAllocationCategory m_category;
Render::Debug::VRAMAllocationSubcategory m_subcategories;
}
m_vramInfo;
};
CodePoint* m_codePoint;
CategoryInfo m_categoryInfo;
};
// Information about a point in code where allocations occur
struct AllocationPoint
{
struct AllocationInfo
{
// Size in bytes
uint32_t m_size;
};
using AllocationInfos = AZStd::vector<AllocationInfo, AZ::Debug::AZStdAssetTrackingAllocator>;
// The point in code where allocations occur
const CodePoint* m_codePoint;
// Total memory allocated through this code point (will be the sum of m_allocations)
uint32_t m_totalAllocatedMemory = 0;
// Individual allocations that occurred through this code point
AllocationInfos m_allocations;
};
// Summary information about a group of allocations
struct Summary
{
// Total bytes allocated in the group
uint32_t m_allocatedMemory = 0;
// Total number of separate allocations in the group
uint32_t m_allocationCount = 0;
};
// Information about an asset
struct AssetData
{
struct CodePointInfo
{
AllocationPoint::AllocationInfos m_allocations;
uint32_t m_totalBytes = 0;
AllocationCategories m_category;
};
uint32_t m_totalAllocations[ALLOCATION_CATEGORY_COUNT];
uint32_t m_totalBytes[ALLOCATION_CATEGORY_COUNT];
AZStd::unordered_map<CodePoint*, CodePointInfo, AZStd::hash<CodePoint*>, AZStd::equal_to<CodePoint*>, AZ::Debug::AZStdAssetTrackingAllocator> m_codePointsToAllocations;
};
// Information about a specific asset.
struct AssetInfo
{
// Identifier for the asset.
const char* m_id = nullptr;
// Total allocations/bytes for this asset, including allocations for any child assets.
Summary m_totalSummary[ALLOCATION_CATEGORY_COUNT];
// Total allocations/bytes for this asset alone, excluding allocations for child assets.
Summary m_localSummary[ALLOCATION_CATEGORY_COUNT];
// Child assets (i.e. assets that enter into scope while this asset is already in scope)
AZStd::vector<AssetInfo, AZ::Debug::AZStdAssetTrackingAllocator> m_childAssets;
// Points in code at which this asset has made allocations
AZStd::vector<AllocationPoint, AZ::Debug::AZStdAssetTrackingAllocator> m_allocationPoints;
};
typedef AZStd::vector<AllocationPoint, AZ::Debug::AZStdAssetTrackingAllocator> AllocationPoints;
}
// Analysis of all loaded assets at a moment in time
class FrameAnalysis
{
public:
AZ_TYPE_INFO(FrameAnalysis, "{6B7287A6-EE5E-4A9D-B219-586DAD865537}");
AZ_CLASS_ALLOCATOR(FrameAnalysis, AZ::Debug::AssetTrackingAllocator, 0);
const Data::AssetInfo& GetRootAsset() const
{
return m_rootAsset;
}
const Data::AllocationPoints& GetAllocationPoints() const
{
return m_allocationPoints;
}
private:
Data::AssetInfo m_rootAsset;
Data::AllocationPoints m_allocationPoints;
friend AnalyzerImpl;
};
class Analyzer
{
public:
AZ_TYPE_INFO(Analyzer, "{00FB30E2-706C-41E6-9BDD-F52A40CF3366}");
AZ_CLASS_ALLOCATOR(Analyzer, AZ::Debug::AssetTrackingAllocator, 0);
Analyzer();
~Analyzer();
AZStd::shared_ptr<FrameAnalysis> GetAnalysis();
private:
AZStd::unique_ptr<AnalyzerImpl> m_impl;
};
}
@@ -0,0 +1,87 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "AssetMemoryAnalyzer_precompiled.h"
#include <CryCommon/IConsole.h>
#include <AzCore/Memory/SystemAllocator.h>
#include "AssetMemoryAnalyzerSystemComponent.h"
#include <IGem.h>
namespace AssetMemoryAnalyzer
{
class AssetMemoryAnalyzerModule
: public CryHooksModule
{
public:
AZ_RTTI(AssetMemoryAnalyzerModule, "{899B0A20-E21D-49BF-ADAF-A2396C27CFCC}", CryHooksModule);
AZ_CLASS_ALLOCATOR(AssetMemoryAnalyzerModule, AZ::OSAllocator, 0);
AssetMemoryAnalyzerModule()
: CryHooksModule()
{
// Push results of [MyComponent]::CreateDescriptor() into m_descriptors here.
m_descriptors.insert(m_descriptors.end(), {
AssetMemoryAnalyzerSystemComponent::CreateDescriptor(),
});
}
/**
* Add required SystemComponents to the SystemEntity.
*/
AZ::ComponentTypeList GetRequiredSystemComponents() const override
{
return AZ::ComponentTypeList{
azrtti_typeid<AssetMemoryAnalyzerSystemComponent>(),
};
}
void OnCrySystemInitialized([[maybe_unused]] ISystem& system, [[maybe_unused]] const SSystemInitParams& systemInitParams) override
{
REGISTER_CVAR2_CB_DEV_ONLY(
"assetmem_enabled",
&m_cvarEnabled,
0,
VF_NULL,
"AssetMemoryAnalyzer: Enable or disable the Asset Memory Analyzer.",
[](ICVar* pArgs)
{
bool enabled = pArgs->GetIVal() ? true : false;
EBUS_EVENT(AssetMemoryAnalyzerRequestBus, SetEnabled, enabled);
}
);
REGISTER_COMMAND_DEV_ONLY(
"assetmem_export_json",
[](IConsoleCmdArgs*) { EBUS_EVENT(AssetMemoryAnalyzerRequestBus, ExportJSONFile, nullptr); },
0,
"AssetMemoryAnalyzer: Export JSON analysis to @log@ directory.");
REGISTER_COMMAND_DEV_ONLY(
"assetmem_export_csv",
[](IConsoleCmdArgs*) { EBUS_EVENT(AssetMemoryAnalyzerRequestBus, ExportCSVFile, nullptr); },
0,
"AssetMemoryAnalyzer: Export CSV analysis to @log@ directory. (Top-level assets only.)");
EBUS_EVENT(AssetMemoryAnalyzerRequestBus, SetEnabled, m_cvarEnabled != 0);
}
private:
int m_cvarEnabled = 0;
};
}
// DO NOT MODIFY THIS LINE UNLESS YOU RENAME THE GEM
// The first parameter should be GemName_GemIdLower
// The second should be the fully qualified name of the class above
AZ_DECLARE_MODULE_CLASS(Gem_AssetMemoryAnalyzer, AssetMemoryAnalyzer::AssetMemoryAnalyzerModule)
@@ -0,0 +1,206 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "AssetMemoryAnalyzer_precompiled.h"
#include <AzCore/Debug/AssetTrackingTypesImpl.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <Common/Memory/VRAMDrillerBus.h>
#include "AssetMemoryAnalyzerSystemComponent.h"
#include "AssetMemoryAnalyzer.h"
#include "DebugImGUI.h"
#include "ExportCSV.h"
#include "ExportJSON.h"
namespace AssetMemoryAnalyzer
{
namespace
{
static const char* GetExportFile(const char* customFilename, const char* extension)
{
static char sharedBuffer[AZ_MAX_PATH_LEN];
if (customFilename)
{
azsnprintf(sharedBuffer, sizeof(sharedBuffer), "@log@/%s", customFilename);
}
else
{
char timestampBuffer[64];
time_t ltime;
time(&ltime);
struct tm timeInfo;
AZ_TRAIT_CTIME_LOCALTIME(&timeInfo, &ltime);
strftime(timestampBuffer, sizeof(timestampBuffer), "@log@/assetmem-%Y-%m-%d-%H-%M-%S.%%s", &timeInfo);
azsnprintf(sharedBuffer, sizeof(sharedBuffer), timestampBuffer, extension);
}
return sharedBuffer;
}
}
static const char* VRAM_CATEGORIES[] =
{
"Texture",
"Buffer",
"Misc"
};
static const char* VRAM_SUBCATEGORIES[] =
{
"Rendertarget",
"Texture",
"Dynamic",
"VB",
"IB",
"CB",
"Other",
"Misc"
};
class AssetMemoryAnalyzerSystemComponent::Impl
{
private:
AZStd::unique_ptr<Analyzer> m_analyzer;
DebugImGUI m_debugImGUI;
ExportCSV m_exportCSV;
ExportJSON m_exportJSON;
friend class AssetMemoryAnalyzerSystemComponent;
};
AssetMemoryAnalyzerSystemComponent::AssetMemoryAnalyzerSystemComponent() : m_impl(new Impl)
{
AZ::AllocatorInstance<AZ::Debug::AssetTrackingAllocator>::Create();
}
AssetMemoryAnalyzerSystemComponent::~AssetMemoryAnalyzerSystemComponent()
{
m_impl.reset(); // Must delete objects before destroying the allocator
AZ::AllocatorInstance<AZ::Debug::AssetTrackingAllocator>::Destroy();
}
void AssetMemoryAnalyzerSystemComponent::Reflect(AZ::ReflectContext* context)
{
if (AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context))
{
serialize->Class<AssetMemoryAnalyzerSystemComponent, AZ::Component>()
->Version(0);
if (AZ::EditContext* ec = serialize->GetEditContext())
{
ec->Class<AssetMemoryAnalyzerSystemComponent>("AssetMemoryAnalyzer", "Provides access to asset memory debugging features")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System", 0xc94d118b))
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
;
}
}
}
void AssetMemoryAnalyzerSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
{
provided.push_back(AZ_CRC("AssetMemoryAnalyzerService", 0x23c52412));
}
void AssetMemoryAnalyzerSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
{
incompatible.push_back(AZ_CRC("AssetMemoryAnalyzerService", 0x23c52412));
}
void AssetMemoryAnalyzerSystemComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
{
(void)required;
}
void AssetMemoryAnalyzerSystemComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent)
{
(void)dependent;
}
const char** AssetMemoryAnalyzerSystemComponent::GetVRAMCategories()
{
return VRAM_CATEGORIES;
}
const char** AssetMemoryAnalyzerSystemComponent::GetVRAMSubCategories()
{
return VRAM_SUBCATEGORIES;
}
bool AssetMemoryAnalyzerSystemComponent::IsEnabled() const
{
return m_impl->m_analyzer.get() != nullptr;
}
AZStd::shared_ptr<FrameAnalysis> AssetMemoryAnalyzerSystemComponent::GetAnalysis()
{
AZStd::shared_ptr<FrameAnalysis> result;
if (m_impl->m_analyzer)
{
result = m_impl->m_analyzer->GetAnalysis();
}
return result;
}
void AssetMemoryAnalyzerSystemComponent::SetEnabled(bool enabled)
{
if (enabled)
{
if (!m_impl->m_analyzer)
{
m_impl->m_analyzer.reset(aznew Analyzer);
}
}
else
{
m_impl->m_analyzer.reset();
}
}
void AssetMemoryAnalyzerSystemComponent::ExportCSVFile(const char* path)
{
const char* outputPath = GetExportFile(path, "csv");
m_impl->m_exportCSV.OutputCSV(outputPath);
}
void AssetMemoryAnalyzerSystemComponent::ExportJSONFile(const char* path)
{
const char* outputPath = GetExportFile(path, "json");
m_impl->m_exportJSON.OutputJSON(outputPath);
}
void AssetMemoryAnalyzerSystemComponent::Init()
{
static_assert(AZ_ARRAY_SIZE(VRAM_CATEGORIES) == Render::Debug::VRAMAllocationCategory::VRAM_CATEGORY_NUMBER_CATEGORIES, "VRAMAllocationCategory has changed length! Fix VRAM_CATEGORIES to match.");
static_assert(AZ_ARRAY_SIZE(VRAM_SUBCATEGORIES) == Render::Debug::VRAMAllocationSubcategory::VRAM_SUBCATEGORY_NUMBER_SUBCATEGORIES, "VRAMAllocationSubcategory has changed length! Fix VRAM_SUBCATEGORIES to match.");
m_impl->m_debugImGUI.Init(this);
m_impl->m_exportCSV.Init(this);
m_impl->m_exportJSON.Init(this);
}
void AssetMemoryAnalyzerSystemComponent::Activate()
{
AssetMemoryAnalyzerRequestBus::Handler::BusConnect();
}
void AssetMemoryAnalyzerSystemComponent::Deactivate()
{
AssetMemoryAnalyzerRequestBus::Handler::BusDisconnect();
}
}
@@ -0,0 +1,67 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/Component/Component.h>
#include <AssetMemoryAnalyzer/AssetMemoryAnalyzerBus.h>
#include <AzCore/std/smart_ptr/shared_ptr.h>
namespace AssetMemoryAnalyzer
{
class FrameAnalysis;
class AssetMemoryAnalyzerSystemComponent
: public AZ::Component
, protected AssetMemoryAnalyzerRequestBus::Handler
{
public:
AZ_COMPONENT(AssetMemoryAnalyzerSystemComponent, "{84428E10-24FF-48A7-B5EC-0A28D25C3C68}");
AssetMemoryAnalyzerSystemComponent();
~AssetMemoryAnalyzerSystemComponent();
static void Reflect(AZ::ReflectContext* context);
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent);
static const char** GetVRAMCategories();
static const char** GetVRAMSubCategories();
bool IsEnabled() const;
////////////////////////////////////////////////////////////////////////
// AssetMemoryAnalyzerRequestBus interface implementation
void SetEnabled(bool enabled) override;
void ExportCSVFile(const char* path) override;
void ExportJSONFile(const char* path) override;
AZStd::shared_ptr<FrameAnalysis> GetAnalysis() override;
////////////////////////////////////////////////////////////////////////
protected:
////////////////////////////////////////////////////////////////////////
// AZ::Component interface implementation
void Init() override;
void Activate() override;
void Deactivate() override;
////////////////////////////////////////////////////////////////////////
private:
class Impl;
private:
AZStd::unique_ptr<Impl> m_impl;
};
}
@@ -0,0 +1,12 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "AssetMemoryAnalyzer_precompiled.h"
@@ -0,0 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <platform.h> // Many CryCommon files require that this is included first.
@@ -0,0 +1,277 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "AssetMemoryAnalyzer_precompiled.h"
#include "AssetMemoryAnalyzer.h"
#include "AssetMemoryAnalyzerSystemComponent.h"
#include "DebugImGUI.h"
#include "FormatUtils.h"
#include <AzCore/Debug/AssetTracking.h>
#include <AzCore/std/sort.h>
#include <imgui/imgui.h>
#include <ImGuiBus.h>
namespace AssetMemoryAnalyzer
{
namespace
{
template<Data::AllocationCategories Category>
struct SortFunctions
{
static bool SortChildAssetsByAllocatedMemory(const Data::AssetInfo* lhs, const Data::AssetInfo* rhs)
{
return lhs->m_totalSummary[(int)Category].m_allocatedMemory > rhs->m_totalSummary[(int)Category].m_allocatedMemory;
}
static bool SortAllocationPointsByAllocatedMemory(const Data::AllocationPoint* lhs, const Data::AllocationPoint* rhs)
{
return (lhs->m_codePoint->m_category == rhs->m_codePoint->m_category) ? (lhs->m_totalAllocatedMemory > rhs->m_totalAllocatedMemory) : (lhs->m_codePoint->m_category == Category);
}
static bool SortChildAssetsByAllocationCount(const Data::AssetInfo* lhs, const Data::AssetInfo* rhs)
{
return lhs->m_totalSummary[(int)Category].m_allocationCount > rhs->m_totalSummary[(int)Category].m_allocationCount;
}
static bool SortAllocationPointsByAllocationCount(const Data::AllocationPoint* lhs, const Data::AllocationPoint* rhs)
{
return (lhs->m_codePoint->m_category == rhs->m_codePoint->m_category) ? (lhs->m_allocations.size() > rhs->m_allocations.size()) : (lhs->m_codePoint->m_category == Category);
}
};
}
static const ImVec4 COLUMN_HEADER_COLOR(0.7f, 0.4f, 0.2f, 1.0f);
static const float COLUMN_WIDTH = 128.0f;
DebugImGUI::DebugImGUI()
{
ImGui::ImGuiUpdateListenerBus::Handler::BusConnect();
}
DebugImGUI::~DebugImGUI()
{
ImGui::ImGuiUpdateListenerBus::Handler::BusDisconnect();
}
void DebugImGUI::Init(AssetMemoryAnalyzerSystemComponent* owner)
{
m_owner = owner;
m_childAssetSortFn = &SortFunctions<Data::AllocationCategories::HEAP>::SortChildAssetsByAllocatedMemory;
m_allocationPointSortFn = &SortFunctions<Data::AllocationCategories::HEAP>::SortAllocationPointsByAllocatedMemory;
}
void DebugImGUI::OnImGuiUpdate()
{
using namespace Data;
// Append to main menu at top of screen.
if (ImGui::BeginMainMenuBar())
{
// Add new menu items.
if (ImGui::BeginMenu("AssetMemoryAnalyzer"))
{
if (ImGui::Button(m_enabled == false ? "Open" : "Close"))
{
ImGui::CloseCurrentPopup();
m_enabled = !m_enabled;
}
if (ImGui::Button("Export JSON"))
{
EBUS_EVENT(AssetMemoryAnalyzerRequestBus, ExportJSONFile, nullptr);
ImGui::CloseCurrentPopup();
}
if (ImGui::Button("Export CSV (top-level only)"))
{
EBUS_EVENT(AssetMemoryAnalyzerRequestBus, ExportCSVFile, nullptr);
ImGui::CloseCurrentPopup();
}
ImGui::EndMenu();
}
ImGui::EndMainMenuBar();
}
if (m_enabled)
{
// Draw the asset memory analysis window and its contents
ImGui::Begin("Asset Memory Analysis", &m_enabled);
#ifndef AZ_TRACK_ASSET_SCOPES
ImGui::TextColored(ImColor(255, 32, 32), "Asset scope tracking disabled in code. Recompile with AZ_TRACK_ASSET_SCOPES defined (see AssetTracking.h).");
#endif
if (!m_owner->IsEnabled())
{
ImGui::TextColored(ImColor(255, 32, 32), "Asset memory analysis must be enabled by setting the \"assetmem_enable\" CVar to 1.");
}
AZStd::shared_ptr<FrameAnalysis> analysis = m_owner->GetAnalysis();
if (analysis)
{
if (ImGui::Button("Heap Allocation Size"))
{
m_childAssetSortFn = &SortFunctions<AllocationCategories::HEAP>::SortChildAssetsByAllocatedMemory;
m_allocationPointSortFn = &SortFunctions<AllocationCategories::HEAP>::SortAllocationPointsByAllocatedMemory;
}
ImGui::SameLine();
if (ImGui::Button("Heap Allocation Count"))
{
m_childAssetSortFn = &SortFunctions<AllocationCategories::HEAP>::SortChildAssetsByAllocationCount;
m_allocationPointSortFn = &SortFunctions<AllocationCategories::HEAP>::SortAllocationPointsByAllocationCount;
}
ImGui::SameLine();
if (ImGui::Button("VRAM Allocation Size"))
{
m_childAssetSortFn = &SortFunctions<AllocationCategories::VRAM>::SortChildAssetsByAllocatedMemory;
m_allocationPointSortFn = &SortFunctions<AllocationCategories::VRAM>::SortAllocationPointsByAllocatedMemory;
}
ImGui::SameLine();
if (ImGui::Button("VRAM Allocation Count"))
{
m_childAssetSortFn = &SortFunctions<AllocationCategories::VRAM>::SortChildAssetsByAllocationCount;
m_allocationPointSortFn = &SortFunctions<AllocationCategories::VRAM>::SortAllocationPointsByAllocationCount;
}
ImGui::SameLine();
if (ImGui::Button("A -> Z"))
{
m_childAssetSortFn = [](const AssetInfo* lhs, const AssetInfo* rhs) { return strcmp(lhs->m_id, rhs->m_id) < 0; };
m_allocationPointSortFn = [](const AllocationPoint* lhs, const AllocationPoint* rhs) {
int cmp = strcmp(lhs->m_codePoint->m_file, rhs->m_codePoint->m_file);
return (cmp < 0) || (cmp == 0 && lhs->m_codePoint->m_line < rhs->m_codePoint->m_line);
};
}
ImGui::Text("Asset/Allocation");
ImGui::SameLine();
ImGui::SetCursorPosX(ImGui::GetWindowWidth() - COLUMN_WIDTH * 2);
ImGui::Text("Heap (#/kB)");
ImGui::SameLine();
ImGui::SetCursorPosX(ImGui::GetWindowWidth() - COLUMN_WIDTH);
ImGui::Text("VRAM (#/kB)");
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(255, 255, 32, 1.0));
OutputLine("Totals", analysis->GetRootAsset().m_totalSummary[(int)AllocationCategories::HEAP], analysis->GetRootAsset().m_totalSummary[(int)AllocationCategories::VRAM]);
ImGui::PopStyleColor();
AZStd::function<void(const AssetInfo*, int depth)> recurse;
recurse = [this, &recurse](const AssetInfo* asset, int depth)
{
AZStd::vector<const AssetInfo*, AZ::OSStdAllocator> childAssetSorter;
childAssetSorter.resize(asset->m_childAssets.size());
AZStd::transform(asset->m_childAssets.begin(), asset->m_childAssets.end(), childAssetSorter.begin(), [](const AssetInfo& ai) { return &ai; });
AZStd::sort(childAssetSorter.begin(), childAssetSorter.end(), m_childAssetSortFn);
m_allocationPointSorter.resize(asset->m_allocationPoints.size());
AZStd::transform(asset->m_allocationPoints.begin(), asset->m_allocationPoints.end(), m_allocationPointSorter.begin(), [](const AllocationPoint& ap) { return &ap; });
AZStd::sort(m_allocationPointSorter.begin(), m_allocationPointSorter.end(), m_allocationPointSortFn);
if (asset->m_id)
{
float prevX = ImGui::GetCursorPosX();
OutputLine(nullptr, asset->m_totalSummary[(int)AllocationCategories::HEAP], asset->m_totalSummary[(int)AllocationCategories::VRAM]);
ImGui::SameLine();
ImGui::SetCursorPosX(prevX);
if (ImGui::TreeNode(asset->m_id))
{
prevX = ImGui::GetCursorPosX();
OutputLine(nullptr, asset->m_localSummary[(int)AllocationCategories::HEAP], asset->m_localSummary[(int)AllocationCategories::VRAM]);
ImGui::SameLine();
ImGui::SetCursorPosX(prevX);
if (ImGui::TreeNode("Scope allocations:"))
{
for (auto ap : m_allocationPointSorter)
{
Summary heapSummary;
Summary vramSummary;
switch (ap->m_codePoint->m_category)
{
case AllocationCategories::HEAP:
ImGui::Text(FormatUtils::FormatCodePoint(*ap->m_codePoint));
heapSummary.m_allocationCount = ap->m_allocations.size();
heapSummary.m_allocatedMemory = ap->m_totalAllocatedMemory;
break;
case AllocationCategories::VRAM:
ImGui::Text("%s", ap->m_codePoint->m_file);
vramSummary.m_allocationCount = ap->m_allocations.size();
vramSummary.m_allocatedMemory = ap->m_totalAllocatedMemory;
break;
}
ImGui::SameLine();
OutputLine(nullptr, heapSummary, vramSummary);
}
ImGui::TreePop();
}
for (auto child : childAssetSorter)
{
recurse(child, depth + 1);
}
ImGui::TreePop();
}
}
else
{
for (auto child : childAssetSorter)
{
recurse(child, depth + 1);
}
}
};
recurse(&analysis->GetRootAsset(), 0);
}
ImGui::End();
}
}
void DebugImGUI::OutputLine(const char* text, const Data::Summary& heapSummary, const Data::Summary& vramSummary)
{
if (text)
{
ImGui::Text(text);
ImGui::SameLine();
}
ImGui::SetCursorPosX(ImGui::GetWindowWidth() - COLUMN_WIDTH * 2);
OutputField(heapSummary);
ImGui::SameLine();
ImGui::SetCursorPosX(ImGui::GetWindowWidth() - COLUMN_WIDTH);
OutputField(vramSummary);
}
void DebugImGUI::OutputField(const Data::Summary& summary)
{
if (summary.m_allocationCount)
{
ImGui::Text("%u / %s", summary.m_allocationCount, FormatUtils::FormatKB(summary.m_allocatedMemory));
}
else
{
ImGui::Text("-- / --");
}
}
}
@@ -0,0 +1,56 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/Component/Component.h>
#include <ImGuiBus.h>
namespace AssetMemoryAnalyzer
{
namespace Data
{
struct AllocationPoint;
struct AssetInfo;
struct Summary;
}
class AssetMemoryAnalyzerSystemComponent;
// This class provides debug UI for the gem using ImGUI.
class DebugImGUI
: public ImGui::ImGuiUpdateListenerBus::Handler
{
public:
AZ_TYPE_INFO(AssetMemoryAnalyzer::DebugImGUI, "{D121DA34-EF16-46C2-AFC4-A1EE69DA0851}");
AZ_CLASS_ALLOCATOR(DebugImGUI, AZ::OSAllocator, 0);
DebugImGUI();
~DebugImGUI();
void Init(AssetMemoryAnalyzerSystemComponent* owner);
// ImGuiUpdateListenerBus
void OnImGuiUpdate() override;
private:
void OutputLine(const char* text, const Data::Summary& heapSummary, const Data::Summary& vramSummary);
void OutputField(const Data::Summary& summary);
AssetMemoryAnalyzerSystemComponent* m_owner;
bool (*m_childAssetSortFn)(const Data::AssetInfo* lhs, const Data::AssetInfo* rhs) = nullptr;
AZStd::vector<const Data::AssetInfo*, AZ::OSStdAllocator> m_childAssetSorter;
bool (*m_allocationPointSortFn)(const Data::AllocationPoint* lhs, const Data::AllocationPoint* rhs) = nullptr;
AZStd::vector<const Data::AllocationPoint*, AZ::OSStdAllocator> m_allocationPointSorter;
bool m_enabled = false;
};
}
@@ -0,0 +1,86 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "AssetMemoryAnalyzer_precompiled.h"
#include "ExportCSV.h"
#include "AssetMemoryAnalyzer.h"
#include "AssetMemoryAnalyzerSystemComponent.h"
#include "FormatUtils.h"
#include <AzCore/IO/FileIO.h>
namespace AssetMemoryAnalyzer
{
ExportCSV::ExportCSV()
{
}
ExportCSV::~ExportCSV()
{
}
void ExportCSV::Init(AssetMemoryAnalyzerSystemComponent* owner)
{
m_owner = owner;
}
void ExportCSV::OutputCSV(const char* path)
{
using namespace Data;
AZStd::shared_ptr<FrameAnalysis> analysis = m_owner->GetAnalysis();
if (!analysis)
{
return;
}
auto fs = AZ::IO::FileIOBase::GetDirectInstance();
AZ::IO::HandleType hdl;
if (!fs->Open(path, AZ::IO::OpenMode::ModeWrite, hdl))
{
AZ_Assert(false, "Unable to open file for writing: %s", path);
}
const AZStd::string header("Label,Heap Count,Heap kb,VRAM Count,VRAM kb\n");
fs->Write(hdl, header.c_str(), header.length());
char lineBuffer[4096];
const auto& rootAsset = analysis->GetRootAsset();
size_t length = snprintf(lineBuffer, sizeof(lineBuffer), "<uncategorized>,%d,%0.2f,%d,%0.2f\n",
rootAsset.m_localSummary[(int)AllocationCategories::HEAP].m_allocationCount,
rootAsset.m_localSummary[(int)AllocationCategories::HEAP].m_allocatedMemory / 1024.0f,
rootAsset.m_localSummary[(int)AllocationCategories::VRAM].m_allocationCount,
rootAsset.m_localSummary[(int)AllocationCategories::VRAM].m_allocatedMemory / 1024.0f
);
fs->Write(hdl, lineBuffer, length);
for (const auto& child : analysis->GetRootAsset().m_childAssets)
{
length = snprintf(lineBuffer, sizeof(lineBuffer), "%s,%d,%0.2f,%d,%0.2f\n",
child.m_id,
child.m_totalSummary[(int)AllocationCategories::HEAP].m_allocationCount,
child.m_totalSummary[(int)AllocationCategories::HEAP].m_allocatedMemory / 1024.0f,
child.m_totalSummary[(int)AllocationCategories::VRAM].m_allocationCount,
child.m_totalSummary[(int)AllocationCategories::VRAM].m_allocatedMemory / 1024.0f
);
fs->Write(hdl, lineBuffer, length);
}
fs->Close(hdl);
AZ_Printf("Debug", "Exported asset allocation list to %s", path);
}
}
@@ -0,0 +1,37 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/Component/Component.h>
namespace AssetMemoryAnalyzer
{
class AssetMemoryAnalyzerSystemComponent;
// This class provides the service of exporting a capture of asset memory to a JSON file that is viewable in the web viewer.
class ExportCSV
{
public:
AZ_TYPE_INFO(AssetMemoryAnalyzer::ExportCSV, "{FEA7D137-EA93-4366-85C2-DCBCE00B3376}");
AZ_CLASS_ALLOCATOR(ExportCSV, AZ::OSAllocator, 0);
ExportCSV();
~ExportCSV();
void Init(AssetMemoryAnalyzerSystemComponent* owner);
void OutputCSV(const char* path);
private:
AssetMemoryAnalyzerSystemComponent* m_owner;
};
}
@@ -0,0 +1,188 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "AssetMemoryAnalyzer_precompiled.h"
#include "ExportJSON.h"
#include "AssetMemoryAnalyzer.h"
#include "AssetMemoryAnalyzerSystemComponent.h"
#include "FormatUtils.h"
#include <AzCore/Debug/AssetTracking.h>
#include <Common/Memory/VRAMDrillerBus.h>
#include <AzCore/IO/FileIO.h>
#include <AzCore/JSON/filewritestream.h>
#include <AzCore/JSON/rapidjson.h>
#include <AzCore/JSON/prettywriter.h>
#include <AzCore/std/sort.h>
#include <imgui/imgui.h>
#include <ImGuiBus.h>
namespace AssetMemoryAnalyzer
{
namespace
{
template<class WriterT>
static void OutputAllocationInfo(WriterT& writer, size_t count, size_t bytes)
{
writer.StartObject();
writer.Key("count");
writer.Int((int)count);
writer.Key("kb");
writer.String(FormatUtils::FormatKB(bytes));
writer.EndObject();
}
template<class WriterT>
static void OutputAllocationInfo(WriterT& writer, const Data::Summary& summary)
{
OutputAllocationInfo(writer, summary.m_allocationCount, summary.m_allocatedMemory);
}
}
ExportJSON::ExportJSON()
{
}
ExportJSON::~ExportJSON()
{
}
void ExportJSON::Init(AssetMemoryAnalyzerSystemComponent* owner)
{
m_owner = owner;
}
void ExportJSON::OutputJSON(const char* path)
{
using namespace Data;
using namespace rapidjson;
AZStd::shared_ptr<FrameAnalysis> analysis = m_owner->GetAnalysis();
if (!analysis)
{
return;
}
StringBuffer buff;
PrettyWriter<StringBuffer> writer(buff);
size_t idCounter = 0;
AZStd::function<void(const AssetInfo&, int)> recurse;
recurse = [&recurse, &writer, &idCounter](const AssetInfo& asset, int depth)
{
writer.StartObject();
writer.Key("id");
writer.Int(idCounter++);
writer.Key("label");
writer.String(asset.m_id ? asset.m_id : "Root");
writer.Key("heap");
OutputAllocationInfo(writer, asset.m_totalSummary[(int)AllocationCategories::HEAP]);
writer.Key("vram");
OutputAllocationInfo(writer, asset.m_totalSummary[(int)AllocationCategories::VRAM]);
if (!asset.m_allocationPoints.empty() || !asset.m_childAssets.empty())
{
writer.Key("_children");
writer.StartArray();
if (!asset.m_allocationPoints.empty())
{
writer.StartObject();
writer.Key("id");
writer.Int(idCounter++);
writer.Key("label");
writer.String("<local allocations>");
writer.Key("heap");
OutputAllocationInfo(writer, asset.m_localSummary[(int)AllocationCategories::HEAP]);
writer.Key("vram");
OutputAllocationInfo(writer, asset.m_localSummary[(int)AllocationCategories::VRAM]);
writer.Key("_children");
writer.StartArray();
for (const auto& ap : asset.m_allocationPoints)
{
Summary heapSummary;
Summary vramSummary;
writer.StartObject();
writer.Key("id");
writer.Int(idCounter++);
writer.Key("label");
switch (ap.m_codePoint->m_category)
{
case AllocationCategories::HEAP:
writer.String(FormatUtils::FormatCodePoint(*ap.m_codePoint));
heapSummary.m_allocationCount = ap.m_allocations.size();
heapSummary.m_allocatedMemory = ap.m_totalAllocatedMemory;
break;
case AllocationCategories::VRAM:
writer.String(ap.m_codePoint->m_file);
vramSummary.m_allocationCount = ap.m_allocations.size();
vramSummary.m_allocatedMemory = ap.m_totalAllocatedMemory;
break;
}
writer.Key("heap");
OutputAllocationInfo(writer, heapSummary);
writer.Key("vram");
OutputAllocationInfo(writer, vramSummary);
writer.EndObject();
}
writer.EndArray();
writer.EndObject();
}
for (const auto& childInfo : asset.m_childAssets)
{
recurse(childInfo, depth + 1);
}
writer.EndArray();
}
writer.EndObject();
};
writer.StartArray();
recurse(analysis->GetRootAsset(), 0);
writer.EndArray();
auto fs = AZ::IO::FileIOBase::GetDirectInstance();
AZ::IO::HandleType hdl;
if (!fs->Open(path, AZ::IO::OpenMode::ModeWrite, hdl))
{
AZ_Assert(false, "Unable to open file for writing: %s", path);
}
fs->Write(hdl, buff.GetString(), buff.GetSize());
fs->Close(hdl);
AZ_Printf("Debug", "Exported asset allocation map to %s", path);
}
}
@@ -0,0 +1,36 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/Component/Component.h>
namespace AssetMemoryAnalyzer
{
class AssetMemoryAnalyzerSystemComponent;
// This class provides the service of exporting a capture of asset memory to a JSON file that is viewable in the web viewer.
class ExportJSON
{
public:
AZ_TYPE_INFO(AssetMemoryAnalyzer::ExportJSON, "{AA85F7E0-8FAF-43BC-9C09-6411270AE3E7}");
AZ_CLASS_ALLOCATOR(ExportJSON, AZ::OSAllocator, 0);
ExportJSON();
~ExportJSON();
void Init(AssetMemoryAnalyzerSystemComponent* owner);
void OutputJSON(const char* path);
private:
AssetMemoryAnalyzerSystemComponent* m_owner;
};
}
@@ -0,0 +1,41 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "AssetMemoryAnalyzer_precompiled.h"
#include "FormatUtils.h"
#include "AssetMemoryAnalyzer.h"
#include <AzFramework/StringFunc/StringFunc.h>
namespace AssetMemoryAnalyzer
{
namespace FormatUtils
{
const char* FormatCodePoint(const Data::CodePoint& cp)
{
static char buff[1024];
azsnprintf(buff, sizeof(buff), "%s:%d", cp.m_file, cp.m_line);
return buff;
}
const char* FormatKB(size_t bytes)
{
static char buff[32];
int len = azsnprintf(buff, sizeof(buff), "%0.2f", bytes / 1024.0f);
AzFramework::StringFunc::NumberFormatting::GroupDigits(buff, sizeof(buff), len - 3);
return buff;
}
}
}
@@ -0,0 +1,31 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
namespace AssetMemoryAnalyzer
{
namespace Data
{
struct CodePoint;
}
namespace FormatUtils
{
// Formats a location in code to a single line of human-readable text. Returns a pointer to the resulting string.
// WARNING: Returns pointer to an internal static buffer for performance. Single-threaded access only!
extern const char* FormatCodePoint(const Data::CodePoint& cp);
// Formats a byte value to be easily read in kilobytes. Returns a pointer to the resulting string.
// WARNING: Returns pointer to an internal static buffer for performance. Single-threaded access only!
extern const char* FormatKB(size_t bytes);
}
}
@@ -0,0 +1,78 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "AssetMemoryAnalyzer_precompiled.h"
#include <AzTest/AzTest.h>
#include <AzCore/Component/ComponentApplication.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AssetMemoryAnalyzer/AssetMemoryAnalyzerBus.h>
#include <../Source/AssetMemoryAnalyzer.h>
#include <../Source/AssetMemoryAnalyzerSystemComponent.h>
using namespace AssetMemoryAnalyzer;
static AZ::IAllocator* testalloc = nullptr;
class AssetMemoryAnalyzerTest
: public UnitTest::AllocatorsTestFixture
{
protected:
void SetUp() override
{
AllocatorsTestFixture::SetUp();
testalloc = &AZ::AllocatorInstance<AZ::SystemAllocator>::GetAllocator();
AZ::ComponentApplication::Descriptor desc;
desc.m_useExistingAllocator = true;
desc.m_enableDrilling = false;
m_app = new (&m_appStorage) AZ::ComponentApplication;
m_systemEntity = m_app->Create(desc);
m_app->RegisterComponentDescriptor(AssetMemoryAnalyzerSystemComponent::CreateDescriptor());
m_gemSystemComponent = m_systemEntity->CreateComponent<AssetMemoryAnalyzerSystemComponent>();
m_systemEntity->Init();
m_systemEntity->Activate();
}
void TearDown() override
{
m_app->Destroy();
m_app->~ComponentApplication();
AllocatorsTestFixture::TearDown();
}
AZStd::aligned_storage_for_t<AZ::ComponentApplication> m_appStorage;
AZ::ComponentApplication* m_app = nullptr;
AZ::Entity* m_systemEntity = nullptr;
AZ::Component* m_gemSystemComponent = nullptr;
};
TEST_F(AssetMemoryAnalyzerTest, BasicTest)
{
AZStd::shared_ptr<FrameAnalysis> analysis;
AssetMemoryAnalyzerRequestBus::BroadcastResult(analysis, &AssetMemoryAnalyzerRequests::GetAnalysis);
EXPECT_FALSE(analysis.get());
AssetMemoryAnalyzerRequestBus::Broadcast(&AssetMemoryAnalyzerRequests::SetEnabled, true);
AssetMemoryAnalyzerRequestBus::BroadcastResult(analysis, &AssetMemoryAnalyzerRequests::GetAnalysis);
ASSERT_TRUE(analysis.get());
#ifndef AZ_TRACK_ASSET_SCOPES
// No recordings should exist if analysis is disabled
ASSERT_TRUE(analysis->GetAllocationPoints().empty());
#endif
}
AZ_UNIT_TEST_HOOK(DEFAULT_UNIT_TEST_ENV);
@@ -0,0 +1,28 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(FILES
Source/AssetMemoryAnalyzer_precompiled.cpp
Source/AssetMemoryAnalyzer_precompiled.h
Include/AssetMemoryAnalyzer/AssetMemoryAnalyzerBus.h
Source/AssetMemoryAnalyzer.cpp
Source/AssetMemoryAnalyzer.h
Source/AssetMemoryAnalyzerSystemComponent.cpp
Source/AssetMemoryAnalyzerSystemComponent.h
Source/DebugImGUI.cpp
Source/DebugImGUI.h
Source/ExportCSV.cpp
Source/ExportCSV.h
Source/ExportJSON.cpp
Source/ExportJSON.h
Source/FormatUtils.cpp
Source/FormatUtils.h
)
@@ -0,0 +1,14 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(FILES
Source/AssetMemoryAnalyzerModule.cpp
)
@@ -0,0 +1,14 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(FILES
Tests/AssetMemoryAnalyzerTest.cpp
)
@@ -0,0 +1,40 @@
---
name: Bug report
about: Create a report to help us improve
---
**Describe the bug**
A clear and concise description of what the bug is.
**Tabulator Info**
- Which version of Tabulator are you using?
- Post a copy of your construct object if possible so we can see how your table is setup
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.
@@ -0,0 +1,17 @@
---
name: Feature request
about: Suggest an idea for this project
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
@@ -0,0 +1,11 @@
---
name: Question
about: Please ask questions on Stack Overflow, NOT on GitHub :)
---
Please ask questions on www.stackoverflow.com the issues list is now reserved for feature requests and bug reports.
Cheers
Oli :)
@@ -0,0 +1,6 @@
*.sublime-project
*.sublime-workspace
node_modules/
examples/
npm-debug.log
@@ -0,0 +1,46 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
## Enforcement
The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2015-2018 Oli Folkerd
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@@ -0,0 +1,84 @@
![Tabulator Table](http://olifolkerd.github.io/tabulator/images/tabulator.png)
### Version 4.1 Out Now!
An easy to use interactive table generation JavaScript library
Full documentation & demos can be found at: [http://tabulator.info](http://tabulator.info)
***
![Tabulator Table](http://tabulator.info/images/tabulator_table.jpg)
***
NPM Package Changed
================================
jQuery was removed as a dependency in the 4.0 release, so Tabulator has moved in NPM from the old [jquery.tabulator](https://www.npmjs.com/package/jquery.tabulator) package to the new [tabulator-tables](https://www.npmjs.com/package/tabulator-tables) package.
Features
================================
Tabulator allows you to create interactive tables in seconds from any HTML Table, Javascript Array or JSON formatted data.
Simply include the library and the css in your project and you're away!
Tabulator is packed with useful features including:
![Tabulator Features](http://olifolkerd.github.io/tabulator/images/featurelist_share.png)
Frontend Framework Support
================================
Tabulator is built to work with all the major front end JavaScript frameworks including React, Angular and Vue.
Setup
================================
Setting up tabulator could not be simpler.
Include the library and the css
```html
<link href="dist/css/tabulator.min.css" rel="stylesheet">
<script type="text/javascript" src="dist/js/tabulator.min.js"></script>
```
Create an element to hold the table
```html
<div id="example-table"></div>
```
Turn the element into a tabulator with some simple javascript
```js
var table = new Tabulator("#example-table", {});
```
### Bower Installation
To get Tabulator via the Bower package manager, open a terminal in your project directory and run the following commmand:
```
bower install tabulator --save
```
### NPM Installation
To get Tabulator via the NPM package manager, open a terminal in your project directory and run the following commmand:
```
npm install tabulator-tables --save
```
### CDN - UNPKG
To access Tabulator directly from the UNPKG CDN servers, include the following two lines at the start of your project, instead of the localy hosted versions:
```html
<link href="https://unpkg.com/tabulator-tables@4.1.2/dist/css/tabulator.min.css" rel="stylesheet">
<script type="text/javascript" src="https://unpkg.com/tabulator-tables@4.1.2/dist/js/tabulator.min.js"></script>
```
Coming Soon
================================
Tabulator is actively under development and I plan to have even more useful features implemented soon, including:
- Data Reactivity
- Custom Row Templates
- Additional Editors and Formatters
- Print Styling
- Multi Cell Editing
- Cell Selection
Get in touch if there are any features you feel Tabulator needs.
@@ -0,0 +1,40 @@
{
"name": "tabulator",
"main": "dist/js/tabulator.js",
"version": "4.1.2",
"description": "Interactive table generation JavaScript library",
"keywords": [
"table",
"grid",
"datagrid",
"tabulator",
"editable",
"cookie",
"jquery",
"jqueryui",
"sort",
"format",
"resizable",
"list",
"scrollable",
"ajax",
"json",
"widget",
"jquery",
"react",
"angular",
"vue"
],
"authors": [
"Oli Folkerd"
],
"license": "MIT",
"homepage": "https://github.com/olifolkerd/tabulator",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
]
}
@@ -0,0 +1,804 @@
/* Tabulator v4.1.2 (c) Oliver Folkerd */
.tabulator {
position: relative;
background-color: #fff;
overflow: hidden;
font-size: 14px;
text-align: left;
width: 100%;
max-width: 100%;
margin-bottom: 20px;
-ms-transform: translatez(0);
transform: translatez(0);
}
.tabulator[tabulator-layout="fitDataFill"] .tabulator-tableHolder .tabulator-table {
min-width: 100%;
}
.tabulator.tabulator-block-select {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.tabulator .tabulator-header {
position: relative;
box-sizing: border-box;
width: 100%;
border-bottom: 2px solid #ddd;
background-color: #fff;
font-weight: bold;
white-space: nowrap;
overflow: hidden;
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
-o-user-select: none;
}
.tabulator .tabulator-header .tabulator-col {
display: inline-block;
position: relative;
box-sizing: border-box;
background-color: #fff;
text-align: left;
vertical-align: bottom;
overflow: hidden;
}
.tabulator .tabulator-header .tabulator-col.tabulator-moving {
position: absolute;
border: 1px solid #ddd;
background: #e6e6e6;
pointer-events: none;
}
.tabulator .tabulator-header .tabulator-col .tabulator-col-content {
box-sizing: border-box;
position: relative;
padding: 8px;
}
.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title {
box-sizing: border-box;
width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
vertical-align: bottom;
}
.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title .tabulator-title-editor {
box-sizing: border-box;
width: 100%;
border: 1px solid #999;
padding: 1px;
background: #fff;
}
.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-arrow {
display: inline-block;
position: absolute;
top: 14px;
right: 8px;
width: 0;
height: 0;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid #bbb;
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-group .tabulator-col-group-cols {
position: relative;
display: -ms-flexbox;
display: flex;
border-top: 1px solid #ddd;
overflow: hidden;
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-group .tabulator-col-group-cols .tabulator-col:last-child {
margin-right: -1px;
}
.tabulator .tabulator-header .tabulator-col:first-child .tabulator-col-resize-handle.prev {
display: none;
}
.tabulator .tabulator-header .tabulator-col.ui-sortable-helper {
position: absolute;
background-color: #e6e6e6 !important;
border: 1px solid #ddd;
}
.tabulator .tabulator-header .tabulator-col .tabulator-header-filter {
position: relative;
box-sizing: border-box;
margin-top: 2px;
width: 100%;
text-align: center;
}
.tabulator .tabulator-header .tabulator-col .tabulator-header-filter textarea {
height: auto !important;
}
.tabulator .tabulator-header .tabulator-col .tabulator-header-filter svg {
margin-top: 3px;
}
.tabulator .tabulator-header .tabulator-col .tabulator-header-filter input::-ms-clear {
width: 0;
height: 0;
}
.tabulator .tabulator-header .tabulator-col.tabulator-sortable .tabulator-col-title {
padding-right: 25px;
}
.tabulator .tabulator-header .tabulator-col.tabulator-sortable:hover {
cursor: pointer;
background-color: #e6e6e6;
}
.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="none"] .tabulator-col-content .tabulator-arrow {
border-top: none;
border-bottom: 6px solid #bbb;
}
.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="asc"] .tabulator-col-content .tabulator-arrow {
border-top: none;
border-bottom: 6px solid #666;
}
.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="desc"] .tabulator-col-content .tabulator-arrow {
border-top: 6px solid #666;
border-bottom: none;
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical .tabulator-col-content .tabulator-col-title {
-webkit-writing-mode: vertical-rl;
-ms-writing-mode: tb-rl;
writing-mode: vertical-rl;
text-orientation: mixed;
display: -ms-flexbox;
display: flex;
-ms-flex-align: center;
align-items: center;
-ms-flex-pack: center;
justify-content: center;
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-col-vertical-flip .tabulator-col-title {
-ms-transform: rotate(180deg);
transform: rotate(180deg);
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable .tabulator-col-title {
padding-right: 0;
padding-top: 20px;
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable.tabulator-col-vertical-flip .tabulator-col-title {
padding-right: 0;
padding-bottom: 20px;
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable .tabulator-arrow {
right: calc(50% - 6px);
}
.tabulator .tabulator-header .tabulator-frozen {
display: inline-block;
position: absolute;
z-index: 10;
}
.tabulator .tabulator-header .tabulator-frozen.tabulator-frozen-left {
border-right: 2px solid #ddd;
}
.tabulator .tabulator-header .tabulator-frozen.tabulator-frozen-right {
border-left: 2px solid #ddd;
}
.tabulator .tabulator-header .tabulator-calcs-holder {
box-sizing: border-box;
width: 100%;
background: white !important;
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
overflow: hidden;
}
.tabulator .tabulator-header .tabulator-calcs-holder .tabulator-row {
background: white !important;
}
.tabulator .tabulator-header .tabulator-calcs-holder .tabulator-row .tabulator-col-resize-handle {
display: none;
}
.tabulator .tabulator-header .tabulator-frozen-rows-holder {
min-width: 400%;
}
.tabulator .tabulator-header .tabulator-frozen-rows-holder:empty {
display: none;
}
.tabulator .tabulator-tableHolder {
position: relative;
width: 100%;
white-space: nowrap;
overflow: auto;
-webkit-overflow-scrolling: touch;
}
.tabulator .tabulator-tableHolder:focus {
outline: none;
}
.tabulator .tabulator-tableHolder .tabulator-placeholder {
box-sizing: border-box;
display: -ms-flexbox;
display: flex;
-ms-flex-align: center;
align-items: center;
width: 100%;
}
.tabulator .tabulator-tableHolder .tabulator-placeholder[tabulator-render-mode="virtual"] {
position: absolute;
top: 0;
left: 0;
height: 100%;
}
.tabulator .tabulator-tableHolder .tabulator-placeholder span {
display: inline-block;
margin: 0 auto;
padding: 10px;
color: #000;
font-weight: bold;
font-size: 20px;
}
.tabulator .tabulator-tableHolder .tabulator-table {
position: relative;
display: inline-block;
background-color: #fff;
white-space: nowrap;
overflow: visible;
}
.tabulator .tabulator-tableHolder .tabulator-table .tabulator-row.tabulator-calcs {
font-weight: bold;
background: #ececec !important;
}
.tabulator .tabulator-tableHolder .tabulator-table .tabulator-row.tabulator-calcs.tabulator-calcs-top {
border-bottom: 2px solid #ddd;
}
.tabulator .tabulator-tableHolder .tabulator-table .tabulator-row.tabulator-calcs.tabulator-calcs-bottom {
border-top: 2px solid #ddd;
}
.tabulator .tabulator-col-resize-handle {
position: absolute;
right: 0;
top: 0;
bottom: 0;
width: 5px;
}
.tabulator .tabulator-col-resize-handle.prev {
left: 0;
right: auto;
}
.tabulator .tabulator-col-resize-handle:hover {
cursor: ew-resize;
}
.tabulator .tabulator-footer {
padding: 5px 10px;
border-top: 2px solid #ddd;
text-align: right;
font-weight: bold;
white-space: nowrap;
-ms-user-select: none;
user-select: none;
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
-o-user-select: none;
}
.tabulator .tabulator-footer .tabulator-calcs-holder {
box-sizing: border-box;
width: calc(100% + 20px);
margin: -5px -10px 5px -10px;
text-align: left;
background: white !important;
border-bottom: 1px solid #ddd;
border-top: 1px solid #ddd;
overflow: hidden;
}
.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row {
background: white !important;
}
.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row .tabulator-col-resize-handle {
display: none;
}
.tabulator .tabulator-footer .tabulator-calcs-holder:only-child {
margin-bottom: -5px;
border-bottom: none;
}
.tabulator .tabulator-footer .tabulator-pages {
margin: 0 7px;
}
.tabulator .tabulator-footer .tabulator-page {
display: inline-block;
margin: 0 2px;
border: 1px solid #ddd;
border-radius: 3px;
padding: 2px 5px;
background: rgba(255, 255, 255, 0.2);
font-family: inherit;
font-weight: inherit;
font-size: inherit;
}
.tabulator .tabulator-footer .tabulator-page.active {
color: #d00;
}
.tabulator .tabulator-footer .tabulator-page:disabled {
opacity: .5;
}
.tabulator .tabulator-footer .tabulator-page:not(.disabled):hover {
cursor: pointer;
background: rgba(0, 0, 0, 0.2);
color: #fff;
}
.tabulator .tabulator-loader {
position: absolute;
display: -ms-flexbox;
display: flex;
-ms-flex-align: center;
align-items: center;
top: 0;
left: 0;
z-index: 100;
height: 100%;
width: 100%;
background: rgba(0, 0, 0, 0.4);
text-align: center;
}
.tabulator .tabulator-loader .tabulator-loader-msg {
display: inline-block;
margin: 0 auto;
padding: 10px 20px;
border-radius: 10px;
background: #fff;
font-weight: bold;
font-size: 16px;
}
.tabulator .tabulator-loader .tabulator-loader-msg.tabulator-loading {
border: 4px solid #333;
color: #000;
}
.tabulator .tabulator-loader .tabulator-loader-msg.tabulator-error {
border: 4px solid #D00;
color: #590000;
}
.tabulator.table-striped .tabulator-row:nth-child(even) {
background-color: #f9f9f9;
}
.tabulator.table-bordered {
border: 1px solid #ddd;
}
.tabulator.table-bordered .tabulator-header .tabulator-col {
border-right: 1px solid #ddd;
}
.tabulator.table-bordered .tabulator-tableHolder .tabulator-table .tabulator-row .tabulator-cell {
border-right: 1px solid #ddd;
}
.tabulator.table-condensed .tabulator-header .tabulator-col .tabulator-col-content {
padding: 5px;
}
.tabulator.table-condensed .tabulator-tableHolder .tabulator-table .tabulator-row {
min-height: 24px;
}
.tabulator.table-condensed .tabulator-tableHolder .tabulator-table .tabulator-row .tabulator-cell {
padding: 5px;
}
.tabulator .tabulator-tableHolder .tabulator-table .tabulator-row.active {
background: #f5f5f5 !important;
}
.tabulator .tabulator-tableHolder .tabulator-table .tabulator-row.success {
background: #dff0d8 !important;
}
.tabulator .tabulator-tableHolder .tabulator-table .tabulator-row.info {
background: #d9edf7 !important;
}
.tabulator .tabulator-tableHolder .tabulator-table .tabulator-row.warning {
background: #fcf8e3 !important;
}
.tabulator .tabulator-tableHolder .tabulator-table .tabulator-row.danger {
background: #f2dede !important;
}
.tabulator-row {
position: relative;
box-sizing: border-box;
min-height: 30px;
background-color: #fff;
border-bottom: 1px solid #ddd;
}
.tabulator-row.tabulator-selectable:hover {
background-color: #f5f5f5 !important;
cursor: pointer;
}
.tabulator-row.tabulator-selected {
background-color: #9ABCEA;
}
.tabulator-row.tabulator-selected:hover {
background-color: #769BCC;
cursor: pointer;
}
.tabulator-row.tabulator-moving {
position: absolute;
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
pointer-events: none !important;
z-index: 15;
}
.tabulator-row .tabulator-row-resize-handle {
position: absolute;
right: 0;
bottom: 0;
left: 0;
height: 5px;
}
.tabulator-row .tabulator-row-resize-handle.prev {
top: 0;
bottom: auto;
}
.tabulator-row .tabulator-row-resize-handle:hover {
cursor: ns-resize;
}
.tabulator-row .tabulator-frozen {
display: inline-block;
position: absolute;
background-color: inherit;
z-index: 10;
}
.tabulator-row .tabulator-frozen.tabulator-frozen-left {
border-right: 2px solid #ddd;
}
.tabulator-row .tabulator-frozen.tabulator-frozen-right {
border-left: 2px solid #ddd;
}
.tabulator-row .tabulator-responsive-collapse {
box-sizing: border-box;
padding: 5px;
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
}
.tabulator-row .tabulator-responsive-collapse:empty {
display: none;
}
.tabulator-row .tabulator-responsive-collapse table {
font-size: 14px;
}
.tabulator-row .tabulator-responsive-collapse table tr td {
position: relative;
}
.tabulator-row .tabulator-responsive-collapse table tr td:first-of-type {
padding-right: 10px;
}
.tabulator-row .tabulator-cell {
display: inline-block;
position: relative;
box-sizing: border-box;
padding: 8px;
vertical-align: middle;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.tabulator-row .tabulator-cell:last-of-type {
border-right: none;
}
.tabulator-row .tabulator-cell.tabulator-editing {
border: 1px solid #1D68CD;
padding: 0;
}
.tabulator-row .tabulator-cell.tabulator-editing input, .tabulator-row .tabulator-cell.tabulator-editing select {
border: 1px;
background: transparent;
}
.tabulator-row .tabulator-cell.tabulator-validation-fail {
border: 1px solid #dd0000;
}
.tabulator-row .tabulator-cell.tabulator-validation-fail input, .tabulator-row .tabulator-cell.tabulator-validation-fail select {
border: 1px;
background: transparent;
color: #dd0000;
}
.tabulator-row .tabulator-cell:first-child .tabulator-col-resize-handle.prev {
display: none;
}
.tabulator-row .tabulator-cell.tabulator-row-handle {
display: -ms-inline-flexbox;
display: inline-flex;
-ms-flex-align: center;
align-items: center;
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
-o-user-select: none;
}
.tabulator-row .tabulator-cell.tabulator-row-handle .tabulator-row-handle-box {
width: 80%;
}
.tabulator-row .tabulator-cell.tabulator-row-handle .tabulator-row-handle-box .tabulator-row-handle-bar {
width: 100%;
height: 3px;
margin-top: 2px;
background: #666;
}
.tabulator-row .tabulator-cell .tabulator-data-tree-branch {
display: inline-block;
vertical-align: middle;
height: 9px;
width: 7px;
margin-top: -9px;
margin-right: 5px;
border-bottom-left-radius: 1px;
border-left: 2px solid #ddd;
border-bottom: 2px solid #ddd;
}
.tabulator-row .tabulator-cell .tabulator-data-tree-control {
display: -ms-inline-flexbox;
display: inline-flex;
-ms-flex-pack: center;
justify-content: center;
-ms-flex-align: center;
align-items: center;
vertical-align: middle;
height: 11px;
width: 11px;
margin-right: 5px;
border: 1px solid #333;
border-radius: 2px;
background: rgba(0, 0, 0, 0.1);
overflow: hidden;
}
.tabulator-row .tabulator-cell .tabulator-data-tree-control:hover {
cursor: pointer;
background: rgba(0, 0, 0, 0.2);
}
.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-collapse {
display: inline-block;
position: relative;
height: 7px;
width: 1px;
background: transparent;
}
.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-collapse:after {
position: absolute;
content: "";
left: -3px;
top: 3px;
height: 1px;
width: 7px;
background: #333;
}
.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-expand {
display: inline-block;
position: relative;
height: 7px;
width: 1px;
background: #333;
}
.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-expand:after {
position: absolute;
content: "";
left: -3px;
top: 3px;
height: 1px;
width: 7px;
background: #333;
}
.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle {
display: -ms-inline-flexbox;
display: inline-flex;
-ms-flex-align: center;
align-items: center;
-ms-flex-pack: center;
justify-content: center;
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
-o-user-select: none;
height: 15px;
width: 15px;
border-radius: 20px;
background: #666;
color: #fff;
font-weight: bold;
font-size: 1.1em;
}
.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle:hover {
opacity: .7;
}
.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle.open .tabulator-responsive-collapse-toggle-close {
display: initial;
}
.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle.open .tabulator-responsive-collapse-toggle-open {
display: none;
}
.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle .tabulator-responsive-collapse-toggle-close {
display: none;
}
.tabulator-row.tabulator-group {
box-sizing: border-box;
border-bottom: 1px solid #999;
border-right: 1px solid #ddd;
border-top: 1px solid #999;
padding: 5px;
padding-left: 10px;
background: #fafafa;
font-weight: bold;
min-width: 100%;
}
.tabulator-row.tabulator-group:hover {
cursor: pointer;
background-color: rgba(0, 0, 0, 0.1);
}
.tabulator-row.tabulator-group.tabulator-group-visible .tabulator-arrow {
margin-right: 10px;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-top: 6px solid #666;
border-bottom: 0;
}
.tabulator-row.tabulator-group.tabulator-group-level-1 .tabulator-arrow {
margin-left: 20px;
}
.tabulator-row.tabulator-group.tabulator-group-level-2 .tabulator-arrow {
margin-left: 40px;
}
.tabulator-row.tabulator-group.tabulator-group-level-3 .tabulator-arrow {
margin-left: 60px;
}
.tabulator-row.tabulator-group.tabulator-group-level-4 .tabulator-arrow {
margin-left: 80px;
}
.tabulator-row.tabulator-group.tabulator-group-level-5 .tabulator-arrow {
margin-left: 100px;
}
.tabulator-row.tabulator-group .tabulator-arrow {
display: inline-block;
width: 0;
height: 0;
margin-right: 16px;
border-top: 6px solid transparent;
border-bottom: 6px solid transparent;
border-right: 0;
border-left: 6px solid #666;
vertical-align: middle;
}
.tabulator-row.tabulator-group span {
margin-left: 10px;
color: #666;
}
.tabulator-edit-select-list {
position: absolute;
display: inline-block;
box-sizing: border-box;
max-height: 200px;
background: #fff;
border: 1px solid #ddd;
font-size: 14px;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
z-index: 10000;
}
.tabulator-edit-select-list .tabulator-edit-select-list-item {
padding: 4px;
}
.tabulator-edit-select-list .tabulator-edit-select-list-item.active {
color: #fff;
background: #1D68CD;
}
.tabulator-edit-select-list .tabulator-edit-select-list-item:hover {
cursor: pointer;
color: #fff;
background: #1D68CD;
}
.tabulator-edit-select-list .tabulator-edit-select-list-group {
border-bottom: 1px solid #ddd;
padding: 4px;
padding-top: 6px;
font-weight: bold;
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,769 @@
/* Tabulator v4.1.2 (c) Oliver Folkerd */
.tabulator {
position: relative;
border: 1px solid #999;
background-color: #888;
font-size: 14px;
text-align: left;
overflow: hidden;
-ms-transform: translatez(0);
transform: translatez(0);
}
.tabulator[tabulator-layout="fitDataFill"] .tabulator-tableHolder .tabulator-table {
min-width: 100%;
}
.tabulator.tabulator-block-select {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.tabulator .tabulator-header {
position: relative;
box-sizing: border-box;
width: 100%;
border-bottom: 1px solid #999;
background-color: #e6e6e6;
color: #555;
font-weight: bold;
white-space: nowrap;
overflow: hidden;
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
-o-user-select: none;
}
.tabulator .tabulator-header .tabulator-col {
display: inline-block;
position: relative;
box-sizing: border-box;
border-right: 1px solid #aaa;
background: #e6e6e6;
text-align: left;
vertical-align: bottom;
overflow: hidden;
}
.tabulator .tabulator-header .tabulator-col.tabulator-moving {
position: absolute;
border: 1px solid #999;
background: #cdcdcd;
pointer-events: none;
}
.tabulator .tabulator-header .tabulator-col .tabulator-col-content {
box-sizing: border-box;
position: relative;
padding: 4px;
}
.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title {
box-sizing: border-box;
width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
vertical-align: bottom;
}
.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title .tabulator-title-editor {
box-sizing: border-box;
width: 100%;
border: 1px solid #999;
padding: 1px;
background: #fff;
}
.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-arrow {
display: inline-block;
position: absolute;
top: 9px;
right: 8px;
width: 0;
height: 0;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid #bbb;
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-group .tabulator-col-group-cols {
position: relative;
display: -ms-flexbox;
display: flex;
border-top: 1px solid #aaa;
overflow: hidden;
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-group .tabulator-col-group-cols .tabulator-col:last-child {
margin-right: -1px;
}
.tabulator .tabulator-header .tabulator-col:first-child .tabulator-col-resize-handle.prev {
display: none;
}
.tabulator .tabulator-header .tabulator-col.ui-sortable-helper {
position: absolute;
background-color: #e6e6e6 !important;
border: 1px solid #aaa;
}
.tabulator .tabulator-header .tabulator-col .tabulator-header-filter {
position: relative;
box-sizing: border-box;
margin-top: 2px;
width: 100%;
text-align: center;
}
.tabulator .tabulator-header .tabulator-col .tabulator-header-filter textarea {
height: auto !important;
}
.tabulator .tabulator-header .tabulator-col .tabulator-header-filter svg {
margin-top: 3px;
}
.tabulator .tabulator-header .tabulator-col .tabulator-header-filter input::-ms-clear {
width: 0;
height: 0;
}
.tabulator .tabulator-header .tabulator-col.tabulator-sortable .tabulator-col-title {
padding-right: 25px;
}
.tabulator .tabulator-header .tabulator-col.tabulator-sortable:hover {
cursor: pointer;
background-color: #cdcdcd;
}
.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="none"] .tabulator-col-content .tabulator-arrow {
border-top: none;
border-bottom: 6px solid #bbb;
}
.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="asc"] .tabulator-col-content .tabulator-arrow {
border-top: none;
border-bottom: 6px solid #666;
}
.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="desc"] .tabulator-col-content .tabulator-arrow {
border-top: 6px solid #666;
border-bottom: none;
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical .tabulator-col-content .tabulator-col-title {
-webkit-writing-mode: vertical-rl;
-ms-writing-mode: tb-rl;
writing-mode: vertical-rl;
text-orientation: mixed;
display: -ms-flexbox;
display: flex;
-ms-flex-align: center;
align-items: center;
-ms-flex-pack: center;
justify-content: center;
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-col-vertical-flip .tabulator-col-title {
-ms-transform: rotate(180deg);
transform: rotate(180deg);
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable .tabulator-col-title {
padding-right: 0;
padding-top: 20px;
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable.tabulator-col-vertical-flip .tabulator-col-title {
padding-right: 0;
padding-bottom: 20px;
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable .tabulator-arrow {
right: calc(50% - 6px);
}
.tabulator .tabulator-header .tabulator-frozen {
display: inline-block;
position: absolute;
z-index: 10;
}
.tabulator .tabulator-header .tabulator-frozen.tabulator-frozen-left {
border-right: 2px solid #aaa;
}
.tabulator .tabulator-header .tabulator-frozen.tabulator-frozen-right {
border-left: 2px solid #aaa;
}
.tabulator .tabulator-header .tabulator-calcs-holder {
box-sizing: border-box;
min-width: 400%;
background: #f3f3f3 !important;
border-top: 1px solid #aaa;
border-bottom: 1px solid #aaa;
overflow: hidden;
}
.tabulator .tabulator-header .tabulator-calcs-holder .tabulator-row {
background: #f3f3f3 !important;
}
.tabulator .tabulator-header .tabulator-calcs-holder .tabulator-row .tabulator-col-resize-handle {
display: none;
}
.tabulator .tabulator-header .tabulator-frozen-rows-holder {
min-width: 400%;
}
.tabulator .tabulator-header .tabulator-frozen-rows-holder:empty {
display: none;
}
.tabulator .tabulator-tableHolder {
position: relative;
width: 100%;
white-space: nowrap;
overflow: auto;
-webkit-overflow-scrolling: touch;
}
.tabulator .tabulator-tableHolder:focus {
outline: none;
}
.tabulator .tabulator-tableHolder .tabulator-placeholder {
box-sizing: border-box;
display: -ms-flexbox;
display: flex;
-ms-flex-align: center;
align-items: center;
width: 100%;
}
.tabulator .tabulator-tableHolder .tabulator-placeholder[tabulator-render-mode="virtual"] {
position: absolute;
top: 0;
left: 0;
height: 100%;
}
.tabulator .tabulator-tableHolder .tabulator-placeholder span {
display: inline-block;
margin: 0 auto;
padding: 10px;
color: #ccc;
font-weight: bold;
font-size: 20px;
}
.tabulator .tabulator-tableHolder .tabulator-table {
position: relative;
display: inline-block;
background-color: #fff;
white-space: nowrap;
overflow: visible;
color: #333;
}
.tabulator .tabulator-tableHolder .tabulator-table .tabulator-row.tabulator-calcs {
font-weight: bold;
background: #e2e2e2 !important;
}
.tabulator .tabulator-tableHolder .tabulator-table .tabulator-row.tabulator-calcs.tabulator-calcs-top {
border-bottom: 2px solid #aaa;
}
.tabulator .tabulator-tableHolder .tabulator-table .tabulator-row.tabulator-calcs.tabulator-calcs-bottom {
border-top: 2px solid #aaa;
}
.tabulator .tabulator-footer {
padding: 5px 10px;
border-top: 1px solid #999;
background-color: #e6e6e6;
text-align: right;
color: #555;
font-weight: bold;
white-space: nowrap;
-ms-user-select: none;
user-select: none;
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
-o-user-select: none;
}
.tabulator .tabulator-footer .tabulator-calcs-holder {
box-sizing: border-box;
width: calc(100% + 20px);
margin: -5px -10px 5px -10px;
text-align: left;
background: #f3f3f3 !important;
border-bottom: 1px solid #aaa;
border-top: 1px solid #aaa;
overflow: hidden;
}
.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row {
background: #f3f3f3 !important;
}
.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row .tabulator-col-resize-handle {
display: none;
}
.tabulator .tabulator-footer .tabulator-calcs-holder:only-child {
margin-bottom: -5px;
border-bottom: none;
}
.tabulator .tabulator-footer .tabulator-pages {
margin: 0 7px;
}
.tabulator .tabulator-footer .tabulator-page {
display: inline-block;
margin: 0 2px;
padding: 2px 5px;
border: 1px solid #aaa;
border-radius: 3px;
background: rgba(255, 255, 255, 0.2);
color: #555;
font-family: inherit;
font-weight: inherit;
font-size: inherit;
}
.tabulator .tabulator-footer .tabulator-page.active {
color: #d00;
}
.tabulator .tabulator-footer .tabulator-page:disabled {
opacity: .5;
}
.tabulator .tabulator-footer .tabulator-page:not(.disabled):hover {
cursor: pointer;
background: rgba(0, 0, 0, 0.2);
color: #fff;
}
.tabulator .tabulator-col-resize-handle {
position: absolute;
right: 0;
top: 0;
bottom: 0;
width: 5px;
}
.tabulator .tabulator-col-resize-handle.prev {
left: 0;
right: auto;
}
.tabulator .tabulator-col-resize-handle:hover {
cursor: ew-resize;
}
.tabulator .tabulator-loader {
position: absolute;
display: -ms-flexbox;
display: flex;
-ms-flex-align: center;
align-items: center;
top: 0;
left: 0;
z-index: 100;
height: 100%;
width: 100%;
background: rgba(0, 0, 0, 0.4);
text-align: center;
}
.tabulator .tabulator-loader .tabulator-loader-msg {
display: inline-block;
margin: 0 auto;
padding: 10px 20px;
border-radius: 10px;
background: #fff;
font-weight: bold;
font-size: 16px;
}
.tabulator .tabulator-loader .tabulator-loader-msg.tabulator-loading {
border: 4px solid #333;
color: #000;
}
.tabulator .tabulator-loader .tabulator-loader-msg.tabulator-error {
border: 4px solid #D00;
color: #590000;
}
.tabulator-row {
position: relative;
box-sizing: border-box;
min-height: 22px;
background-color: #fff;
}
.tabulator-row.tabulator-row-even {
background-color: #EFEFEF;
}
.tabulator-row.tabulator-selectable:hover {
background-color: #bbb;
cursor: pointer;
}
.tabulator-row.tabulator-selected {
background-color: #9ABCEA;
}
.tabulator-row.tabulator-selected:hover {
background-color: #769BCC;
cursor: pointer;
}
.tabulator-row.tabulator-row-moving {
border: 1px solid #000;
background: #fff;
}
.tabulator-row.tabulator-moving {
position: absolute;
border-top: 1px solid #aaa;
border-bottom: 1px solid #aaa;
pointer-events: none;
z-index: 15;
}
.tabulator-row .tabulator-row-resize-handle {
position: absolute;
right: 0;
bottom: 0;
left: 0;
height: 5px;
}
.tabulator-row .tabulator-row-resize-handle.prev {
top: 0;
bottom: auto;
}
.tabulator-row .tabulator-row-resize-handle:hover {
cursor: ns-resize;
}
.tabulator-row .tabulator-frozen {
display: inline-block;
position: absolute;
background-color: inherit;
z-index: 10;
}
.tabulator-row .tabulator-frozen.tabulator-frozen-left {
border-right: 2px solid #aaa;
}
.tabulator-row .tabulator-frozen.tabulator-frozen-right {
border-left: 2px solid #aaa;
}
.tabulator-row .tabulator-responsive-collapse {
box-sizing: border-box;
padding: 5px;
border-top: 1px solid #aaa;
border-bottom: 1px solid #aaa;
}
.tabulator-row .tabulator-responsive-collapse:empty {
display: none;
}
.tabulator-row .tabulator-responsive-collapse table {
font-size: 14px;
}
.tabulator-row .tabulator-responsive-collapse table tr td {
position: relative;
}
.tabulator-row .tabulator-responsive-collapse table tr td:first-of-type {
padding-right: 10px;
}
.tabulator-row .tabulator-cell {
display: inline-block;
position: relative;
box-sizing: border-box;
padding: 4px;
border-right: 1px solid #aaa;
vertical-align: middle;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.tabulator-row .tabulator-cell.tabulator-editing {
border: 1px solid #1D68CD;
padding: 0;
}
.tabulator-row .tabulator-cell.tabulator-editing input, .tabulator-row .tabulator-cell.tabulator-editing select {
border: 1px;
background: transparent;
}
.tabulator-row .tabulator-cell.tabulator-validation-fail {
border: 1px solid #dd0000;
}
.tabulator-row .tabulator-cell.tabulator-validation-fail input, .tabulator-row .tabulator-cell.tabulator-validation-fail select {
border: 1px;
background: transparent;
color: #dd0000;
}
.tabulator-row .tabulator-cell:first-child .tabulator-col-resize-handle.prev {
display: none;
}
.tabulator-row .tabulator-cell.tabulator-row-handle {
display: -ms-inline-flexbox;
display: inline-flex;
-ms-flex-align: center;
align-items: center;
-ms-flex-pack: center;
justify-content: center;
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
-o-user-select: none;
}
.tabulator-row .tabulator-cell.tabulator-row-handle .tabulator-row-handle-box {
width: 80%;
}
.tabulator-row .tabulator-cell.tabulator-row-handle .tabulator-row-handle-box .tabulator-row-handle-bar {
width: 100%;
height: 3px;
margin-top: 2px;
background: #666;
}
.tabulator-row .tabulator-cell .tabulator-data-tree-branch {
display: inline-block;
vertical-align: middle;
height: 9px;
width: 7px;
margin-top: -9px;
margin-right: 5px;
border-bottom-left-radius: 1px;
border-left: 2px solid #aaa;
border-bottom: 2px solid #aaa;
}
.tabulator-row .tabulator-cell .tabulator-data-tree-control {
display: -ms-inline-flexbox;
display: inline-flex;
-ms-flex-pack: center;
justify-content: center;
-ms-flex-align: center;
align-items: center;
vertical-align: middle;
height: 11px;
width: 11px;
margin-right: 5px;
border: 1px solid #333;
border-radius: 2px;
background: rgba(0, 0, 0, 0.1);
overflow: hidden;
}
.tabulator-row .tabulator-cell .tabulator-data-tree-control:hover {
cursor: pointer;
background: rgba(0, 0, 0, 0.2);
}
.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-collapse {
display: inline-block;
position: relative;
height: 7px;
width: 1px;
background: transparent;
}
.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-collapse:after {
position: absolute;
content: "";
left: -3px;
top: 3px;
height: 1px;
width: 7px;
background: #333;
}
.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-expand {
display: inline-block;
position: relative;
height: 7px;
width: 1px;
background: #333;
}
.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-expand:after {
position: absolute;
content: "";
left: -3px;
top: 3px;
height: 1px;
width: 7px;
background: #333;
}
.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle {
display: -ms-inline-flexbox;
display: inline-flex;
-ms-flex-align: center;
align-items: center;
-ms-flex-pack: center;
justify-content: center;
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
-o-user-select: none;
height: 15px;
width: 15px;
border-radius: 20px;
background: #666;
color: #fff;
font-weight: bold;
font-size: 1.1em;
}
.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle:hover {
opacity: .7;
}
.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle.open .tabulator-responsive-collapse-toggle-close {
display: initial;
}
.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle.open .tabulator-responsive-collapse-toggle-open {
display: none;
}
.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle .tabulator-responsive-collapse-toggle-close {
display: none;
}
.tabulator-row.tabulator-group {
box-sizing: border-box;
border-bottom: 1px solid #999;
border-right: 1px solid #aaa;
border-top: 1px solid #999;
padding: 5px;
padding-left: 10px;
background: #ccc;
font-weight: bold;
min-width: 100%;
}
.tabulator-row.tabulator-group:hover {
cursor: pointer;
background-color: rgba(0, 0, 0, 0.1);
}
.tabulator-row.tabulator-group.tabulator-group-visible .tabulator-arrow {
margin-right: 10px;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-top: 6px solid #666;
border-bottom: 0;
}
.tabulator-row.tabulator-group.tabulator-group-level-1 .tabulator-arrow {
margin-left: 20px;
}
.tabulator-row.tabulator-group.tabulator-group-level-2 .tabulator-arrow {
margin-left: 40px;
}
.tabulator-row.tabulator-group.tabulator-group-level-3 .tabulator-arrow {
margin-left: 60px;
}
.tabulator-row.tabulator-group.tabulator-group-level-4 .tabulator-arrow {
margin-left: 80px;
}
.tabulator-row.tabulator-group.tabulator-group-level-5 .tabulator-arrow {
margin-left: 100px;
}
.tabulator-row.tabulator-group .tabulator-arrow {
display: inline-block;
width: 0;
height: 0;
margin-right: 16px;
border-top: 6px solid transparent;
border-bottom: 6px solid transparent;
border-right: 0;
border-left: 6px solid #666;
vertical-align: middle;
}
.tabulator-row.tabulator-group span {
margin-left: 10px;
color: #d00;
}
.tabulator-edit-select-list {
position: absolute;
display: inline-block;
box-sizing: border-box;
max-height: 200px;
background: #fff;
border: 1px solid #aaa;
font-size: 14px;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
z-index: 10000;
}
.tabulator-edit-select-list .tabulator-edit-select-list-item {
padding: 4px;
color: #333;
}
.tabulator-edit-select-list .tabulator-edit-select-list-item.active {
color: #fff;
background: #1D68CD;
}
.tabulator-edit-select-list .tabulator-edit-select-list-item:hover {
cursor: pointer;
color: #fff;
background: #1D68CD;
}
.tabulator-edit-select-list .tabulator-edit-select-list-group {
border-bottom: 1px solid #aaa;
padding: 4px;
padding-top: 6px;
color: #333;
font-weight: bold;
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,771 @@
/* Tabulator v4.1.2 (c) Oliver Folkerd */
.tabulator {
position: relative;
border: 1px solid #333;
background-color: #222;
overflow: hidden;
font-size: 14px;
text-align: left;
-ms-transform: translatez(0);
transform: translatez(0);
}
.tabulator[tabulator-layout="fitDataFill"] .tabulator-tableHolder .tabulator-table {
min-width: 100%;
}
.tabulator.tabulator-block-select {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.tabulator .tabulator-header {
position: relative;
box-sizing: border-box;
width: 100%;
border-bottom: 1px solid #999;
background-color: #333;
color: #fff;
font-weight: bold;
white-space: nowrap;
overflow: hidden;
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
-o-user-select: none;
}
.tabulator .tabulator-header .tabulator-col {
display: inline-block;
position: relative;
box-sizing: border-box;
border-right: 1px solid #aaa;
background-color: #333;
text-align: left;
vertical-align: bottom;
overflow: hidden;
}
.tabulator .tabulator-header .tabulator-col.tabulator-moving {
position: absolute;
border: 1px solid #999;
background: #1a1a1a;
pointer-events: none;
}
.tabulator .tabulator-header .tabulator-col .tabulator-col-content {
box-sizing: border-box;
position: relative;
padding: 4px;
}
.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title {
box-sizing: border-box;
width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
vertical-align: bottom;
}
.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title .tabulator-title-editor {
box-sizing: border-box;
width: 100%;
border: 1px solid #999;
padding: 1px;
background: #444;
color: #fff;
}
.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-arrow {
display: inline-block;
position: absolute;
top: 9px;
right: 8px;
width: 0;
height: 0;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid #bbb;
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-group .tabulator-col-group-cols {
position: relative;
display: -ms-flexbox;
display: flex;
border-top: 1px solid #aaa;
overflow: hidden;
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-group .tabulator-col-group-cols .tabulator-col:last-child {
margin-right: -1px;
}
.tabulator .tabulator-header .tabulator-col:first-child .tabulator-col-resize-handle.prev {
display: none;
}
.tabulator .tabulator-header .tabulator-col.ui-sortable-helper {
position: absolute;
background-color: #1a1a1a !important;
border: 1px solid #aaa;
}
.tabulator .tabulator-header .tabulator-col .tabulator-header-filter {
position: relative;
box-sizing: border-box;
margin-top: 2px;
width: 100%;
text-align: center;
}
.tabulator .tabulator-header .tabulator-col .tabulator-header-filter textarea {
height: auto !important;
}
.tabulator .tabulator-header .tabulator-col .tabulator-header-filter svg {
margin-top: 3px;
}
.tabulator .tabulator-header .tabulator-col .tabulator-header-filter input, .tabulator .tabulator-header .tabulator-col .tabulator-header-filter select {
border: 1px solid #999;
background: #444;
color: #fff;
}
.tabulator .tabulator-header .tabulator-col .tabulator-header-filter input::-ms-clear {
width: 0;
height: 0;
}
.tabulator .tabulator-header .tabulator-col.tabulator-sortable .tabulator-col-title {
padding-right: 25px;
}
.tabulator .tabulator-header .tabulator-col.tabulator-sortable:hover {
cursor: pointer;
background-color: #1a1a1a;
}
.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="none"] .tabulator-col-content .tabulator-arrow {
border-top: none;
border-bottom: 6px solid #bbb;
}
.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="asc"] .tabulator-col-content .tabulator-arrow {
border-top: none;
border-bottom: 6px solid #666;
}
.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="desc"] .tabulator-col-content .tabulator-arrow {
border-top: 6px solid #666;
border-bottom: none;
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical .tabulator-col-content .tabulator-col-title {
-webkit-writing-mode: vertical-rl;
-ms-writing-mode: tb-rl;
writing-mode: vertical-rl;
text-orientation: mixed;
display: -ms-flexbox;
display: flex;
-ms-flex-align: center;
align-items: center;
-ms-flex-pack: center;
justify-content: center;
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-col-vertical-flip .tabulator-col-title {
-ms-transform: rotate(180deg);
transform: rotate(180deg);
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable .tabulator-col-title {
padding-right: 0;
padding-top: 20px;
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable.tabulator-col-vertical-flip .tabulator-col-title {
padding-right: 0;
padding-bottom: 20px;
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable .tabulator-arrow {
right: calc(50% - 6px);
}
.tabulator .tabulator-header .tabulator-frozen {
display: inline-block;
position: absolute;
z-index: 10;
}
.tabulator .tabulator-header .tabulator-frozen.tabulator-frozen-left {
border-right: 2px solid #888;
}
.tabulator .tabulator-header .tabulator-frozen.tabulator-frozen-right {
border-left: 2px solid #888;
}
.tabulator .tabulator-header .tabulator-calcs-holder {
box-sizing: border-box;
min-width: 400%;
background: #1a1a1a !important;
border-top: 1px solid #888;
border-bottom: 1px solid #aaa;
overflow: hidden;
}
.tabulator .tabulator-header .tabulator-calcs-holder .tabulator-row {
background: #1a1a1a !important;
}
.tabulator .tabulator-header .tabulator-calcs-holder .tabulator-row .tabulator-col-resize-handle {
display: none;
}
.tabulator .tabulator-header .tabulator-frozen-rows-holder {
min-width: 400%;
}
.tabulator .tabulator-header .tabulator-frozen-rows-holder:empty {
display: none;
}
.tabulator .tabulator-tableHolder {
position: relative;
width: 100%;
white-space: nowrap;
overflow: auto;
-webkit-overflow-scrolling: touch;
}
.tabulator .tabulator-tableHolder:focus {
outline: none;
}
.tabulator .tabulator-tableHolder .tabulator-placeholder {
box-sizing: border-box;
display: -ms-flexbox;
display: flex;
-ms-flex-align: center;
align-items: center;
width: 100%;
}
.tabulator .tabulator-tableHolder .tabulator-placeholder[tabulator-render-mode="virtual"] {
position: absolute;
top: 0;
left: 0;
height: 100%;
}
.tabulator .tabulator-tableHolder .tabulator-placeholder span {
display: inline-block;
margin: 0 auto;
padding: 10px;
color: #eee;
font-weight: bold;
font-size: 20px;
}
.tabulator .tabulator-tableHolder .tabulator-table {
position: relative;
display: inline-block;
background-color: #666;
white-space: nowrap;
overflow: visible;
color: #fff;
}
.tabulator .tabulator-tableHolder .tabulator-table .tabulator-row.tabulator-calcs {
font-weight: bold;
background: #373737 !important;
}
.tabulator .tabulator-tableHolder .tabulator-table .tabulator-row.tabulator-calcs.tabulator-calcs-top {
border-bottom: 2px solid #888;
}
.tabulator .tabulator-tableHolder .tabulator-table .tabulator-row.tabulator-calcs.tabulator-calcs-bottom {
border-top: 2px solid #888;
}
.tabulator .tabulator-col-resize-handle {
position: absolute;
right: 0;
top: 0;
bottom: 0;
width: 5px;
}
.tabulator .tabulator-col-resize-handle.prev {
left: 0;
right: auto;
}
.tabulator .tabulator-col-resize-handle:hover {
cursor: ew-resize;
}
.tabulator .tabulator-footer {
padding: 5px 10px;
border-top: 1px solid #999;
background-color: #333;
text-align: right;
color: #333;
font-weight: bold;
white-space: nowrap;
-ms-user-select: none;
user-select: none;
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
-o-user-select: none;
}
.tabulator .tabulator-footer .tabulator-calcs-holder {
box-sizing: border-box;
width: calc(100% + 20px);
margin: -5px -10px 5px -10px;
text-align: left;
background: #262626 !important;
border-bottom: 1px solid #888;
border-top: 1px solid #888;
overflow: hidden;
}
.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row {
background: #262626 !important;
color: #fff;
}
.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row .tabulator-col-resize-handle {
display: none;
}
.tabulator .tabulator-footer .tabulator-calcs-holder:only-child {
margin-bottom: -5px;
border-bottom: none;
}
.tabulator .tabulator-footer .tabulator-pages {
margin: 0 7px;
}
.tabulator .tabulator-footer .tabulator-page {
display: inline-block;
margin: 0 2px;
border: 1px solid #aaa;
border-radius: 3px;
padding: 2px 5px;
background: rgba(255, 255, 255, 0.2);
color: #333;
font-family: inherit;
font-weight: inherit;
font-size: inherit;
}
.tabulator .tabulator-footer .tabulator-page.active {
color: #fff;
}
.tabulator .tabulator-footer .tabulator-page:disabled {
opacity: .5;
}
.tabulator .tabulator-footer .tabulator-page:not(.disabled):hover {
cursor: pointer;
background: rgba(0, 0, 0, 0.2);
color: #fff;
}
.tabulator .tabulator-loader {
position: absolute;
display: -ms-flexbox;
display: flex;
-ms-flex-align: center;
align-items: center;
top: 0;
left: 0;
z-index: 100;
height: 100%;
width: 100%;
background: rgba(0, 0, 0, 0.4);
text-align: center;
}
.tabulator .tabulator-loader .tabulator-loader-msg {
display: inline-block;
margin: 0 auto;
padding: 10px 20px;
border-radius: 10px;
background: #fff;
font-weight: bold;
font-size: 16px;
}
.tabulator .tabulator-loader .tabulator-loader-msg.tabulator-loading {
border: 4px solid #333;
color: #000;
}
.tabulator .tabulator-loader .tabulator-loader-msg.tabulator-error {
border: 4px solid #D00;
color: #590000;
}
.tabulator-row {
position: relative;
box-sizing: border-box;
min-height: 22px;
background-color: #666;
}
.tabulator-row:nth-child(even) {
background-color: #444;
}
.tabulator-row.tabulator-selectable:hover {
background-color: #999;
cursor: pointer;
}
.tabulator-row.tabulator-selected {
background-color: #000;
}
.tabulator-row.tabulator-selected:hover {
background-color: #888;
cursor: pointer;
}
.tabulator-row.tabulator-moving {
position: absolute;
border-top: 1px solid #888;
border-bottom: 1px solid #888;
pointer-events: none !important;
z-index: 15;
}
.tabulator-row .tabulator-row-resize-handle {
position: absolute;
right: 0;
bottom: 0;
left: 0;
height: 5px;
}
.tabulator-row .tabulator-row-resize-handle.prev {
top: 0;
bottom: auto;
}
.tabulator-row .tabulator-row-resize-handle:hover {
cursor: ns-resize;
}
.tabulator-row .tabulator-frozen {
display: inline-block;
position: absolute;
background-color: inherit;
z-index: 10;
}
.tabulator-row .tabulator-frozen.tabulator-frozen-left {
border-right: 2px solid #888;
}
.tabulator-row .tabulator-frozen.tabulator-frozen-right {
border-left: 2px solid #888;
}
.tabulator-row .tabulator-responsive-collapse {
box-sizing: border-box;
padding: 5px;
border-top: 1px solid #888;
border-bottom: 1px solid #888;
}
.tabulator-row .tabulator-responsive-collapse:empty {
display: none;
}
.tabulator-row .tabulator-responsive-collapse table {
font-size: 14px;
}
.tabulator-row .tabulator-responsive-collapse table tr td {
position: relative;
}
.tabulator-row .tabulator-responsive-collapse table tr td:first-of-type {
padding-right: 10px;
}
.tabulator-row .tabulator-cell {
display: inline-block;
position: relative;
box-sizing: border-box;
padding: 4px;
border-right: 1px solid #888;
vertical-align: middle;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.tabulator-row .tabulator-cell.tabulator-editing {
border: 1px solid #999;
padding: 0;
}
.tabulator-row .tabulator-cell.tabulator-editing input, .tabulator-row .tabulator-cell.tabulator-editing select {
border: 1px;
background: transparent;
}
.tabulator-row .tabulator-cell.tabulator-validation-fail {
border: 1px solid #dd0000;
}
.tabulator-row .tabulator-cell.tabulator-validation-fail input, .tabulator-row .tabulator-cell.tabulator-validation-fail select {
border: 1px;
background: transparent;
color: #dd0000;
}
.tabulator-row .tabulator-cell:first-child .tabulator-col-resize-handle.prev {
display: none;
}
.tabulator-row .tabulator-cell.tabulator-row-handle {
display: -ms-inline-flexbox;
display: inline-flex;
-ms-flex-align: center;
align-items: center;
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
-o-user-select: none;
}
.tabulator-row .tabulator-cell.tabulator-row-handle .tabulator-row-handle-box {
width: 80%;
}
.tabulator-row .tabulator-cell.tabulator-row-handle .tabulator-row-handle-box .tabulator-row-handle-bar {
width: 100%;
height: 3px;
margin-top: 2px;
background: #666;
}
.tabulator-row .tabulator-cell .tabulator-data-tree-branch {
display: inline-block;
vertical-align: middle;
height: 9px;
width: 7px;
margin-top: -9px;
margin-right: 5px;
border-bottom-left-radius: 1px;
border-left: 2px solid #888;
border-bottom: 2px solid #888;
}
.tabulator-row .tabulator-cell .tabulator-data-tree-control {
display: -ms-inline-flexbox;
display: inline-flex;
-ms-flex-pack: center;
justify-content: center;
-ms-flex-align: center;
align-items: center;
vertical-align: middle;
height: 11px;
width: 11px;
margin-right: 5px;
border: 1px solid #fff;
border-radius: 2px;
background: rgba(0, 0, 0, 0.1);
overflow: hidden;
}
.tabulator-row .tabulator-cell .tabulator-data-tree-control:hover {
cursor: pointer;
background: rgba(0, 0, 0, 0.2);
}
.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-collapse {
display: inline-block;
position: relative;
height: 7px;
width: 1px;
background: transparent;
}
.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-collapse:after {
position: absolute;
content: "";
left: -3px;
top: 3px;
height: 1px;
width: 7px;
background: #fff;
}
.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-expand {
display: inline-block;
position: relative;
height: 7px;
width: 1px;
background: #fff;
}
.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-expand:after {
position: absolute;
content: "";
left: -3px;
top: 3px;
height: 1px;
width: 7px;
background: #fff;
}
.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle {
display: -ms-inline-flexbox;
display: inline-flex;
-ms-flex-align: center;
align-items: center;
-ms-flex-pack: center;
justify-content: center;
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
-o-user-select: none;
height: 15px;
width: 15px;
border-radius: 20px;
background: #fff;
color: #666;
font-weight: bold;
font-size: 1.1em;
}
.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle:hover {
opacity: .7;
}
.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle.open .tabulator-responsive-collapse-toggle-close {
display: initial;
}
.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle.open .tabulator-responsive-collapse-toggle-open {
display: none;
}
.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle .tabulator-responsive-collapse-toggle-close {
display: none;
}
.tabulator-row.tabulator-group {
box-sizing: border-box;
border-bottom: 1px solid #999;
border-right: 1px solid #888;
border-top: 1px solid #999;
padding: 5px;
padding-left: 10px;
background: #ccc;
font-weight: bold;
color: #333;
min-width: 100%;
}
.tabulator-row.tabulator-group:hover {
cursor: pointer;
background-color: rgba(0, 0, 0, 0.1);
}
.tabulator-row.tabulator-group.tabulator-group-visible .tabulator-arrow {
margin-right: 10px;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-top: 6px solid #666;
border-bottom: 0;
}
.tabulator-row.tabulator-group.tabulator-group-level-1 .tabulator-arrow {
margin-left: 20px;
}
.tabulator-row.tabulator-group.tabulator-group-level-2 .tabulator-arrow {
margin-left: 40px;
}
.tabulator-row.tabulator-group.tabulator-group-level-3 .tabulator-arrow {
margin-left: 60px;
}
.tabulator-row.tabulator-group.tabulator-group-level-4 .tabulator-arrow {
margin-left: 80px;
}
.tabulator-row.tabulator-group.tabulator-group-level-5 .tabulator-arrow {
margin-left: 100px;
}
.tabulator-row.tabulator-group .tabulator-arrow {
display: inline-block;
width: 0;
height: 0;
margin-right: 16px;
border-top: 6px solid transparent;
border-bottom: 6px solid transparent;
border-right: 0;
border-left: 6px solid #666;
vertical-align: middle;
}
.tabulator-row.tabulator-group span {
margin-left: 10px;
color: #666;
}
.tabulator-edit-select-list {
position: absolute;
display: inline-block;
box-sizing: border-box;
max-height: 200px;
background: #666;
border: 1px solid #888;
font-size: 14px;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
z-index: 10000;
}
.tabulator-edit-select-list .tabulator-edit-select-list-item {
padding: 4px;
color: #fff;
}
.tabulator-edit-select-list .tabulator-edit-select-list-item.active {
color: #666;
background: #999;
}
.tabulator-edit-select-list .tabulator-edit-select-list-item:hover {
cursor: pointer;
color: #666;
background: #999;
}
.tabulator-edit-select-list .tabulator-edit-select-list-group {
border-bottom: 1px solid #888;
padding: 4px;
padding-top: 6px;
color: #fff;
font-weight: bold;
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,794 @@
/* Tabulator v4.1.2 (c) Oliver Folkerd */
.tabulator {
position: relative;
border: 1px solid #fff;
background-color: #fff;
overflow: hidden;
font-size: 16px;
text-align: left;
-ms-transform: translatez(0);
transform: translatez(0);
}
.tabulator[tabulator-layout="fitDataFill"] .tabulator-tableHolder .tabulator-table {
min-width: 100%;
}
.tabulator.tabulator-block-select {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.tabulator .tabulator-header {
position: relative;
box-sizing: border-box;
width: 100%;
border-bottom: 3px solid #3759D7;
margin-bottom: 4px;
background-color: #fff;
color: #3759D7;
font-weight: bold;
white-space: nowrap;
overflow: hidden;
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
-o-user-select: none;
padding-left: 10px;
font-size: 1.1em;
}
.tabulator .tabulator-header .tabulator-col {
display: inline-block;
position: relative;
box-sizing: border-box;
border-right: 2px solid #fff;
background-color: #fff;
text-align: left;
vertical-align: bottom;
overflow: hidden;
}
.tabulator .tabulator-header .tabulator-col.tabulator-moving {
position: absolute;
border: 1px solid #3759D7;
background: #e6e6e6;
pointer-events: none;
}
.tabulator .tabulator-header .tabulator-col .tabulator-col-content {
box-sizing: border-box;
position: relative;
padding: 4px;
}
.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title {
box-sizing: border-box;
width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
vertical-align: bottom;
}
.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title .tabulator-title-editor {
box-sizing: border-box;
width: 100%;
border: 1px solid #3759D7;
padding: 1px;
background: #fff;
font-size: 1em;
color: #3759D7;
}
.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-arrow {
display: inline-block;
position: absolute;
top: 9px;
right: 8px;
width: 0;
height: 0;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid #b7c3f1;
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-group .tabulator-col-group-cols {
position: relative;
display: -ms-flexbox;
display: flex;
border-top: 2px solid #3759D7;
overflow: hidden;
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-group .tabulator-col-group-cols .tabulator-col:last-child {
margin-right: -1px;
}
.tabulator .tabulator-header .tabulator-col:first-child .tabulator-col-resize-handle.prev {
display: none;
}
.tabulator .tabulator-header .tabulator-col.ui-sortable-helper {
position: absolute;
background-color: #e6e6e6 !important;
border: 1px solid #fff;
}
.tabulator .tabulator-header .tabulator-col .tabulator-header-filter {
position: relative;
box-sizing: border-box;
margin-top: 2px;
width: 100%;
text-align: center;
}
.tabulator .tabulator-header .tabulator-col .tabulator-header-filter textarea {
height: auto !important;
}
.tabulator .tabulator-header .tabulator-col .tabulator-header-filter svg {
margin-top: 3px;
}
.tabulator .tabulator-header .tabulator-col .tabulator-header-filter input::-ms-clear {
width: 0;
height: 0;
}
.tabulator .tabulator-header .tabulator-col.tabulator-sortable .tabulator-col-title {
padding-right: 25px;
}
.tabulator .tabulator-header .tabulator-col.tabulator-sortable:hover {
cursor: pointer;
background-color: #e6e6e6;
}
.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="none"] .tabulator-col-content .tabulator-arrow {
border-top: none;
border-bottom: 6px solid #b7c3f1;
}
.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="asc"] .tabulator-col-content .tabulator-arrow {
border-top: none;
border-bottom: 6px solid #3759D7;
}
.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="desc"] .tabulator-col-content .tabulator-arrow {
border-top: 6px solid #3759D7;
border-bottom: none;
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical .tabulator-col-content .tabulator-col-title {
-webkit-writing-mode: vertical-rl;
-ms-writing-mode: tb-rl;
writing-mode: vertical-rl;
text-orientation: mixed;
display: -ms-flexbox;
display: flex;
-ms-flex-align: center;
align-items: center;
-ms-flex-pack: center;
justify-content: center;
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-col-vertical-flip .tabulator-col-title {
-ms-transform: rotate(180deg);
transform: rotate(180deg);
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable .tabulator-col-title {
padding-right: 0;
padding-top: 20px;
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable.tabulator-col-vertical-flip .tabulator-col-title {
padding-right: 0;
padding-bottom: 20px;
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable .tabulator-arrow {
right: calc(50% - 6px);
}
.tabulator .tabulator-header .tabulator-frozen {
display: inline-block;
position: absolute;
z-index: 10;
}
.tabulator .tabulator-header .tabulator-frozen.tabulator-frozen-left {
padding-left: 10px;
border-right: 2px solid #fff;
}
.tabulator .tabulator-header .tabulator-frozen.tabulator-frozen-right {
border-left: 2px solid #fff;
}
.tabulator .tabulator-header .tabulator-calcs-holder {
box-sizing: border-box;
min-width: 400%;
border-top: 2px solid #3759D7 !important;
background: white !important;
border-top: 1px solid #fff;
border-bottom: 1px solid #fff;
overflow: hidden;
}
.tabulator .tabulator-header .tabulator-calcs-holder .tabulator-row {
padding-left: 0 !important;
background: white !important;
}
.tabulator .tabulator-header .tabulator-calcs-holder .tabulator-row .tabulator-col-resize-handle {
display: none;
}
.tabulator .tabulator-header .tabulator-calcs-holder .tabulator-row .tabulator-cell {
background: none;
}
.tabulator .tabulator-header .tabulator-frozen-rows-holder {
min-width: 400%;
}
.tabulator .tabulator-header .tabulator-frozen-rows-holder:empty {
display: none;
}
.tabulator .tabulator-tableHolder {
position: relative;
width: 100%;
white-space: nowrap;
overflow: auto;
-webkit-overflow-scrolling: touch;
}
.tabulator .tabulator-tableHolder:focus {
outline: none;
}
.tabulator .tabulator-tableHolder .tabulator-placeholder {
box-sizing: border-box;
display: -ms-flexbox;
display: flex;
-ms-flex-align: center;
align-items: center;
width: 100%;
}
.tabulator .tabulator-tableHolder .tabulator-placeholder[tabulator-render-mode="virtual"] {
position: absolute;
top: 0;
left: 0;
height: 100%;
}
.tabulator .tabulator-tableHolder .tabulator-placeholder span {
display: inline-block;
margin: 0 auto;
padding: 10px;
color: #3759D7;
font-weight: bold;
font-size: 20px;
}
.tabulator .tabulator-tableHolder .tabulator-table {
position: relative;
display: inline-block;
background-color: #f3f3f3;
white-space: nowrap;
overflow: visible;
color: #333;
}
.tabulator .tabulator-tableHolder .tabulator-table .tabulator-row.tabulator-calcs {
font-weight: bold;
background: #f2f2f2 !important;
}
.tabulator .tabulator-tableHolder .tabulator-table .tabulator-row.tabulator-calcs.tabulator-calcs-top {
border-bottom: 2px solid #3759D7;
}
.tabulator .tabulator-tableHolder .tabulator-table .tabulator-row.tabulator-calcs.tabulator-calcs-bottom {
border-top: 2px solid #3759D7;
}
.tabulator .tabulator-col-resize-handle {
position: absolute;
right: 0;
top: 0;
bottom: 0;
width: 5px;
}
.tabulator .tabulator-col-resize-handle.prev {
left: 0;
right: auto;
}
.tabulator .tabulator-col-resize-handle:hover {
cursor: ew-resize;
}
.tabulator .tabulator-footer {
padding: 5px 10px;
border-top: 1px solid #999;
background-color: #fff;
text-align: right;
color: #3759D7;
font-weight: bold;
white-space: nowrap;
-ms-user-select: none;
user-select: none;
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
-o-user-select: none;
}
.tabulator .tabulator-footer .tabulator-calcs-holder {
box-sizing: border-box;
width: calc(100% + 20px);
margin: -5px -10px 5px -10px;
text-align: left;
background: white !important;
border-top: 3px solid #3759D7 !important;
border-bottom: 2px solid #3759D7 !important;
border-bottom: 1px solid #fff;
border-top: 1px solid #fff;
overflow: hidden;
}
.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row {
background: white !important;
}
.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row .tabulator-col-resize-handle {
display: none;
}
.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row .tabulator-cell {
background: none;
}
.tabulator .tabulator-footer .tabulator-calcs-holder:only-child {
margin-bottom: -5px;
border-bottom: none;
border-bottom: none !important;
}
.tabulator .tabulator-footer .tabulator-pages {
margin: 0 7px;
}
.tabulator .tabulator-footer .tabulator-page {
display: inline-block;
margin: 0 2px;
border: 1px solid #aaa;
border-radius: 3px;
padding: 2px 5px;
background: rgba(255, 255, 255, 0.2);
color: #3759D7;
font-family: inherit;
font-weight: inherit;
font-size: inherit;
}
.tabulator .tabulator-footer .tabulator-page.active {
color: #3759D7;
}
.tabulator .tabulator-footer .tabulator-page:disabled {
opacity: .5;
}
.tabulator .tabulator-footer .tabulator-page:not(.disabled):hover {
cursor: pointer;
background: rgba(0, 0, 0, 0.2);
color: #fff;
}
.tabulator .tabulator-loader {
position: absolute;
display: -ms-flexbox;
display: flex;
-ms-flex-align: center;
align-items: center;
top: 0;
left: 0;
z-index: 100;
height: 100%;
width: 100%;
background: rgba(0, 0, 0, 0.4);
text-align: center;
}
.tabulator .tabulator-loader .tabulator-loader-msg {
display: inline-block;
margin: 0 auto;
padding: 10px 20px;
border-radius: 10px;
background: #fff;
font-weight: bold;
font-size: 16px;
}
.tabulator .tabulator-loader .tabulator-loader-msg.tabulator-loading {
border: 4px solid #333;
color: #000;
}
.tabulator .tabulator-loader .tabulator-loader-msg.tabulator-error {
border: 4px solid #D00;
color: #590000;
}
.tabulator-row {
position: relative;
box-sizing: border-box;
box-sizing: border-box;
min-height: 24px;
background-color: #3759D7;
padding-left: 10px !important;
margin-bottom: 2px;
}
.tabulator-row:nth-child(even) {
background-color: #627ce0;
}
.tabulator-row:nth-child(even) .tabulator-cell {
background-color: #fff;
}
.tabulator-row.tabulator-selectable:hover {
cursor: pointer;
}
.tabulator-row.tabulator-selectable:hover .tabulator-cell {
background-color: #bbb;
}
.tabulator-row.tabulator-selected .tabulator-cell {
background-color: #9ABCEA;
}
.tabulator-row.tabulator-selected:hover .tabulator-cell {
background-color: #769BCC;
cursor: pointer;
}
.tabulator-row.tabulator-moving {
position: absolute;
border-top: 1px solid #fff;
border-bottom: 1px solid #fff;
pointer-events: none !important;
z-index: 15;
}
.tabulator-row .tabulator-row-resize-handle {
position: absolute;
right: 0;
bottom: 0;
left: 0;
height: 5px;
}
.tabulator-row .tabulator-row-resize-handle.prev {
top: 0;
bottom: auto;
}
.tabulator-row .tabulator-row-resize-handle:hover {
cursor: ns-resize;
}
.tabulator-row .tabulator-frozen {
display: inline-block;
position: absolute;
background-color: inherit;
z-index: 10;
}
.tabulator-row .tabulator-frozen.tabulator-frozen-left {
padding-left: 10px;
border-right: 2px solid #fff;
}
.tabulator-row .tabulator-frozen.tabulator-frozen-right {
border-left: 2px solid #fff;
}
.tabulator-row .tabulator-responsive-collapse {
box-sizing: border-box;
padding: 5px;
border-top: 1px solid #fff;
border-bottom: 1px solid #fff;
}
.tabulator-row .tabulator-responsive-collapse:empty {
display: none;
}
.tabulator-row .tabulator-responsive-collapse table {
font-size: 16px;
}
.tabulator-row .tabulator-responsive-collapse table tr td {
position: relative;
}
.tabulator-row .tabulator-responsive-collapse table tr td:first-of-type {
padding-right: 10px;
}
.tabulator-row .tabulator-cell {
display: inline-block;
position: relative;
box-sizing: border-box;
padding: 6px 4px;
border-right: 2px solid #fff;
vertical-align: middle;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
background-color: #f3f3f3;
}
.tabulator-row .tabulator-cell.tabulator-editing {
border: 1px solid #1D68CD;
padding: 0;
}
.tabulator-row .tabulator-cell.tabulator-editing input, .tabulator-row .tabulator-cell.tabulator-editing select {
border: 1px;
background: transparent;
}
.tabulator-row .tabulator-cell.tabulator-validation-fail {
border: 1px solid #dd0000;
}
.tabulator-row .tabulator-cell.tabulator-validation-fail input, .tabulator-row .tabulator-cell.tabulator-validation-fail select {
border: 1px;
background: transparent;
color: #dd0000;
}
.tabulator-row .tabulator-cell:first-child .tabulator-col-resize-handle.prev {
display: none;
}
.tabulator-row .tabulator-cell.tabulator-row-handle {
display: -ms-inline-flexbox;
display: inline-flex;
-ms-flex-align: center;
align-items: center;
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
-o-user-select: none;
}
.tabulator-row .tabulator-cell.tabulator-row-handle .tabulator-row-handle-box {
width: 80%;
}
.tabulator-row .tabulator-cell.tabulator-row-handle .tabulator-row-handle-box .tabulator-row-handle-bar {
width: 100%;
height: 3px;
margin-top: 2px;
background: #666;
}
.tabulator-row .tabulator-cell .tabulator-data-tree-branch {
display: inline-block;
vertical-align: middle;
height: 9px;
width: 7px;
margin-top: -9px;
margin-right: 5px;
border-bottom-left-radius: 1px;
border-left: 2px solid #fff;
border-bottom: 2px solid #fff;
}
.tabulator-row .tabulator-cell .tabulator-data-tree-control {
display: -ms-inline-flexbox;
display: inline-flex;
-ms-flex-pack: center;
justify-content: center;
-ms-flex-align: center;
align-items: center;
vertical-align: middle;
height: 11px;
width: 11px;
margin-right: 5px;
border: 1px solid #333;
border-radius: 2px;
background: rgba(0, 0, 0, 0.1);
overflow: hidden;
}
.tabulator-row .tabulator-cell .tabulator-data-tree-control:hover {
cursor: pointer;
background: rgba(0, 0, 0, 0.2);
}
.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-collapse {
display: inline-block;
position: relative;
height: 7px;
width: 1px;
background: transparent;
}
.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-collapse:after {
position: absolute;
content: "";
left: -3px;
top: 3px;
height: 1px;
width: 7px;
background: #333;
}
.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-expand {
display: inline-block;
position: relative;
height: 7px;
width: 1px;
background: #333;
}
.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-expand:after {
position: absolute;
content: "";
left: -3px;
top: 3px;
height: 1px;
width: 7px;
background: #333;
}
.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle {
display: -ms-inline-flexbox;
display: inline-flex;
-ms-flex-align: center;
align-items: center;
-ms-flex-pack: center;
justify-content: center;
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
-o-user-select: none;
height: 15px;
width: 15px;
border-radius: 20px;
background: #666;
color: #f3f3f3;
font-weight: bold;
font-size: 1.1em;
}
.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle:hover {
opacity: .7;
}
.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle.open .tabulator-responsive-collapse-toggle-close {
display: initial;
}
.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle.open .tabulator-responsive-collapse-toggle-open {
display: none;
}
.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle .tabulator-responsive-collapse-toggle-close {
display: none;
}
.tabulator-row.tabulator-group {
box-sizing: border-box;
border-bottom: 2px solid #3759D7;
border-top: 2px solid #3759D7;
padding: 5px;
padding-left: 10px;
background: #8ca0e8;
font-weight: bold;
color: fff;
margin-bottom: 2px;
min-width: 100%;
}
.tabulator-row.tabulator-group:hover {
cursor: pointer;
background-color: rgba(0, 0, 0, 0.1);
}
.tabulator-row.tabulator-group.tabulator-group-visible .tabulator-arrow {
margin-right: 10px;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-top: 6px solid #3759D7;
border-bottom: 0;
}
.tabulator-row.tabulator-group.tabulator-group-level-1 .tabulator-arrow {
margin-left: 20px;
}
.tabulator-row.tabulator-group.tabulator-group-level-2 .tabulator-arrow {
margin-left: 40px;
}
.tabulator-row.tabulator-group.tabulator-group-level-3 .tabulator-arrow {
margin-left: 60px;
}
.tabulator-row.tabulator-group.tabulator-group-level-4 .tabulator-arrow {
margin-left: 80px;
}
.tabulator-row.tabulator-group.tabulator-group-level-5 .tabulator-arrow {
margin-left: 100px;
}
.tabulator-row.tabulator-group .tabulator-arrow {
display: inline-block;
width: 0;
height: 0;
margin-right: 16px;
border-top: 6px solid transparent;
border-bottom: 6px solid transparent;
border-right: 0;
border-left: 6px solid #3759D7;
vertical-align: middle;
}
.tabulator-row.tabulator-group span {
margin-left: 10px;
color: #3759D7;
}
.tabulator-edit-select-list {
position: absolute;
display: inline-block;
box-sizing: border-box;
max-height: 200px;
background: #f3f3f3;
border: 1px solid #fff;
font-size: 16px;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
z-index: 10000;
}
.tabulator-edit-select-list .tabulator-edit-select-list-item {
padding: 4px;
color: #333;
}
.tabulator-edit-select-list .tabulator-edit-select-list-item.active {
color: #f3f3f3;
background: #1D68CD;
}
.tabulator-edit-select-list .tabulator-edit-select-list-item:hover {
cursor: pointer;
color: #f3f3f3;
background: #1D68CD;
}
.tabulator-edit-select-list .tabulator-edit-select-list-group {
border-bottom: 1px solid #fff;
padding: 4px;
padding-top: 6px;
color: #333;
font-weight: bold;
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,766 @@
/* Tabulator v4.1.2 (c) Oliver Folkerd */
.tabulator {
position: relative;
background-color: #fff;
overflow: hidden;
font-size: 14px;
text-align: left;
-ms-transform: translatez(0);
transform: translatez(0);
}
.tabulator[tabulator-layout="fitDataFill"] .tabulator-tableHolder .tabulator-table {
min-width: 100%;
}
.tabulator.tabulator-block-select {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.tabulator .tabulator-header {
position: relative;
box-sizing: border-box;
width: 100%;
border-bottom: 1px solid #999;
background-color: #fff;
color: #555;
font-weight: bold;
white-space: nowrap;
overflow: hidden;
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
-o-user-select: none;
}
.tabulator .tabulator-header .tabulator-col {
display: inline-block;
position: relative;
box-sizing: border-box;
border-right: 1px solid #ddd;
background-color: #fff;
text-align: left;
vertical-align: bottom;
overflow: hidden;
}
.tabulator .tabulator-header .tabulator-col.tabulator-moving {
position: absolute;
border: 1px solid #999;
background: #e6e6e6;
pointer-events: none;
}
.tabulator .tabulator-header .tabulator-col .tabulator-col-content {
box-sizing: border-box;
position: relative;
padding: 4px;
}
.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title {
box-sizing: border-box;
width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
vertical-align: bottom;
}
.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title .tabulator-title-editor {
box-sizing: border-box;
width: 100%;
border: 1px solid #999;
padding: 1px;
background: #fff;
}
.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-arrow {
display: inline-block;
position: absolute;
top: 9px;
right: 8px;
width: 0;
height: 0;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid #bbb;
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-group .tabulator-col-group-cols {
position: relative;
display: -ms-flexbox;
display: flex;
border-top: 1px solid #ddd;
overflow: hidden;
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-group .tabulator-col-group-cols .tabulator-col:last-child {
margin-right: -1px;
}
.tabulator .tabulator-header .tabulator-col:first-child .tabulator-col-resize-handle.prev {
display: none;
}
.tabulator .tabulator-header .tabulator-col.ui-sortable-helper {
position: absolute;
background-color: #e6e6e6 !important;
border: 1px solid #ddd;
}
.tabulator .tabulator-header .tabulator-col .tabulator-header-filter {
position: relative;
box-sizing: border-box;
margin-top: 2px;
width: 100%;
text-align: center;
}
.tabulator .tabulator-header .tabulator-col .tabulator-header-filter textarea {
height: auto !important;
}
.tabulator .tabulator-header .tabulator-col .tabulator-header-filter svg {
margin-top: 3px;
}
.tabulator .tabulator-header .tabulator-col .tabulator-header-filter input::-ms-clear {
width: 0;
height: 0;
}
.tabulator .tabulator-header .tabulator-col.tabulator-sortable .tabulator-col-title {
padding-right: 25px;
}
.tabulator .tabulator-header .tabulator-col.tabulator-sortable:hover {
cursor: pointer;
background-color: #e6e6e6;
}
.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="none"] .tabulator-col-content .tabulator-arrow {
border-top: none;
border-bottom: 6px solid #bbb;
}
.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="asc"] .tabulator-col-content .tabulator-arrow {
border-top: none;
border-bottom: 6px solid #666;
}
.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="desc"] .tabulator-col-content .tabulator-arrow {
border-top: 6px solid #666;
border-bottom: none;
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical .tabulator-col-content .tabulator-col-title {
-webkit-writing-mode: vertical-rl;
-ms-writing-mode: tb-rl;
writing-mode: vertical-rl;
text-orientation: mixed;
display: -ms-flexbox;
display: flex;
-ms-flex-align: center;
align-items: center;
-ms-flex-pack: center;
justify-content: center;
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-col-vertical-flip .tabulator-col-title {
-ms-transform: rotate(180deg);
transform: rotate(180deg);
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable .tabulator-col-title {
padding-right: 0;
padding-top: 20px;
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable.tabulator-col-vertical-flip .tabulator-col-title {
padding-right: 0;
padding-bottom: 20px;
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable .tabulator-arrow {
right: calc(50% - 6px);
}
.tabulator .tabulator-header .tabulator-frozen {
display: inline-block;
position: absolute;
z-index: 10;
}
.tabulator .tabulator-header .tabulator-frozen.tabulator-frozen-left {
border-right: 2px solid #ddd;
}
.tabulator .tabulator-header .tabulator-frozen.tabulator-frozen-right {
border-left: 2px solid #ddd;
}
.tabulator .tabulator-header .tabulator-calcs-holder {
box-sizing: border-box;
min-width: 400%;
background: #f2f2f2 !important;
border-top: 1px solid #ddd;
border-bottom: 1px solid #999;
overflow: hidden;
}
.tabulator .tabulator-header .tabulator-calcs-holder .tabulator-row {
background: #f2f2f2 !important;
}
.tabulator .tabulator-header .tabulator-calcs-holder .tabulator-row .tabulator-col-resize-handle {
display: none;
}
.tabulator .tabulator-header .tabulator-frozen-rows-holder {
min-width: 400%;
}
.tabulator .tabulator-header .tabulator-frozen-rows-holder:empty {
display: none;
}
.tabulator .tabulator-tableHolder {
position: relative;
width: 100%;
white-space: nowrap;
overflow: auto;
-webkit-overflow-scrolling: touch;
}
.tabulator .tabulator-tableHolder:focus {
outline: none;
}
.tabulator .tabulator-tableHolder .tabulator-placeholder {
box-sizing: border-box;
display: -ms-flexbox;
display: flex;
-ms-flex-align: center;
align-items: center;
width: 100%;
}
.tabulator .tabulator-tableHolder .tabulator-placeholder[tabulator-render-mode="virtual"] {
position: absolute;
top: 0;
left: 0;
height: 100%;
}
.tabulator .tabulator-tableHolder .tabulator-placeholder span {
display: inline-block;
margin: 0 auto;
padding: 10px;
color: #000;
font-weight: bold;
font-size: 20px;
}
.tabulator .tabulator-tableHolder .tabulator-table {
position: relative;
display: inline-block;
background-color: #fff;
white-space: nowrap;
overflow: visible;
color: #333;
}
.tabulator .tabulator-tableHolder .tabulator-table .tabulator-row.tabulator-calcs {
font-weight: bold;
background: #f2f2f2 !important;
}
.tabulator .tabulator-tableHolder .tabulator-table .tabulator-row.tabulator-calcs.tabulator-calcs-top {
border-bottom: 2px solid #ddd;
}
.tabulator .tabulator-tableHolder .tabulator-table .tabulator-row.tabulator-calcs.tabulator-calcs-bottom {
border-top: 2px solid #ddd;
}
.tabulator .tabulator-col-resize-handle {
position: absolute;
right: 0;
top: 0;
bottom: 0;
width: 5px;
}
.tabulator .tabulator-col-resize-handle.prev {
left: 0;
right: auto;
}
.tabulator .tabulator-col-resize-handle:hover {
cursor: ew-resize;
}
.tabulator .tabulator-footer {
padding: 5px 10px;
border-top: 1px solid #999;
background-color: #fff;
text-align: right;
color: #555;
font-weight: bold;
white-space: nowrap;
-ms-user-select: none;
user-select: none;
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
-o-user-select: none;
}
.tabulator .tabulator-footer .tabulator-calcs-holder {
box-sizing: border-box;
width: calc(100% + 20px);
margin: -5px -10px 5px -10px;
text-align: left;
background: #f2f2f2 !important;
border-bottom: 1px solid #fff;
border-top: 1px solid #ddd;
overflow: hidden;
}
.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row {
background: #f2f2f2 !important;
}
.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row .tabulator-col-resize-handle {
display: none;
}
.tabulator .tabulator-footer .tabulator-calcs-holder:only-child {
margin-bottom: -5px;
border-bottom: none;
}
.tabulator .tabulator-footer .tabulator-pages {
margin: 0 7px;
}
.tabulator .tabulator-footer .tabulator-page {
display: inline-block;
margin: 0 2px;
border: 1px solid #aaa;
border-radius: 3px;
padding: 2px 5px;
background: rgba(255, 255, 255, 0.2);
color: #555;
font-family: inherit;
font-weight: inherit;
font-size: inherit;
}
.tabulator .tabulator-footer .tabulator-page.active {
color: #d00;
}
.tabulator .tabulator-footer .tabulator-page:disabled {
opacity: .5;
}
.tabulator .tabulator-footer .tabulator-page:not(.disabled):hover {
cursor: pointer;
background: rgba(0, 0, 0, 0.2);
color: #fff;
}
.tabulator .tabulator-loader {
position: absolute;
display: -ms-flexbox;
display: flex;
-ms-flex-align: center;
align-items: center;
top: 0;
left: 0;
z-index: 100;
height: 100%;
width: 100%;
background: rgba(0, 0, 0, 0.4);
text-align: center;
}
.tabulator .tabulator-loader .tabulator-loader-msg {
display: inline-block;
margin: 0 auto;
padding: 10px 20px;
border-radius: 10px;
background: #fff;
font-weight: bold;
font-size: 16px;
}
.tabulator .tabulator-loader .tabulator-loader-msg.tabulator-loading {
border: 4px solid #333;
color: #000;
}
.tabulator .tabulator-loader .tabulator-loader-msg.tabulator-error {
border: 4px solid #D00;
color: #590000;
}
.tabulator-row {
position: relative;
box-sizing: border-box;
min-height: 22px;
background-color: #fff;
border-bottom: 1px solid #ddd;
}
.tabulator-row:nth-child(even) {
background-color: #fff;
}
.tabulator-row.tabulator-selectable:hover {
background-color: #bbb;
cursor: pointer;
}
.tabulator-row.tabulator-selected {
background-color: #9ABCEA;
}
.tabulator-row.tabulator-selected:hover {
background-color: #769BCC;
cursor: pointer;
}
.tabulator-row.tabulator-moving {
position: absolute;
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
pointer-events: none !important;
z-index: 15;
}
.tabulator-row .tabulator-row-resize-handle {
position: absolute;
right: 0;
bottom: 0;
left: 0;
height: 5px;
}
.tabulator-row .tabulator-row-resize-handle.prev {
top: 0;
bottom: auto;
}
.tabulator-row .tabulator-row-resize-handle:hover {
cursor: ns-resize;
}
.tabulator-row .tabulator-frozen {
display: inline-block;
position: absolute;
background-color: inherit;
z-index: 10;
}
.tabulator-row .tabulator-frozen.tabulator-frozen-left {
border-right: 2px solid #ddd;
}
.tabulator-row .tabulator-frozen.tabulator-frozen-right {
border-left: 2px solid #ddd;
}
.tabulator-row .tabulator-responsive-collapse {
box-sizing: border-box;
padding: 5px;
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
}
.tabulator-row .tabulator-responsive-collapse:empty {
display: none;
}
.tabulator-row .tabulator-responsive-collapse table {
font-size: 14px;
}
.tabulator-row .tabulator-responsive-collapse table tr td {
position: relative;
}
.tabulator-row .tabulator-responsive-collapse table tr td:first-of-type {
padding-right: 10px;
}
.tabulator-row .tabulator-cell {
display: inline-block;
position: relative;
box-sizing: border-box;
padding: 4px;
border-right: 1px solid #ddd;
vertical-align: middle;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.tabulator-row .tabulator-cell:last-of-type {
border-right: none;
}
.tabulator-row .tabulator-cell.tabulator-editing {
border: 1px solid #1D68CD;
padding: 0;
}
.tabulator-row .tabulator-cell.tabulator-editing input, .tabulator-row .tabulator-cell.tabulator-editing select {
border: 1px;
background: transparent;
}
.tabulator-row .tabulator-cell.tabulator-validation-fail {
border: 1px solid #dd0000;
}
.tabulator-row .tabulator-cell.tabulator-validation-fail input, .tabulator-row .tabulator-cell.tabulator-validation-fail select {
border: 1px;
background: transparent;
color: #dd0000;
}
.tabulator-row .tabulator-cell:first-child .tabulator-col-resize-handle.prev {
display: none;
}
.tabulator-row .tabulator-cell.tabulator-row-handle {
display: -ms-inline-flexbox;
display: inline-flex;
-ms-flex-align: center;
align-items: center;
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
-o-user-select: none;
}
.tabulator-row .tabulator-cell.tabulator-row-handle .tabulator-row-handle-box {
width: 80%;
}
.tabulator-row .tabulator-cell.tabulator-row-handle .tabulator-row-handle-box .tabulator-row-handle-bar {
width: 100%;
height: 3px;
margin-top: 2px;
background: #666;
}
.tabulator-row .tabulator-cell .tabulator-data-tree-branch {
display: inline-block;
vertical-align: middle;
height: 9px;
width: 7px;
margin-top: -9px;
margin-right: 5px;
border-bottom-left-radius: 1px;
border-left: 2px solid #ddd;
border-bottom: 2px solid #ddd;
}
.tabulator-row .tabulator-cell .tabulator-data-tree-control {
display: -ms-inline-flexbox;
display: inline-flex;
-ms-flex-pack: center;
justify-content: center;
-ms-flex-align: center;
align-items: center;
vertical-align: middle;
height: 11px;
width: 11px;
margin-right: 5px;
border: 1px solid #333;
border-radius: 2px;
background: rgba(0, 0, 0, 0.1);
overflow: hidden;
}
.tabulator-row .tabulator-cell .tabulator-data-tree-control:hover {
cursor: pointer;
background: rgba(0, 0, 0, 0.2);
}
.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-collapse {
display: inline-block;
position: relative;
height: 7px;
width: 1px;
background: transparent;
}
.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-collapse:after {
position: absolute;
content: "";
left: -3px;
top: 3px;
height: 1px;
width: 7px;
background: #333;
}
.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-expand {
display: inline-block;
position: relative;
height: 7px;
width: 1px;
background: #333;
}
.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-expand:after {
position: absolute;
content: "";
left: -3px;
top: 3px;
height: 1px;
width: 7px;
background: #333;
}
.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle {
display: -ms-inline-flexbox;
display: inline-flex;
-ms-flex-align: center;
align-items: center;
-ms-flex-pack: center;
justify-content: center;
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
-o-user-select: none;
height: 15px;
width: 15px;
border-radius: 20px;
background: #666;
color: #fff;
font-weight: bold;
font-size: 1.1em;
}
.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle:hover {
opacity: .7;
}
.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle.open .tabulator-responsive-collapse-toggle-close {
display: initial;
}
.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle.open .tabulator-responsive-collapse-toggle-open {
display: none;
}
.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle .tabulator-responsive-collapse-toggle-close {
display: none;
}
.tabulator-row.tabulator-group {
box-sizing: border-box;
border-bottom: 1px solid #999;
border-right: 1px solid #ddd;
border-top: 1px solid #999;
padding: 5px;
padding-left: 10px;
background: #fafafa;
font-weight: bold;
min-width: 100%;
}
.tabulator-row.tabulator-group:hover {
cursor: pointer;
background-color: rgba(0, 0, 0, 0.1);
}
.tabulator-row.tabulator-group.tabulator-group-visible .tabulator-arrow {
margin-right: 10px;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-top: 6px solid #666;
border-bottom: 0;
}
.tabulator-row.tabulator-group.tabulator-group-level-1 .tabulator-arrow {
margin-left: 20px;
}
.tabulator-row.tabulator-group.tabulator-group-level-2 .tabulator-arrow {
margin-left: 40px;
}
.tabulator-row.tabulator-group.tabulator-group-level-3 .tabulator-arrow {
margin-left: 60px;
}
.tabulator-row.tabulator-group.tabulator-group-level-4 .tabulator-arrow {
margin-left: 80px;
}
.tabulator-row.tabulator-group.tabulator-group-level-5 .tabulator-arrow {
margin-left: 100px;
}
.tabulator-row.tabulator-group .tabulator-arrow {
display: inline-block;
width: 0;
height: 0;
margin-right: 16px;
border-top: 6px solid transparent;
border-bottom: 6px solid transparent;
border-right: 0;
border-left: 6px solid #666;
vertical-align: middle;
}
.tabulator-row.tabulator-group span {
margin-left: 10px;
color: #666;
}
.tabulator-edit-select-list {
position: absolute;
display: inline-block;
box-sizing: border-box;
max-height: 200px;
background: #fff;
border: 1px solid #ddd;
font-size: 14px;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
z-index: 10000;
}
.tabulator-edit-select-list .tabulator-edit-select-list-item {
padding: 4px;
color: #333;
}
.tabulator-edit-select-list .tabulator-edit-select-list-item.active {
color: #fff;
background: #1D68CD;
}
.tabulator-edit-select-list .tabulator-edit-select-list-item:hover {
cursor: pointer;
color: #fff;
background: #1D68CD;
}
.tabulator-edit-select-list .tabulator-edit-select-list-group {
border-bottom: 1px solid #ddd;
padding: 4px;
padding-top: 6px;
color: #333;
font-weight: bold;
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,765 @@
/* Tabulator v4.1.2 (c) Oliver Folkerd */
.tabulator {
position: relative;
border-bottom: 5px solid #222;
background-color: #fff;
font-size: 14px;
text-align: left;
overflow: hidden;
-ms-transform: translatez(0);
transform: translatez(0);
}
.tabulator[tabulator-layout="fitDataFill"] .tabulator-tableHolder .tabulator-table {
min-width: 100%;
}
.tabulator[tabulator-layout="fitColumns"] .tabulator-row .tabulator-cell:last-of-type {
border-right: none;
}
.tabulator.tabulator-block-select {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.tabulator .tabulator-header {
position: relative;
box-sizing: border-box;
width: 100%;
border-bottom: 3px solid #3FB449;
background-color: #222;
color: #fff;
font-weight: bold;
white-space: nowrap;
overflow: hidden;
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
-o-user-select: none;
}
.tabulator .tabulator-header .tabulator-col {
display: inline-block;
position: relative;
box-sizing: border-box;
border-right: 1px solid #aaa;
background-color: #222;
text-align: left;
vertical-align: bottom;
overflow: hidden;
}
.tabulator .tabulator-header .tabulator-col.tabulator-moving {
position: absolute;
border: 1px solid #3FB449;
background: #090909;
pointer-events: none;
}
.tabulator .tabulator-header .tabulator-col .tabulator-col-content {
box-sizing: border-box;
position: relative;
padding: 8px;
}
.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title {
box-sizing: border-box;
width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
vertical-align: bottom;
}
.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title .tabulator-title-editor {
box-sizing: border-box;
width: 100%;
border: 1px solid #999;
padding: 1px;
background: #fff;
}
.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-arrow {
display: inline-block;
position: absolute;
top: 14px;
right: 8px;
width: 0;
height: 0;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid #bbb;
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-group .tabulator-col-group-cols {
position: relative;
display: -ms-flexbox;
display: flex;
border-top: 1px solid #aaa;
overflow: hidden;
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-group .tabulator-col-group-cols .tabulator-col:last-child {
margin-right: -1px;
}
.tabulator .tabulator-header .tabulator-col:first-child .tabulator-col-resize-handle.prev {
display: none;
}
.tabulator .tabulator-header .tabulator-col.ui-sortable-helper {
position: absolute;
background-color: #222 !important;
border: 1px solid #aaa;
}
.tabulator .tabulator-header .tabulator-col .tabulator-header-filter {
position: relative;
box-sizing: border-box;
margin-top: 2px;
width: 100%;
text-align: center;
}
.tabulator .tabulator-header .tabulator-col .tabulator-header-filter textarea {
height: auto !important;
}
.tabulator .tabulator-header .tabulator-col .tabulator-header-filter svg {
margin-top: 3px;
}
.tabulator .tabulator-header .tabulator-col .tabulator-header-filter input::-ms-clear {
width: 0;
height: 0;
}
.tabulator .tabulator-header .tabulator-col.tabulator-sortable .tabulator-col-title {
padding-right: 25px;
}
.tabulator .tabulator-header .tabulator-col.tabulator-sortable:hover {
cursor: pointer;
background-color: #090909;
}
.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="none"] .tabulator-col-content .tabulator-arrow {
border-top: none;
border-bottom: 6px solid #bbb;
}
.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="asc"] .tabulator-col-content .tabulator-arrow {
border-top: none;
border-bottom: 6px solid #3FB449;
}
.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="desc"] .tabulator-col-content .tabulator-arrow {
border-top: 6px solid #3FB449;
border-bottom: none;
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical .tabulator-col-content .tabulator-col-title {
-webkit-writing-mode: vertical-rl;
-ms-writing-mode: tb-rl;
writing-mode: vertical-rl;
text-orientation: mixed;
display: -ms-flexbox;
display: flex;
-ms-flex-align: center;
align-items: center;
-ms-flex-pack: center;
justify-content: center;
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-col-vertical-flip .tabulator-col-title {
-ms-transform: rotate(180deg);
transform: rotate(180deg);
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable .tabulator-col-title {
padding-right: 0;
padding-top: 20px;
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable.tabulator-col-vertical-flip .tabulator-col-title {
padding-right: 0;
padding-bottom: 20px;
}
.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable .tabulator-arrow {
right: calc(50% - 6px);
}
.tabulator .tabulator-header .tabulator-frozen {
display: inline-block;
position: absolute;
z-index: 10;
}
.tabulator .tabulator-header .tabulator-frozen.tabulator-frozen-left {
border-right: 2px solid #aaa;
}
.tabulator .tabulator-header .tabulator-frozen.tabulator-frozen-right {
border-left: 2px solid #aaa;
}
.tabulator .tabulator-header .tabulator-calcs-holder {
box-sizing: border-box;
min-width: 400%;
background: #3c3c3c !important;
border-top: 1px solid #aaa;
overflow: hidden;
}
.tabulator .tabulator-header .tabulator-calcs-holder .tabulator-row {
background: #3c3c3c !important;
}
.tabulator .tabulator-header .tabulator-calcs-holder .tabulator-row .tabulator-col-resize-handle {
display: none;
}
.tabulator .tabulator-header .tabulator-frozen-rows-holder {
min-width: 400%;
}
.tabulator .tabulator-header .tabulator-frozen-rows-holder:empty {
display: none;
}
.tabulator .tabulator-tableHolder {
position: relative;
width: 100%;
white-space: nowrap;
overflow: auto;
-webkit-overflow-scrolling: touch;
}
.tabulator .tabulator-tableHolder:focus {
outline: none;
}
.tabulator .tabulator-tableHolder .tabulator-placeholder {
box-sizing: border-box;
display: -ms-flexbox;
display: flex;
-ms-flex-align: center;
align-items: center;
width: 100%;
}
.tabulator .tabulator-tableHolder .tabulator-placeholder[tabulator-render-mode="virtual"] {
position: absolute;
top: 0;
left: 0;
height: 100%;
}
.tabulator .tabulator-tableHolder .tabulator-placeholder span {
display: inline-block;
margin: 0 auto;
padding: 10px;
color: #3FB449;
font-weight: bold;
font-size: 20px;
}
.tabulator .tabulator-tableHolder .tabulator-table {
position: relative;
display: inline-block;
background-color: #fff;
white-space: nowrap;
overflow: visible;
color: #333;
}
.tabulator .tabulator-tableHolder .tabulator-table .tabulator-row.tabulator-calcs {
font-weight: bold;
background: #484848 !important;
color: #fff;
}
.tabulator .tabulator-footer {
padding: 5px 10px;
padding-top: 8px;
border-top: 3px solid #3FB449;
background-color: #222;
text-align: right;
color: #222;
font-weight: bold;
white-space: nowrap;
-ms-user-select: none;
user-select: none;
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
-o-user-select: none;
}
.tabulator .tabulator-footer .tabulator-calcs-holder {
box-sizing: border-box;
width: calc(100% + 20px);
margin: -8px -10px 8px -10px;
text-align: left;
background: #3c3c3c !important;
border-bottom: 1px solid #aaa;
overflow: hidden;
}
.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row {
background: #3c3c3c !important;
color: #fff !important;
}
.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row .tabulator-col-resize-handle {
display: none;
}
.tabulator .tabulator-footer .tabulator-calcs-holder:only-child {
margin-bottom: -5px;
border-bottom: none;
}
.tabulator .tabulator-footer .tabulator-pages {
margin: 0 7px;
}
.tabulator .tabulator-footer .tabulator-page {
display: inline-block;
margin: 0 2px;
padding: 2px 5px;
border: 1px solid #aaa;
border-radius: 3px;
background: #fff;
color: #222;
font-family: inherit;
font-weight: inherit;
font-size: inherit;
}
.tabulator .tabulator-footer .tabulator-page.active {
color: #3FB449;
}
.tabulator .tabulator-footer .tabulator-page:disabled {
opacity: .5;
}
.tabulator .tabulator-footer .tabulator-page:not(.disabled):hover {
cursor: pointer;
background: rgba(0, 0, 0, 0.2);
color: #fff;
}
.tabulator .tabulator-col-resize-handle {
position: absolute;
right: 0;
top: 0;
bottom: 0;
width: 5px;
}
.tabulator .tabulator-col-resize-handle.prev {
left: 0;
right: auto;
}
.tabulator .tabulator-col-resize-handle:hover {
cursor: ew-resize;
}
.tabulator .tabulator-loader {
position: absolute;
display: -ms-flexbox;
display: flex;
-ms-flex-align: center;
align-items: center;
top: 0;
left: 0;
z-index: 100;
height: 100%;
width: 100%;
background: rgba(0, 0, 0, 0.4);
text-align: center;
}
.tabulator .tabulator-loader .tabulator-loader-msg {
display: inline-block;
margin: 0 auto;
padding: 10px 20px;
border-radius: 10px;
background: #fff;
font-weight: bold;
font-size: 16px;
}
.tabulator .tabulator-loader .tabulator-loader-msg.tabulator-loading {
border: 4px solid #333;
color: #000;
}
.tabulator .tabulator-loader .tabulator-loader-msg.tabulator-error {
border: 4px solid #D00;
color: #590000;
}
.tabulator-row {
position: relative;
box-sizing: border-box;
min-height: 22px;
background-color: #fff;
}
.tabulator-row.tabulator-row-even {
background-color: #EFEFEF;
}
.tabulator-row.tabulator-selectable:hover {
background-color: #bbb;
cursor: pointer;
}
.tabulator-row.tabulator-selected {
background-color: #9ABCEA;
}
.tabulator-row.tabulator-selected:hover {
background-color: #769BCC;
cursor: pointer;
}
.tabulator-row.tabulator-row-moving {
border: 1px solid #000;
background: #fff;
}
.tabulator-row.tabulator-moving {
position: absolute;
border-top: 1px solid #aaa;
border-bottom: 1px solid #aaa;
pointer-events: none !important;
z-index: 15;
}
.tabulator-row .tabulator-row-resize-handle {
position: absolute;
right: 0;
bottom: 0;
left: 0;
height: 5px;
}
.tabulator-row .tabulator-row-resize-handle.prev {
top: 0;
bottom: auto;
}
.tabulator-row .tabulator-row-resize-handle:hover {
cursor: ns-resize;
}
.tabulator-row .tabulator-frozen {
display: inline-block;
position: absolute;
background-color: inherit;
z-index: 10;
}
.tabulator-row .tabulator-frozen.tabulator-frozen-left {
border-right: 2px solid #aaa;
}
.tabulator-row .tabulator-frozen.tabulator-frozen-right {
border-left: 2px solid #aaa;
}
.tabulator-row .tabulator-responsive-collapse {
box-sizing: border-box;
padding: 5px;
border-top: 1px solid #aaa;
border-bottom: 1px solid #aaa;
}
.tabulator-row .tabulator-responsive-collapse:empty {
display: none;
}
.tabulator-row .tabulator-responsive-collapse table {
font-size: 14px;
}
.tabulator-row .tabulator-responsive-collapse table tr td {
position: relative;
}
.tabulator-row .tabulator-responsive-collapse table tr td:first-of-type {
padding-right: 10px;
}
.tabulator-row .tabulator-cell {
display: inline-block;
position: relative;
box-sizing: border-box;
padding: 6px;
border-right: 1px solid #aaa;
vertical-align: middle;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.tabulator-row .tabulator-cell.tabulator-editing {
border: 1px solid #1D68CD;
padding: 0;
}
.tabulator-row .tabulator-cell.tabulator-editing input, .tabulator-row .tabulator-cell.tabulator-editing select {
border: 1px;
background: transparent;
}
.tabulator-row .tabulator-cell.tabulator-validation-fail {
border: 1px solid #dd0000;
}
.tabulator-row .tabulator-cell.tabulator-validation-fail input, .tabulator-row .tabulator-cell.tabulator-validation-fail select {
border: 1px;
background: transparent;
color: #dd0000;
}
.tabulator-row .tabulator-cell:first-child .tabulator-col-resize-handle.prev {
display: none;
}
.tabulator-row .tabulator-cell.tabulator-row-handle {
display: -ms-inline-flexbox;
display: inline-flex;
-ms-flex-align: center;
align-items: center;
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
-o-user-select: none;
}
.tabulator-row .tabulator-cell.tabulator-row-handle .tabulator-row-handle-box {
width: 80%;
}
.tabulator-row .tabulator-cell.tabulator-row-handle .tabulator-row-handle-box .tabulator-row-handle-bar {
width: 100%;
height: 3px;
margin-top: 2px;
background: #3FB449;
}
.tabulator-row .tabulator-cell .tabulator-data-tree-branch {
display: inline-block;
vertical-align: middle;
height: 9px;
width: 7px;
margin-top: -9px;
margin-right: 5px;
border-bottom-left-radius: 1px;
border-left: 2px solid #aaa;
border-bottom: 2px solid #aaa;
}
.tabulator-row .tabulator-cell .tabulator-data-tree-control {
display: -ms-inline-flexbox;
display: inline-flex;
-ms-flex-pack: center;
justify-content: center;
-ms-flex-align: center;
align-items: center;
vertical-align: middle;
height: 11px;
width: 11px;
margin-right: 5px;
border: 1px solid #333;
border-radius: 2px;
background: rgba(0, 0, 0, 0.1);
overflow: hidden;
}
.tabulator-row .tabulator-cell .tabulator-data-tree-control:hover {
cursor: pointer;
background: rgba(0, 0, 0, 0.2);
}
.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-collapse {
display: inline-block;
position: relative;
height: 7px;
width: 1px;
background: transparent;
}
.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-collapse:after {
position: absolute;
content: "";
left: -3px;
top: 3px;
height: 1px;
width: 7px;
background: #333;
}
.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-expand {
display: inline-block;
position: relative;
height: 7px;
width: 1px;
background: #333;
}
.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-expand:after {
position: absolute;
content: "";
left: -3px;
top: 3px;
height: 1px;
width: 7px;
background: #333;
}
.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle {
display: -ms-inline-flexbox;
display: inline-flex;
-ms-flex-align: center;
align-items: center;
-ms-flex-pack: center;
justify-content: center;
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
-o-user-select: none;
height: 15px;
width: 15px;
border-radius: 20px;
background: #666;
color: #fff;
font-weight: bold;
font-size: 1.1em;
}
.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle:hover {
opacity: .7;
}
.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle.open .tabulator-responsive-collapse-toggle-close {
display: initial;
}
.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle.open .tabulator-responsive-collapse-toggle-open {
display: none;
}
.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle .tabulator-responsive-collapse-toggle-close {
display: none;
}
.tabulator-row.tabulator-group {
box-sizing: border-box;
border-right: 1px solid #aaa;
border-top: 1px solid #000;
border-bottom: 2px solid #3FB449;
padding: 5px;
padding-left: 10px;
background: #222;
color: #fff;
font-weight: bold;
min-width: 100%;
}
.tabulator-row.tabulator-group:hover {
cursor: pointer;
background-color: #090909;
}
.tabulator-row.tabulator-group.tabulator-group-visible .tabulator-arrow {
margin-right: 10px;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-top: 6px solid #3FB449;
border-bottom: 0;
}
.tabulator-row.tabulator-group.tabulator-group-level-1 .tabulator-arrow {
margin-left: 20px;
}
.tabulator-row.tabulator-group.tabulator-group-level-2 .tabulator-arrow {
margin-left: 40px;
}
.tabulator-row.tabulator-group.tabulator-group-level-3 .tabulator-arrow {
margin-left: 60px;
}
.tabulator-row.tabulator-group.tabulator-group-level-4 .tabulator-arrow {
margin-left: 80px;
}
.tabulator-row.tabulator-group.tabulator-group-level-5 .tabulator-arrow {
margin-left: 100px;
}
.tabulator-row.tabulator-group .tabulator-arrow {
display: inline-block;
width: 0;
height: 0;
margin-right: 16px;
border-top: 6px solid transparent;
border-bottom: 6px solid transparent;
border-right: 0;
border-left: 6px solid #3FB449;
vertical-align: middle;
}
.tabulator-row.tabulator-group span {
margin-left: 10px;
color: #3FB449;
}
.tabulator-edit-select-list {
position: absolute;
display: inline-block;
box-sizing: border-box;
max-height: 200px;
background: #fff;
border: 1px solid #aaa;
font-size: 14px;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
z-index: 10000;
}
.tabulator-edit-select-list .tabulator-edit-select-list-item {
padding: 4px;
color: #333;
}
.tabulator-edit-select-list .tabulator-edit-select-list-item.active {
color: #fff;
background: #1D68CD;
}
.tabulator-edit-select-list .tabulator-edit-select-list-item:hover {
cursor: pointer;
color: #fff;
background: #1D68CD;
}
.tabulator-edit-select-list .tabulator-edit-select-list-group {
border-bottom: 1px solid #aaa;
padding: 4px;
padding-top: 6px;
color: #333;
font-weight: bold;
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,46 @@
/* Tabulator v4.1.2 (c) Oliver Folkerd */
/*
* This file is part of the Tabulator package.
*
* (c) Oliver Folkerd <oliver.folkerd@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* Full Documentation & Demos can be found at: http://olifolkerd.github.io/tabulator/
*
*/
(function (factory) {
"use strict";
if (typeof define === 'function' && define.amd) {
define(['jquery'], factory);
} else if (typeof module !== 'undefined' && module.exports) {
module.exports = factory(require('jquery'));
} else {
factory(jQuery);
}
})(function ($, undefined) {
$.widget("ui.tabulator", {
_create: function _create() {
this.table = new Tabulator(this.element[0], this.options);
//map tabulator functions to jquery wrapper
for (var key in Tabulator.prototype) {
if (typeof Tabulator.prototype[key] === "function" && key.charAt(0) !== "_") {
this[key] = this.table[key].bind(this.table);
}
}
},
_setOption: function _setOption(option, value) {
console.error("Tabulator jQuery wrapper does not support setting options after the table has been instantiated");
},
_destroy: function _destroy(option, value) {
this.table.destroy();
}
});
});
@@ -0,0 +1,2 @@
/* Tabulator v4.1.2 (c) Oliver Folkerd */
!function(t){"use strict";"function"==typeof define&&define.amd?define(["jquery"],t):"undefined"!=typeof module&&module.exports?module.exports=t(require("jquery")):t(jQuery)}(function(t,e){t.widget("ui.tabulator",{_create:function(){this.table=new Tabulator(this.element[0],this.options);for(var t in Tabulator.prototype)"function"==typeof Tabulator.prototype[t]&&"_"!==t.charAt(0)&&(this[t]=this.table[t].bind(this.table))},_setOption:function(t,e){console.error("Tabulator jQuery wrapper does not support setting options after the table has been instantiated")},_destroy:function(t,e){this.table.destroy()}})});
@@ -0,0 +1,91 @@
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
/* Tabulator v4.1.2 (c) Oliver Folkerd */
var Accessor = function Accessor(table) {
this.table = table; //hold Tabulator object
this.allowedTypes = ["", "data", "download", "clipboard"]; //list of accessor types
};
//initialize column accessor
Accessor.prototype.initializeColumn = function (column) {
var self = this,
match = false,
config = {};
this.allowedTypes.forEach(function (type) {
var key = "accessor" + (type.charAt(0).toUpperCase() + type.slice(1)),
accessor;
if (column.definition[key]) {
accessor = self.lookupAccessor(column.definition[key]);
if (accessor) {
match = true;
config[key] = {
accessor: accessor,
params: column.definition[key + "Params"] || {}
};
}
}
});
if (match) {
column.modules.accessor = config;
}
}, Accessor.prototype.lookupAccessor = function (value) {
var accessor = false;
//set column accessor
switch (typeof value === "undefined" ? "undefined" : _typeof(value)) {
case "string":
if (this.accessors[value]) {
accessor = this.accessors[value];
} else {
console.warn("Accessor Error - No such accessor found, ignoring: ", value);
}
break;
case "function":
accessor = value;
break;
}
return accessor;
};
//apply accessor to row
Accessor.prototype.transformRow = function (dataIn, type) {
var self = this,
key = "accessor" + (type.charAt(0).toUpperCase() + type.slice(1));
//clone data object with deep copy to isolate internal data from returned result
var data = Tabulator.prototype.helpers.deepClone(dataIn || {});
self.table.columnManager.traverse(function (column) {
var value, accessor, params, component;
if (column.modules.accessor) {
accessor = column.modules.accessor[key] || column.modules.accessor.accessor || false;
if (accessor) {
value = column.getFieldValue(data);
if (value != "undefined") {
component = column.getComponent();
params = typeof accessor.params === "function" ? accessor.params(value, data, type, component) : accessor.params;
column.setFieldValue(data, accessor.accessor(value, data, type, params, component));
}
}
}
});
return data;
},
//default accessors
Accessor.prototype.accessors = {};
Tabulator.prototype.registerModule("accessor", Accessor);
@@ -0,0 +1,2 @@
/* Tabulator v4.1.2 (c) Oliver Folkerd */
var _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(o){return typeof o}:function(o){return o&&"function"==typeof Symbol&&o.constructor===Symbol&&o!==Symbol.prototype?"symbol":typeof o},Accessor=function(o){this.table=o,this.allowedTypes=["","data","download","clipboard"]};Accessor.prototype.initializeColumn=function(o){var e=this,s=!1,r={};this.allowedTypes.forEach(function(c){var t,a="accessor"+(c.charAt(0).toUpperCase()+c.slice(1));o.definition[a]&&(t=e.lookupAccessor(o.definition[a]))&&(s=!0,r[a]={accessor:t,params:o.definition[a+"Params"]||{}})}),s&&(o.modules.accessor=r)},Accessor.prototype.lookupAccessor=function(o){var e=!1;switch(void 0===o?"undefined":_typeof(o)){case"string":this.accessors[o]?e=this.accessors[o]:console.warn("Accessor Error - No such accessor found, ignoring: ",o);break;case"function":e=o}return e},Accessor.prototype.transformRow=function(o,e){var s=this,r="accessor"+(e.charAt(0).toUpperCase()+e.slice(1)),c=Tabulator.prototype.helpers.deepClone(o||{});return s.table.columnManager.traverse(function(o){var s,t,a,n;o.modules.accessor&&(t=o.modules.accessor[r]||o.modules.accessor.accessor||!1)&&"undefined"!=(s=o.getFieldValue(c))&&(n=o.getComponent(),a="function"==typeof t.params?t.params(s,c,e,n):t.params,o.setFieldValue(c,t.accessor(s,c,e,a,n)))}),c},Accessor.prototype.accessors={},Tabulator.prototype.registerModule("accessor",Accessor);
@@ -0,0 +1,429 @@
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
/* Tabulator v4.1.2 (c) Oliver Folkerd */
var Ajax = function Ajax(table) {
this.table = table; //hold Tabulator object
this.config = false; //hold config object for ajax request
this.url = ""; //request URL
this.urlGenerator = false;
this.params = false; //request parameters
this.loaderElement = this.createLoaderElement(); //loader message div
this.msgElement = this.createMsgElement(); //message element
this.loadingElement = false;
this.errorElement = false;
this.loaderPromise = false;
this.progressiveLoad = false;
this.loading = false;
this.requestOrder = 0; //prevent requests comming out of sequence if overridden by another load request
};
//initialize setup options
Ajax.prototype.initialize = function () {
this.loaderElement.appendChild(this.msgElement);
if (this.table.options.ajaxLoaderLoading) {
this.loadingElement = this.table.options.ajaxLoaderLoading;
}
this.loaderPromise = this.table.options.ajaxRequestFunc || this.defaultLoaderPromise;
this.urlGenerator = this.table.options.ajaxURLGenerator || this.defaultURLGenerator;
if (this.table.options.ajaxLoaderError) {
this.errorElement = this.table.options.ajaxLoaderError;
}
if (this.table.options.ajaxParams) {
this.setParams(this.table.options.ajaxParams);
}
if (this.table.options.ajaxConfig) {
this.setConfig(this.table.options.ajaxConfig);
}
if (this.table.options.ajaxURL) {
this.setUrl(this.table.options.ajaxURL);
}
if (this.table.options.ajaxProgressiveLoad) {
if (this.table.options.pagination) {
this.progressiveLoad = false;
console.error("Progressive Load Error - Pagination and progressive load cannot be used at the same time");
} else {
if (this.table.modExists("page")) {
this.progressiveLoad = this.table.options.ajaxProgressiveLoad;
this.table.modules.page.initializeProgressive(this.progressiveLoad);
} else {
console.error("Pagination plugin is required for progressive ajax loading");
}
}
}
};
Ajax.prototype.createLoaderElement = function () {
var el = document.createElement("div");
el.classList.add("tabulator-loader");
return el;
};
Ajax.prototype.createMsgElement = function () {
var el = document.createElement("div");
el.classList.add("tabulator-loader-msg");
el.setAttribute("role", "alert");
return el;
};
//set ajax params
Ajax.prototype.setParams = function (params, update) {
if (update) {
this.params = this.params || {};
for (var key in params) {
this.params[key] = params[key];
}
} else {
this.params = params;
}
};
Ajax.prototype.getParams = function () {
return this.params || {};
};
//load config object
Ajax.prototype.setConfig = function (config) {
this._loadDefaultConfig();
if (typeof config == "string") {
this.config.method = config;
} else {
for (var key in config) {
this.config[key] = config[key];
}
}
};
//create config object from default
Ajax.prototype._loadDefaultConfig = function (force) {
var self = this;
if (!self.config || force) {
self.config = {};
//load base config from defaults
for (var key in self.defaultConfig) {
self.config[key] = self.defaultConfig[key];
}
}
};
//set request url
Ajax.prototype.setUrl = function (url) {
this.url = url;
};
//get request url
Ajax.prototype.getUrl = function () {
return this.url;
};
//lstandard loading function
Ajax.prototype.loadData = function (inPosition) {
var self = this;
if (this.progressiveLoad) {
return this._loadDataProgressive();
} else {
return this._loadDataStandard(inPosition);
}
};
Ajax.prototype.nextPage = function (diff) {
var margin;
if (!this.loading) {
margin = this.table.options.ajaxProgressiveLoadScrollMargin || this.table.rowManager.getElement().clientHeight * 2;
if (diff < margin) {
this.table.modules.page.nextPage().then(function () {}).catch(function () {});
}
}
};
Ajax.prototype.blockActiveRequest = function () {
this.requestOrder++;
};
Ajax.prototype._loadDataProgressive = function () {
this.table.rowManager.setData([]);
return this.table.modules.page.setPage(1);
};
Ajax.prototype._loadDataStandard = function (inPosition) {
var _this = this;
return new Promise(function (resolve, reject) {
_this.sendRequest(inPosition).then(function (data) {
_this.table.rowManager.setData(data, inPosition);
resolve();
}).catch(function (e) {
reject();
});
});
};
Ajax.prototype.generateParamsList = function (data, prefix) {
var self = this,
output = [];
prefix = prefix || "";
if (Array.isArray(data)) {
data.forEach(function (item, i) {
output = output.concat(self.generateParamsList(item, prefix ? prefix + "[" + i + "]" : i));
});
} else if ((typeof data === "undefined" ? "undefined" : _typeof(data)) === "object") {
for (var key in data) {
output = output.concat(self.generateParamsList(data[key], prefix ? prefix + "[" + key + "]" : key));
}
} else {
output.push({ key: prefix, value: data });
}
return output;
};
Ajax.prototype.serializeParams = function (params) {
var output = this.generateParamsList(params),
encoded = [];
output.forEach(function (item) {
encoded.push(encodeURIComponent(item.key) + "=" + encodeURIComponent(item.value));
});
return encoded.join("&");
};
//send ajax request
Ajax.prototype.sendRequest = function (silent) {
var _this2 = this;
var self = this,
url = self.url,
requestNo,
esc,
query;
self.requestOrder++;
requestNo = self.requestOrder;
self._loadDefaultConfig();
return new Promise(function (resolve, reject) {
if (self.table.options.ajaxRequesting.call(_this2.table, self.url, self.params) !== false) {
self.loading = true;
if (!silent) {
self.showLoader();
}
_this2.loaderPromise(url, self.config, self.params).then(function (data) {
if (requestNo === self.requestOrder) {
if (self.table.options.ajaxResponse) {
data = self.table.options.ajaxResponse.call(self.table, self.url, self.params, data);
}
resolve(data);
} else {
console.warn("Ajax Response Blocked - An active ajax request was blocked by an attempt to change table data while the request was being made");
}
self.hideLoader();
self.loading = false;
}).catch(function (error) {
console.error("Ajax Load Error: ", error);
self.table.options.ajaxError.call(self.table, error);
self.showError();
setTimeout(function () {
self.hideLoader();
}, 3000);
self.loading = false;
reject();
});
} else {
reject();
}
});
};
Ajax.prototype.showLoader = function () {
var shouldLoad = typeof this.table.options.ajaxLoader === "function" ? this.table.options.ajaxLoader() : this.table.options.ajaxLoader;
if (shouldLoad) {
this.hideLoader();
while (this.msgElement.firstChild) {
this.msgElement.removeChild(this.msgElement.firstChild);
}this.msgElement.classList.remove("tabulator-error");
this.msgElement.classList.add("tabulator-loading");
if (this.loadingElement) {
this.msgElement.appendChild(this.loadingElement);
} else {
this.msgElement.innerHTML = this.table.modules.localize.getText("ajax|loading");
}
this.table.element.appendChild(this.loaderElement);
}
};
Ajax.prototype.showError = function () {
this.hideLoader();
while (this.msgElement.firstChild) {
this.msgElement.removeChild(this.msgElement.firstChild);
}this.msgElement.classList.remove("tabulator-loading");
this.msgElement.classList.add("tabulator-error");
if (this.errorElement) {
this.msgElement.appendChild(this.errorElement);
} else {
this.msgElement.innerHTML = this.table.modules.localize.getText("ajax|error");
}
this.table.element.appendChild(this.loaderElement);
};
Ajax.prototype.hideLoader = function () {
if (this.loaderElement.parentNode) {
this.loaderElement.parentNode.removeChild(this.loaderElement);
}
};
//default ajax config object
Ajax.prototype.defaultConfig = {
method: "GET"
};
Ajax.prototype.defaultURLGenerator = function (url, config, params) {
if (params && Object.keys(params).length) {
if (!config.method || config.method.toLowerCase() == "get") {
config.method = "get";
url += "?" + this.serializeParams(params);
}
}
return url;
};
Ajax.prototype.defaultLoaderPromise = function (url, config, params) {
var self = this,
contentType;
return new Promise(function (resolve, reject) {
//set url
url = self.urlGenerator(url, config, params);
//set body content if not GET request
if (config.method != "get") {
contentType = _typeof(self.table.options.ajaxContentType) === "object" ? self.table.options.ajaxContentType : self.contentTypeFormatters[self.table.options.ajaxContentType];
if (contentType) {
for (var key in contentType.headers) {
if (!config.headers) {
config.headers = {};
}
if (typeof config.headers[key] === "undefined") {
config.headers[key] = contentType.headers[key];
}
}
config.body = contentType.body.call(self, url, config, params);
} else {
console.warn("Ajax Error - Invalid ajaxContentType value:", self.table.options.ajaxContentType);
}
}
if (url) {
//configure headers
if (typeof config.credentials === "undefined") {
config.credentials = 'include';
}
if (typeof config.headers === "undefined") {
config.headers = {};
}
if (typeof config.headers.Accept === "undefined") {
config.headers.Accept = "application/json";
}
if (typeof config.headers["X-Requested-With"] === "undefined") {
config.headers["X-Requested-With"] = "XMLHttpRequest";
}
//send request
fetch(url, config).then(function (response) {
if (response.ok) {
response.json().then(function (data) {
resolve(data);
}).catch(function (error) {
reject(error);
console.warn("Ajax Load Error - Invalid JSON returned", error);
});
} else {
console.error("Ajax Load Error - Connection Error: " + response.status, response.statusText);
reject(response);
}
}).catch(function (error) {
console.error("Ajax Load Error - Connection Error: ", error);
reject(error);
});
} else {
reject("No URL Set");
}
});
};
Ajax.prototype.contentTypeFormatters = {
"json": {
headers: {
'Content-Type': 'application/json'
},
body: function body(url, config, params) {
return JSON.stringify(params);
}
},
"form": {
headers: {},
body: function body(url, config, params) {
var output = this.generateParamsList(params),
form = new FormData();
output.forEach(function (item) {
form.append(item.key, item.value);
});
return form;
}
}
};
Tabulator.prototype.registerModule("ajax", Ajax);
File diff suppressed because one or more lines are too long
@@ -0,0 +1,453 @@
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
/* Tabulator v4.1.2 (c) Oliver Folkerd */
var ColumnCalcs = function ColumnCalcs(table) {
this.table = table; //hold Tabulator object
this.topCalcs = [];
this.botCalcs = [];
this.genColumn = false;
this.topElement = this.createElement();
this.botElement = this.createElement();
this.topRow = false;
this.botRow = false;
this.topInitialized = false;
this.botInitialized = false;
this.initialize();
};
ColumnCalcs.prototype.createElement = function () {
var el = document.createElement("div");
el.classList.add("tabulator-calcs-holder");
return el;
};
ColumnCalcs.prototype.initialize = function () {
this.genColumn = new Column({ field: "value" }, this);
};
//dummy functions to handle being mock column manager
ColumnCalcs.prototype.registerColumnField = function () {};
//initialize column calcs
ColumnCalcs.prototype.initializeColumn = function (column) {
var def = column.definition;
var config = {
topCalcParams: def.topCalcParams || {},
botCalcParams: def.bottomCalcParams || {}
};
if (def.topCalc) {
switch (_typeof(def.topCalc)) {
case "string":
if (this.calculations[def.topCalc]) {
config.topCalc = this.calculations[def.topCalc];
} else {
console.warn("Column Calc Error - No such calculation found, ignoring: ", def.topCalc);
}
break;
case "function":
config.topCalc = def.topCalc;
break;
}
if (config.topCalc) {
column.modules.columnCalcs = config;
this.topCalcs.push(column);
if (this.table.options.columnCalcs != "group") {
this.initializeTopRow();
}
}
}
if (def.bottomCalc) {
switch (_typeof(def.bottomCalc)) {
case "string":
if (this.calculations[def.bottomCalc]) {
config.botCalc = this.calculations[def.bottomCalc];
} else {
console.warn("Column Calc Error - No such calculation found, ignoring: ", def.bottomCalc);
}
break;
case "function":
config.botCalc = def.bottomCalc;
break;
}
if (config.botCalc) {
column.modules.columnCalcs = config;
this.botCalcs.push(column);
if (this.table.options.columnCalcs != "group") {
this.initializeBottomRow();
}
}
}
};
ColumnCalcs.prototype.removeCalcs = function () {
var changed = false;
if (this.topInitialized) {
this.topInitialized = false;
this.topElement.parentNode.removeChild(this.topElement);
changed = true;
}
if (this.botInitialized) {
this.botInitialized = false;
this.table.footerManager.remove(this.botElement);
changed = true;
}
if (changed) {
this.table.rowManager.adjustTableSize();
}
};
ColumnCalcs.prototype.initializeTopRow = function () {
if (!this.topInitialized) {
// this.table.columnManager.headersElement.after(this.topElement);
this.table.columnManager.getElement().insertBefore(this.topElement, this.table.columnManager.headersElement.nextSibling);
this.topInitialized = true;
}
};
ColumnCalcs.prototype.initializeBottomRow = function () {
if (!this.botInitialized) {
this.table.footerManager.prepend(this.botElement);
this.botInitialized = true;
}
};
ColumnCalcs.prototype.scrollHorizontal = function (left) {
var hozAdjust = 0,
scrollWidth = this.table.columnManager.getElement().scrollWidth - this.table.element.clientWidth;
if (this.botInitialized) {
this.botRow.getElement().style.marginLeft = -left + "px";
}
};
ColumnCalcs.prototype.recalc = function (rows) {
var data, row;
if (this.topInitialized || this.botInitialized) {
data = this.rowsToData(rows);
if (this.topInitialized) {
row = this.generateRow("top", this.rowsToData(rows));
this.topRow = row;
while (this.topElement.firstChild) {
this.topElement.removeChild(this.topElement.firstChild);
}this.topElement.appendChild(row.getElement());
row.initialize(true);
}
if (this.botInitialized) {
row = this.generateRow("bottom", this.rowsToData(rows));
this.botRow = row;
while (this.botElement.firstChild) {
this.botElement.removeChild(this.botElement.firstChild);
}this.botElement.appendChild(row.getElement());
row.initialize(true);
}
this.table.rowManager.adjustTableSize();
//set resizable handles
if (this.table.modExists("frozenColumns")) {
this.table.modules.frozenColumns.layout();
}
}
};
ColumnCalcs.prototype.recalcRowGroup = function (row) {
this.recalcGroup(this.table.modules.groupRows.getRowGroup(row));
};
ColumnCalcs.prototype.recalcGroup = function (group) {
var data, rowData;
if (group) {
if (group.calcs) {
if (group.calcs.bottom) {
data = this.rowsToData(group.rows);
rowData = this.generateRowData("bottom", data);
group.calcs.bottom.updateData(rowData);
group.calcs.bottom.reinitialize();
}
if (group.calcs.top) {
data = this.rowsToData(group.rows);
rowData = this.generateRowData("top", data);
group.calcs.top.updateData(rowData);
group.calcs.top.reinitialize();
}
}
}
};
//generate top stats row
ColumnCalcs.prototype.generateTopRow = function (rows) {
return this.generateRow("top", this.rowsToData(rows));
};
//generate bottom stats row
ColumnCalcs.prototype.generateBottomRow = function (rows) {
return this.generateRow("bottom", this.rowsToData(rows));
};
ColumnCalcs.prototype.rowsToData = function (rows) {
var data = [];
rows.forEach(function (row) {
data.push(row.getData());
});
return data;
};
//generate stats row
ColumnCalcs.prototype.generateRow = function (pos, data) {
var self = this,
rowData = this.generateRowData(pos, data),
row;
if (self.table.modExists("mutator")) {
self.table.modules.mutator.disable();
}
row = new Row(rowData, this);
if (self.table.modExists("mutator")) {
self.table.modules.mutator.enable();
}
row.getElement().classList.add("tabulator-calcs", "tabulator-calcs-" + pos);
row.type = "calc";
row.generateCells = function () {
var cells = [];
self.table.columnManager.columnsByIndex.forEach(function (column) {
if (column.visible) {
//set field name of mock column
self.genColumn.setField(column.getField());
self.genColumn.hozAlign = column.hozAlign;
if (column.definition[pos + "CalcFormatter"] && self.table.modExists("format")) {
self.genColumn.modules.format = {
formatter: self.table.modules.format.getFormatter(column.definition[pos + "CalcFormatter"]),
params: column.definition[pos + "CalcFormatterParams"]
};
} else {
self.genColumn.modules.format = {
formatter: self.table.modules.format.getFormatter("plaintext"),
params: {}
};
}
//generate cell and assign to correct column
var cell = new Cell(self.genColumn, row);
cell.column = column;
cell.setWidth(column.width);
column.cells.push(cell);
cells.push(cell);
}
});
this.cells = cells;
};
return row;
};
//generate stats row
ColumnCalcs.prototype.generateRowData = function (pos, data) {
var rowData = {},
calcs = pos == "top" ? this.topCalcs : this.botCalcs,
type = pos == "top" ? "topCalc" : "botCalc",
params,
paramKey;
calcs.forEach(function (column) {
var values = [];
if (column.modules.columnCalcs && column.modules.columnCalcs[type]) {
data.forEach(function (item) {
values.push(column.getFieldValue(item));
});
paramKey = type + "Params";
params = typeof column.modules.columnCalcs[paramKey] === "function" ? column.modules.columnCalcs[paramKey](value, data) : column.modules.columnCalcs[paramKey];
column.setFieldValue(rowData, column.modules.columnCalcs[type](values, data, params));
}
});
return rowData;
};
ColumnCalcs.prototype.hasTopCalcs = function () {
return !!this.topCalcs.length;
}, ColumnCalcs.prototype.hasBottomCalcs = function () {
return !!this.botCalcs.length;
},
//handle table redraw
ColumnCalcs.prototype.redraw = function () {
if (this.topRow) {
this.topRow.normalizeHeight(true);
}
if (this.botRow) {
this.botRow.normalizeHeight(true);
}
};
//return the calculated
ColumnCalcs.prototype.getResults = function () {
var self = this,
results = {},
groups;
if (this.table.options.groupBy && this.table.modExists("groupRows")) {
groups = this.table.modules.groupRows.getGroups(true);
groups.forEach(function (group) {
results[group.getKey()] = self.getGroupResults(group);
});
} else {
results = {
top: this.topRow ? this.topRow.getData() : {},
bottom: this.botRow ? this.botRow.getData() : {}
};
}
return results;
};
//get results from a group
ColumnCalcs.prototype.getGroupResults = function (group) {
var self = this,
groupObj = group._getSelf(),
subGroups = group.getSubGroups(),
subGroupResults = {},
results = {};
subGroups.forEach(function (subgroup) {
subGroupResults[subgroup.getKey()] = self.getGroupResults(subgroup);
});
results = {
top: groupObj.calcs.top ? groupObj.calcs.top.getData() : {},
bottom: groupObj.calcs.bottom ? groupObj.calcs.bottom.getData() : {},
groups: subGroupResults
};
return results;
};
//default calculations
ColumnCalcs.prototype.calculations = {
"avg": function avg(values, data, calcParams) {
var output = 0,
precision = typeof calcParams.precision !== "undefined" ? calcParams.precision : 2;
if (values.length) {
output = values.reduce(function (sum, value) {
value = Number(value);
return sum + value;
});
output = output / values.length;
output = precision !== false ? output.toFixed(precision) : output;
}
return parseFloat(output).toString();
},
"max": function max(values, data, calcParams) {
var output = null,
precision = typeof calcParams.precision !== "undefined" ? calcParams.precision : false;
values.forEach(function (value) {
value = Number(value);
if (value > output || output === null) {
output = value;
}
});
return output !== null ? precision !== false ? output.toFixed(precision) : output : "";
},
"min": function min(values, data, calcParams) {
var output = null,
precision = typeof calcParams.precision !== "undefined" ? calcParams.precision : false;
values.forEach(function (value) {
value = Number(value);
if (value < output || output === null) {
output = value;
}
});
return output !== null ? precision !== false ? output.toFixed(precision) : output : "";
},
"sum": function sum(values, data, calcParams) {
var output = 0,
precision = typeof calcParams.precision !== "undefined" ? calcParams.precision : false;
if (values.length) {
values.forEach(function (value) {
value = Number(value);
output += !isNaN(value) ? Number(value) : 0;
});
}
return precision !== false ? output.toFixed(precision) : output;
},
"concat": function concat(values, data, calcParams) {
var output = 0;
if (values.length) {
output = values.reduce(function (sum, value) {
return String(sum) + String(value);
});
}
return output;
},
"count": function count(values, data, calcParams) {
var output = 0;
if (values.length) {
values.forEach(function (value) {
if (value) {
output++;
}
});
}
return output;
}
};
Tabulator.prototype.registerModule("columnCalcs", ColumnCalcs);
File diff suppressed because one or more lines are too long
@@ -0,0 +1,923 @@
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
/* Tabulator v4.1.2 (c) Oliver Folkerd */
var Clipboard = function Clipboard(table) {
this.table = table;
this.mode = true;
this.copySelector = false;
this.copySelectorParams = {};
this.copyFormatter = false;
this.copyFormatterParams = {};
this.pasteParser = function () {};
this.pasteAction = function () {};
this.htmlElement = false;
this.config = {};
this.blocked = true; //block copy actions not originating from this command
};
Clipboard.prototype.initialize = function () {
var self = this;
this.mode = this.table.options.clipboard;
if (this.mode === true || this.mode === "copy") {
this.table.element.addEventListener("copy", function (e) {
var data;
self.processConfig();
if (!self.blocked) {
e.preventDefault();
data = self.generateContent();
if (window.clipboardData && window.clipboardData.setData) {
window.clipboardData.setData('Text', data);
} else if (e.clipboardData && e.clipboardData.setData) {
e.clipboardData.setData('text/plain', data);
if (self.htmlElement) {
e.clipboardData.setData('text/html', self.htmlElement.outerHTML);
}
} else if (e.originalEvent && e.originalEvent.clipboardData.setData) {
e.originalEvent.clipboardData.setData('text/plain', data);
if (self.htmlElement) {
e.originalEvent.clipboardData.setData('text/html', self.htmlElement.outerHTML);
}
}
self.table.options.clipboardCopied.call(this.table, data);
self.reset();
}
});
}
if (this.mode === true || this.mode === "paste") {
this.table.element.addEventListener("paste", function (e) {
self.paste(e);
});
}
this.setPasteParser(this.table.options.clipboardPasteParser);
this.setPasteAction(this.table.options.clipboardPasteAction);
};
Clipboard.prototype.processConfig = function () {
var config = {
columnHeaders: "groups",
rowGroups: true
};
if (typeof this.table.options.clipboardCopyHeader !== "undefined") {
config.columnHeaders = this.table.options.clipboardCopyHeader;
console.warn("DEPRECATION WANRING - clipboardCopyHeader option has been depricated, please use the columnHeaders property on the clipboardCopyConfig option");
}
if (this.table.options.clipboardCopyConfig) {
for (var key in this.table.options.clipboardCopyConfig) {
config[key] = this.table.options.clipboardCopyConfig[key];
}
}
if (config.rowGroups && this.table.options.groupBy && this.table.modExists("groupRows")) {
this.config.rowGroups = true;
}
if (config.columnHeaders) {
if ((config.columnHeaders === "groups" || config === true) && this.table.columnManager.columns.length != this.table.columnManager.columnsByIndex.length) {
this.config.columnHeaders = "groups";
} else {
this.config.columnHeaders = "columns";
}
} else {
this.config.columnHeaders = false;
}
};
Clipboard.prototype.reset = function () {
this.blocked = false;
this.originalSelectionText = "";
};
Clipboard.prototype.setPasteAction = function (action) {
switch (typeof action === "undefined" ? "undefined" : _typeof(action)) {
case "string":
this.pasteAction = this.pasteActions[action];
if (!this.pasteAction) {
console.warn("Clipboard Error - No such paste action found:", action);
}
break;
case "function":
this.pasteAction = action;
break;
}
};
Clipboard.prototype.setPasteParser = function (parser) {
switch (typeof parser === "undefined" ? "undefined" : _typeof(parser)) {
case "string":
this.pasteParser = this.pasteParsers[parser];
if (!this.pasteParser) {
console.warn("Clipboard Error - No such paste parser found:", parser);
}
break;
case "function":
this.pasteParser = parser;
break;
}
};
Clipboard.prototype.paste = function (e) {
var data, rowData, rows;
if (this.checkPaseOrigin(e)) {
data = this.getPasteData(e);
rowData = this.pasteParser.call(this, data);
if (rowData) {
e.preventDefault();
if (this.table.modExists("mutator")) {
rowData = this.mutateData(rowData);
}
rows = this.pasteAction.call(this, rowData);
this.table.options.clipboardPasted.call(this.table, data, rowData, rows);
} else {
this.table.options.clipboardPasteError.call(this.table, data);
}
}
};
Clipboard.prototype.mutateData = function (data) {
var self = this,
output = [];
if (Array.isArray(data)) {
data.forEach(function (row) {
output.push(self.table.modules.mutator.transformRow(row, "clipboard"));
});
} else {
output = data;
}
return output;
};
Clipboard.prototype.checkPaseOrigin = function (e) {
var valid = true;
if (e.target.tagName != "DIV" || this.table.modules.edit.currentCell) {
valid = false;
}
return valid;
};
Clipboard.prototype.getPasteData = function (e) {
var data;
if (window.clipboardData && window.clipboardData.getData) {
data = window.clipboardData.getData('Text');
} else if (e.clipboardData && e.clipboardData.getData) {
data = e.clipboardData.getData('text/plain');
} else if (e.originalEvent && e.originalEvent.clipboardData.getData) {
data = e.originalEvent.clipboardData.getData('text/plain');
}
return data;
};
Clipboard.prototype.copy = function (selector, selectorParams, formatter, formatterParams, internal) {
var range, sel;
this.blocked = false;
if (this.mode === true || this.mode === "copy") {
if (typeof window.getSelection != "undefined" && typeof document.createRange != "undefined") {
range = document.createRange();
range.selectNodeContents(this.table.element);
sel = window.getSelection();
if (sel.toString() && internal) {
selector = "userSelection";
formatter = "raw";
selectorParams = sel.toString();
}
sel.removeAllRanges();
sel.addRange(range);
} else if (typeof document.selection != "undefined" && typeof document.body.createTextRange != "undefined") {
textRange = document.body.createTextRange();
textRange.moveToElementText(this.table.element);
textRange.select();
}
this.setSelector(selector);
this.copySelectorParams = typeof selectorParams != "undefined" && selectorParams != null ? selectorParams : this.config.columnHeaders;
this.setFormatter(formatter);
this.copyFormatterParams = typeof formatterParams != "undefined" && formatterParams != null ? formatterParams : {};
document.execCommand('copy');
if (sel) {
sel.removeAllRanges();
}
}
};
Clipboard.prototype.setSelector = function (selector) {
selector = selector || this.table.options.clipboardCopySelector;
switch (typeof selector === "undefined" ? "undefined" : _typeof(selector)) {
case "string":
if (this.copySelectors[selector]) {
this.copySelector = this.copySelectors[selector];
} else {
console.warn("Clipboard Error - No such selector found:", selector);
}
break;
case "function":
this.copySelector = selector;
break;
}
};
Clipboard.prototype.setFormatter = function (formatter) {
formatter = formatter || this.table.options.clipboardCopyFormatter;
switch (typeof formatter === "undefined" ? "undefined" : _typeof(formatter)) {
case "string":
if (this.copyFormatters[formatter]) {
this.copyFormatter = this.copyFormatters[formatter];
} else {
console.warn("Clipboard Error - No such formatter found:", formatter);
}
break;
case "function":
this.copyFormatter = formatter;
break;
}
};
Clipboard.prototype.generateContent = function () {
var data;
this.htmlElement = false;
data = this.copySelector.call(this, this.config, this.copySelectorParams);
return this.copyFormatter.call(this, data, this.config, this.copyFormatterParams);
};
Clipboard.prototype.generateSimpleHeaders = function (columns) {
var headers = [];
columns.forEach(function (column) {
headers.push(column.definition.title);
});
return headers;
};
Clipboard.prototype.generateColumnGroupHeaders = function (columns) {
var _this = this;
var output = [];
this.table.columnManager.columns.forEach(function (column) {
var colData = _this.processColumnGroup(column);
if (colData) {
output.push(colData);
}
});
return output;
};
Clipboard.prototype.processColumnGroup = function (column) {
var _this2 = this;
var subGroups = column.columns;
var groupData = {
type: "group",
title: column.definition.title,
column: column
};
if (subGroups.length) {
groupData.subGroups = [];
groupData.width = 0;
subGroups.forEach(function (subGroup) {
var subGroupData = _this2.processColumnGroup(subGroup);
if (subGroupData) {
groupData.width += subGroupData.width;
groupData.subGroups.push(subGroupData);
}
});
if (!groupData.width) {
return false;
}
} else {
if (column.field && column.visible) {
groupData.width = 1;
} else {
return false;
}
}
return groupData;
};
Clipboard.prototype.groupHeadersToRows = function (columns) {
var headers = [];
function parseColumnGroup(column, level) {
if (typeof headers[level] === "undefined") {
headers[level] = [];
}
headers[level].push(column.title);
if (column.subGroups) {
column.subGroups.forEach(function (subGroup) {
parseColumnGroup(subGroup, level + 1);
});
} else {
padColumnheaders();
}
}
function padColumnheaders() {
var max = 0;
headers.forEach(function (title) {
var len = title.length;
if (len > max) {
max = len;
}
});
headers.forEach(function (title) {
var len = title.length;
if (len < max) {
for (var i = len; i < max; i++) {
title.push("");
}
}
});
}
columns.forEach(function (column) {
parseColumnGroup(column, 0);
});
return headers;
};
Clipboard.prototype.rowsToData = function (rows, config, params) {
var columns = this.table.columnManager.columnsByIndex,
data = [];
rows.forEach(function (row) {
var rowArray = [],
rowData = row.getData("clipboard");
columns.forEach(function (column) {
var value = column.getFieldValue(rowData);
switch (typeof value === "undefined" ? "undefined" : _typeof(value)) {
case "object":
value = JSON.stringify(value);
break;
case "undefined":
case "null":
value = "";
break;
default:
value = value;
}
rowArray.push(value);
});
data.push(rowArray);
});
return data;
};
Clipboard.prototype.buildComplexRows = function (config) {
var _this3 = this;
var output = [],
groups = this.table.modules.groupRows.getGroups();
groups.forEach(function (group) {
output.push(_this3.processGroupData(group));
});
return output;
};
Clipboard.prototype.processGroupData = function (group) {
var _this4 = this;
var subGroups = group.getSubGroups();
var groupData = {
type: "group",
key: group.key
};
if (subGroups.length) {
groupData.subGroups = [];
subGroups.forEach(function (subGroup) {
groupData.subGroups.push(_this4.processGroupData(subGroup));
});
} else {
groupData.rows = group.getRows(true);
}
return groupData;
};
Clipboard.prototype.buildOutput = function (rows, config, params) {
var _this5 = this;
var output = [],
columns = this.table.columnManager.columnsByIndex;
if (config.columnHeaders) {
if (config.columnHeaders == "groups") {
columns = this.generateColumnGroupHeaders(this.table.columnManager.columns);
output = output.concat(this.groupHeadersToRows(columns));
} else {
output.push(this.generateSimpleHeaders(columns));
}
}
//generate styled content
if (this.table.options.clipboardCopyStyled) {
this.generateHTML(rows, columns, config, params);
}
//generate unstyled content
if (config.rowGroups) {
rows.forEach(function (row) {
output = output.concat(_this5.parseRowGroupData(row, config, params));
});
} else {
output = output.concat(this.rowsToData(rows, config, params));
}
return output;
};
Clipboard.prototype.parseRowGroupData = function (group, config, params) {
var _this6 = this;
var groupData = [];
groupData.push([group.key]);
if (group.subGroups) {
group.subGroups.forEach(function (subGroup) {
groupData = groupData.concat(_this6.parseRowGroupData(subGroup, config, params));
});
} else {
groupData = groupData.concat(this.rowsToData(group.rows, config, params));
}
return groupData;
};
Clipboard.prototype.generateHTML = function (rows, columns, config, params) {
var self = this,
data = [],
headers = [],
body,
oddRow,
evenRow,
firstRow,
firstCell,
firstGroup,
lastCell,
styleCells;
//create table element
this.htmlElement = document.createElement("table");
self.mapElementStyles(this.table.element, this.htmlElement, ["border-top", "border-left", "border-right", "border-bottom"]);
function generateSimpleHeaders() {
var headerEl = document.createElement("tr");
columns.forEach(function (column) {
var columnEl = document.createElement("th");
columnEl.innerHTML = column.definition.title;
self.mapElementStyles(column.getElement(), columnEl, ["border-top", "border-left", "border-right", "border-bottom", "background-color", "color", "font-weight", "font-family", "font-size"]);
headerEl.appendChild(columnEl);
});
self.mapElementStyles(self.table.columnManager.getHeadersElement(), headerEl, ["border-top", "border-left", "border-right", "border-bottom", "background-color", "color", "font-weight", "font-family", "font-size"]);
self.htmlElement.appendChild(document.createElement("thead").appendChild(headerEl));
}
function generateHeaders(headers) {
var headerHolderEl = document.createElement("thead");
headers.forEach(function (columns) {
var headerEl = document.createElement("tr");
columns.forEach(function (column) {
var columnEl = document.createElement("th");
if (column.width > 1) {
columnEl.colSpan = column.width;
}
if (column.height > 1) {
columnEl.rowSpan = column.height;
}
columnEl.innerHTML = column.title;
self.mapElementStyles(column.element, columnEl, ["border-top", "border-left", "border-right", "border-bottom", "background-color", "color", "font-weight", "font-family", "font-size"]);
headerEl.appendChild(columnEl);
});
self.mapElementStyles(self.table.columnManager.getHeadersElement(), headerEl, ["border-top", "border-left", "border-right", "border-bottom", "background-color", "color", "font-weight", "font-family", "font-size"]);
headerHolderEl.appendChild(headerEl);
});
self.htmlElement.appendChild(headerHolderEl);
}
function parseColumnGroup(column, level) {
if (typeof headers[level] === "undefined") {
headers[level] = [];
}
headers[level].push({
title: column.title,
width: column.width,
height: 1,
children: !!column.subGroups,
element: column.column.getElement()
});
if (column.subGroups) {
column.subGroups.forEach(function (subGroup) {
parseColumnGroup(subGroup, level + 1);
});
}
}
function padVerticalColumnheaders() {
headers.forEach(function (row, index) {
row.forEach(function (header) {
if (!header.children) {
header.height = headers.length - index;
}
});
});
}
//create headers if needed
if (config.columnHeaders) {
if (config.columnHeaders == "groups") {
columns.forEach(function (column) {
parseColumnGroup(column, 0);
});
padVerticalColumnheaders();
generateHeaders(headers);
} else {
generateSimpleHeaders();
}
}
columns = this.table.columnManager.columnsByIndex;
//create table body
body = document.createElement("tbody");
//lookup row styles
if (window.getComputedStyle) {
oddRow = this.table.element.querySelector(".tabulator-row-odd:not(.tabulator-group):not(.tabulator-calcs)");
evenRow = this.table.element.querySelector(".tabulator-row-even:not(.tabulator-group):not(.tabulator-calcs)");
firstRow = this.table.element.querySelector(".tabulator-row:not(.tabulator-group):not(.tabulator-calcs)");
firstGroup = this.table.element.getElementsByClassName("tabulator-group")[0];
if (firstRow) {
styleCells = firstRow.getElementsByClassName("tabulator-cell");
firstCell = styleCells[0];
lastCell = styleCells[styleCells.length - 1];
}
}
function processRows(rowArray) {
//add rows to table
rowArray.forEach(function (row, i) {
var rowEl = document.createElement("tr"),
rowData = row.getData("clipboard"),
styleRow = firstRow;
columns.forEach(function (column, j) {
var cellEl = document.createElement("td"),
value = column.getFieldValue(rowData);
switch (typeof value === "undefined" ? "undefined" : _typeof(value)) {
case "object":
value = JSON.stringify(value);
break;
case "undefined":
case "null":
value = "";
break;
default:
value = value;
}
cellEl.innerHTML = value;
if (column.definition.align) {
cellEl.style.textAlign = column.definition.align;
}
if (j < columns.length - 1) {
if (firstCell) {
self.mapElementStyles(firstCell, cellEl, ["border-top", "border-left", "border-right", "border-bottom", "color", "font-weight", "font-family", "font-size"]);
}
} else {
if (firstCell) {
self.mapElementStyles(firstCell, cellEl, ["border-top", "border-left", "border-right", "border-bottom", "color", "font-weight", "font-family", "font-size"]);
}
}
rowEl.appendChild(cellEl);
});
if (!(i % 2) && oddRow) {
styleRow = oddRow;
}
if (i % 2 && evenRow) {
styleRow = evenRow;
}
if (styleRow) {
self.mapElementStyles(styleRow, rowEl, ["border-top", "border-left", "border-right", "border-bottom", "color", "font-weight", "font-family", "font-size", "background-color"]);
}
body.appendChild(rowEl);
});
}
function processGroup(group) {
var groupEl = document.createElement("tr"),
groupCellEl = document.createElement("td");
groupCellEl.colSpan = columns.length;
groupCellEl.innerHTML = group.key;
groupEl.appendChild(groupCellEl);
body.appendChild(groupEl);
self.mapElementStyles(firstGroup, groupEl, ["border-top", "border-left", "border-right", "border-bottom", "color", "font-weight", "font-family", "font-size", "background-color"]);
if (group.subGroups) {
group.subGroups.forEach(function (subGroup) {
processGroup(subGroup);
});
} else {
processRows(group.rows);
}
}
if (config.rowGroups) {
rows.forEach(function (group) {
processGroup(group);
});
} else {
processRows(rows);
}
this.htmlElement.appendChild(body);
};
Clipboard.prototype.mapElementStyles = function (from, to, props) {
var lookup = {
"background-color": "backgroundColor",
"color": "fontColor",
"font-weight": "fontWeight",
"font-family": "fontFamily",
"font-size": "fontSize",
"border-top": "borderTop",
"border-left": "borderLeft",
"border-right": "borderRight",
"border-bottom": "borderBottom"
};
if (window.getComputedStyle) {
var fromStyle = window.getComputedStyle(from);
props.forEach(function (prop) {
to.style[lookup[prop]] = fromStyle.getPropertyValue(prop);
});
}
// return window.getComputedStyle ? window.getComputedStyle(element, null).getPropertyValue(property) : element.style[property.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); })];
};
Clipboard.prototype.copySelectors = {
userSelection: function userSelection(config, params) {
return params;
},
selected: function selected(config, params) {
var rows = [];
if (this.table.modExists("selectRow", true)) {
rows = this.table.modules.selectRow.getSelectedRows();
}
if (config.rowGroups) {
console.warn("Clipboard Warning - select coptSelector does not support row groups");
}
return this.buildOutput(rows, config, params);
},
table: function table(config, params) {
if (config.rowGroups) {
console.warn("Clipboard Warning - table coptSelector does not support row groups");
}
return this.buildOutput(this.table.rowManager.getComponents(), config, params);
},
active: function active(config, params) {
var rows;
if (config.rowGroups) {
rows = this.buildComplexRows(config);
} else {
rows = this.table.rowManager.getComponents(true);
}
return this.buildOutput(rows, config, params);
}
};
Clipboard.prototype.copyFormatters = {
raw: function raw(data, params) {
return data;
},
table: function table(data, params) {
var output = [];
data.forEach(function (row) {
row.forEach(function (value) {
if (typeof value == "undefined") {
value = "";
}
value = typeof value == "undefined" || value === null ? "" : value.toString();
if (value.match(/\r|\n/)) {
value = value.split('"').join('""');
value = '"' + value + '"';
}
});
output.push(row.join("\t"));
});
return output.join("\n");
}
};
Clipboard.prototype.pasteParsers = {
table: function table(clipboard) {
var data = [],
success = false,
headerFindSuccess = true,
columns = this.table.columnManager.columns,
columnMap = [],
rows = [];
//get data from clipboard into array of columns and rows.
clipboard = clipboard.split("\n");
clipboard.forEach(function (row) {
data.push(row.split("\t"));
});
if (data.length && !(data.length === 1 && data[0].length < 2)) {
success = true;
//check if headers are present by title
data[0].forEach(function (value) {
var column = columns.find(function (column) {
return value && column.definition.title && value.trim() && column.definition.title.trim() === value.trim();
});
if (column) {
columnMap.push(column);
} else {
headerFindSuccess = false;
}
});
//check if column headers are present by field
if (!headerFindSuccess) {
headerFindSuccess = true;
columnMap = [];
data[0].forEach(function (value) {
var column = columns.find(function (column) {
return value && column.field && value.trim() && column.field.trim() === value.trim();
});
if (column) {
columnMap.push(column);
} else {
headerFindSuccess = false;
}
});
if (!headerFindSuccess) {
columnMap = this.table.columnManager.columnsByIndex;
}
}
//remove header row if found
if (headerFindSuccess) {
data.shift();
}
data.forEach(function (item) {
var row = {};
item.forEach(function (value, i) {
if (columnMap[i]) {
row[columnMap[i].field] = value;
}
});
rows.push(row);
});
return rows;
} else {
return false;
}
}
};
Clipboard.prototype.pasteActions = {
replace: function replace(rows) {
return this.table.setData(rows);
},
update: function update(rows) {
return this.table.updateOrAddData(rows);
},
insert: function insert(rows) {
return this.table.addData(rows);
}
};
Tabulator.prototype.registerModule("clipboard", Clipboard);
File diff suppressed because one or more lines are too long
@@ -0,0 +1,301 @@
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
/* Tabulator v4.1.2 (c) Oliver Folkerd */
var DataTree = function DataTree(table) {
this.table = table;
this.indent = 10;
this.field = "";
this.collapseEl = null;
this.expandEl = null;
this.branchEl = null;
this.startOpen = function () {};
this.displayIndex = 0;
};
DataTree.prototype.initialize = function () {
var dummyEl = null,
options = this.table.options;
this.field = options.dataTreeChildField;
this.indent = options.dataTreeChildIndent;
if (options.dataTreeBranchElement) {
if (options.dataTreeBranchElement === true) {
this.branchEl = document.createElement("div");
this.branchEl.classList.add("tabulator-data-tree-branch");
} else {
if (typeof options.dataTreeBranchElement === "string") {
dummyEl = document.createElement("div");
dummyEl.innerHTML = options.dataTreeBranchElement;
this.branchEl = dummyEl.firstChild;
} else {
this.branchEl = options.dataTreeBranchElement;
}
}
}
if (options.dataTreeCollapseElement) {
if (typeof options.dataTreeCollapseElement === "string") {
dummyEl = document.createElement("div");
dummyEl.innerHTML = options.dataTreeCollapseElement;
this.collapseEl = dummyEl.firstChild;
} else {
this.collapseEl = options.dataTreeCollapseElement;
}
} else {
this.collapseEl = document.createElement("div");
this.collapseEl.classList.add("tabulator-data-tree-control");
this.collapseEl.innerHTML = "<div class='tabulator-data-tree-control-collapse'></div>";
}
if (options.dataTreeExpandElement) {
if (typeof options.dataTreeExpandElement === "string") {
dummyEl = document.createElement("div");
dummyEl.innerHTML = options.dataTreeExpandElement;
this.expandEl = dummyEl.firstChild;
} else {
this.expandEl = options.dataTreeExpandElement;
}
} else {
this.expandEl = document.createElement("div");
this.expandEl.classList.add("tabulator-data-tree-control");
this.expandEl.innerHTML = "<div class='tabulator-data-tree-control-expand'></div>";
}
switch (_typeof(options.dataTreeStartExpanded)) {
case "boolean":
this.startOpen = function (row, index) {
return options.dataTreeStartExpanded;
};
break;
case "function":
this.startOpen = options.dataTreeStartExpanded;
break;
default:
this.startOpen = function (row, index) {
return options.dataTreeStartExpanded[index];
};
break;
}
};
DataTree.prototype.initializeRow = function (row) {
var children = typeof row.getData()[this.field] !== "undefined";
row.modules.dataTree = {
index: 0,
open: children ? this.startOpen(row.getComponent(), 0) : false,
controlEl: false,
branchEl: false,
parent: false,
children: children
};
};
DataTree.prototype.layoutRow = function (row) {
var cell = row.getCells()[0],
el = cell.getElement(),
config = row.modules.dataTree;
el.style.paddingLeft = parseInt(window.getComputedStyle(el, null).getPropertyValue('padding-left')) + config.index * this.indent + "px";
if (config.branchEl) {
config.branchEl.parentNode.removeChild(config.branchEl);
}
this.generateControlElement(row, el);
if (config.index && this.branchEl) {
config.branchEl = this.branchEl.cloneNode(true);
el.insertBefore(config.branchEl, el.firstChild);
el.style.paddingLeft = parseInt(el.style.paddingLeft) + (config.branchEl.offsetWidth + config.branchEl.style.marginRight) * (config.index - 1) + "px";
}
};
DataTree.prototype.generateControlElement = function (row, el) {
var _this = this;
var config = row.modules.dataTree,
el = el || row.getCells()[0].getElement(),
oldControl = config.controlEl;
if (config.children !== false) {
if (config.open) {
config.controlEl = this.collapseEl.cloneNode(true);
config.controlEl.addEventListener("click", function (e) {
e.stopPropagation();
_this.collapseRow(row);
});
} else {
config.controlEl = this.expandEl.cloneNode(true);
config.controlEl.addEventListener("click", function (e) {
e.stopPropagation();
_this.expandRow(row);
});
}
config.controlEl.addEventListener("mousedown", function (e) {
e.stopPropagation();
});
if (oldControl && oldControl.parentNode === el) {
oldControl.parentNode.replaceChild(config.controlEl, oldControl);
} else {
el.insertBefore(config.controlEl, el.firstChild);
}
}
};
DataTree.prototype.setDisplayIndex = function (index) {
this.displayIndex = index;
};
DataTree.prototype.getDisplayIndex = function () {
return this.displayIndex;
};
DataTree.prototype.getRows = function (rows) {
var _this2 = this;
var output = [];
rows.forEach(function (row, i) {
var config = row.modules.dataTree.children,
children;
output.push(row);
if (!config.index && config.children !== false) {
children = _this2.getChildren(row);
children.forEach(function (child) {
output.push(child);
});
}
});
return output;
};
DataTree.prototype.getChildren = function (row) {
var _this3 = this;
var config = row.modules.dataTree,
output = [];
if (config.children !== false && config.open) {
if (!Array.isArray(config.children)) {
config.children = this.generateChildren(row);
}
config.children.forEach(function (child) {
output.push(child);
var subChildren = _this3.getChildren(child);
subChildren.forEach(function (sub) {
output.push(sub);
});
});
}
return output;
};
DataTree.prototype.generateChildren = function (row) {
var _this4 = this;
var children = [];
row.getData()[this.field].forEach(function (childData) {
var childRow = new Row(childData || {}, _this4.table.rowManager);
childRow.modules.dataTree.index = row.modules.dataTree.index + 1;
childRow.modules.dataTree.parent = row;
childRow.modules.dataTree.open = _this4.startOpen(row, childRow.modules.dataTree.index);
children.push(childRow);
});
return children;
};
DataTree.prototype.expandRow = function (row, silent) {
var config = row.modules.dataTree;
if (config.children !== false) {
config.open = true;
row.reinitialize();
this.table.rowManager.refreshActiveData("tree", false, true);
this.table.options.dataTreeRowExpanded(row.getComponent(), row.modules.dataTree.index);
}
};
DataTree.prototype.collapseRow = function (row) {
var config = row.modules.dataTree;
if (config.children !== false) {
config.open = false;
row.reinitialize();
this.table.rowManager.refreshActiveData("tree", false, true);
this.table.options.dataTreeRowCollapsed(row.getComponent(), row.modules.dataTree.index);
}
};
DataTree.prototype.toggleRow = function (row) {
var config = row.modules.dataTree;
if (config.children !== false) {
if (config.open) {
this.collapseRow(row);
} else {
this.expandRow(row);
}
}
};
DataTree.prototype.getTreeParent = function (row) {
return row.modules.dataTree.parent ? row.modules.dataTree.parent.getComponent() : false;
};
DataTree.prototype.getTreeChildren = function (row) {
var config = row.modules.dataTree,
output = [];
if (config.children) {
if (!Array.isArray(config.children)) {
config.children = this.generateChildren(row);
}
config.children.forEach(function (childRow) {
if (childRow instanceof Row) {
output.push(childRow.getComponent());
}
});
}
return output;
};
DataTree.prototype.checkForRestyle = function (cell) {
if (!cell.row.cells.indexOf(cell)) {
if (cell.row.modules.dataTree.children !== false) {
cell.row.reinitialize();
}
}
};
Tabulator.prototype.registerModule("dataTree", DataTree);
File diff suppressed because one or more lines are too long
@@ -0,0 +1,736 @@
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
/* Tabulator v4.1.2 (c) Oliver Folkerd */
var Download = function Download(table) {
this.table = table; //hold Tabulator object
this.fields = {}; //hold filed multi dimension arrays
this.columnsByIndex = []; //hold columns in their order in the table
this.columnsByField = {}; //hold columns with lookup by field name
this.config = {};
};
//trigger file download
Download.prototype.download = function (type, filename, options, interceptCallback) {
var self = this,
downloadFunc = false;
this.processConfig();
function buildLink(data, mime) {
if (interceptCallback) {
interceptCallback(data);
} else {
self.triggerDownload(data, mime, type, filename);
}
}
if (typeof type == "function") {
downloadFunc = type;
} else {
if (self.downloaders[type]) {
downloadFunc = self.downloaders[type];
} else {
console.warn("Download Error - No such download type found: ", type);
}
}
this.processColumns();
if (downloadFunc) {
downloadFunc.call(this, self.processDefinitions(), self.processData(), options || {}, buildLink, this.config);
}
};
Download.prototype.processConfig = function () {
var config = { //download config
columnGroups: true,
rowGroups: true
};
if (this.table.options.downloadConfig) {
for (var key in this.table.options.downloadConfig) {
config[key] = this.table.options.downloadConfig[key];
}
}
if (config.rowGroups && this.table.options.groupBy && this.table.modExists("groupRows")) {
this.config.rowGroups = true;
}
if (config.columnGroups && this.table.columnManager.columns.length != this.table.columnManager.columnsByIndex.length) {
this.config.columnGroups = true;
}
};
Download.prototype.processColumns = function () {
var self = this;
self.columnsByIndex = [];
self.columnsByField = {};
self.table.columnManager.columnsByIndex.forEach(function (column) {
if (column.field && column.visible && column.definition.download !== false) {
self.columnsByIndex.push(column);
self.columnsByField[column.field] = column;
}
});
};
Download.prototype.processDefinitions = function () {
var self = this,
processedDefinitions = [];
if (this.config.columnGroups) {
self.table.columnManager.columns.forEach(function (column) {
var colData = self.processColumnGroup(column);
if (colData) {
processedDefinitions.push(colData);
}
});
} else {
self.columnsByIndex.forEach(function (column) {
if (column.download !== false) {
//isolate definiton from defintion object
processedDefinitions.push(self.processDefinition(column));
}
});
}
return processedDefinitions;
};
Download.prototype.processColumnGroup = function (column) {
var _this = this;
var subGroups = column.columns;
var groupData = {
type: "group",
title: column.definition.title
};
if (subGroups.length) {
groupData.subGroups = [];
groupData.width = 0;
subGroups.forEach(function (subGroup) {
var subGroupData = _this.processColumnGroup(subGroup);
if (subGroupData) {
groupData.width += subGroupData.width;
groupData.subGroups.push(subGroupData);
}
});
if (!groupData.width) {
return false;
}
} else {
if (column.field && column.visible && column.definition.download !== false) {
groupData.width = 1;
groupData.definition = this.processDefinition(column);
} else {
return false;
}
}
return groupData;
};
Download.prototype.processDefinition = function (column) {
var def = {};
for (var key in column.definition) {
def[key] = column.definition[key];
}
if (typeof column.definition.downloadTitle != "undefined") {
def.title = column.definition.downloadTitle;
}
return def;
};
Download.prototype.processData = function () {
var _this2 = this;
var self = this,
data = [],
groups = [];
if (this.config.rowGroups) {
groups = this.table.modules.groupRows.getGroups();
groups.forEach(function (group) {
data.push(_this2.processGroupData(group));
});
} else {
data = self.table.rowManager.getData(true, "download");
}
//bulk data processing
if (typeof self.table.options.downloadDataFormatter == "function") {
data = self.table.options.downloadDataFormatter(data);
}
return data;
};
Download.prototype.processGroupData = function (group) {
var _this3 = this;
var subGroups = group.getSubGroups();
var groupData = {
type: "group",
key: group.key
};
if (subGroups.length) {
groupData.subGroups = [];
subGroups.forEach(function (subGroup) {
groupData.subGroups.push(_this3.processGroupData(subGroup));
});
} else {
groupData.rows = group.getData(true, "download");
}
return groupData;
};
Download.prototype.triggerDownload = function (data, mime, type, filename) {
var element = document.createElement('a'),
blob = new Blob([data], { type: mime }),
filename = filename || "Tabulator." + (typeof type === "function" ? "txt" : type);
blob = this.table.options.downloadReady.call(this.table, data, blob);
if (blob) {
if (navigator.msSaveOrOpenBlob) {
navigator.msSaveOrOpenBlob(blob, filename);
} else {
element.setAttribute('href', window.URL.createObjectURL(blob));
//set file title
element.setAttribute('download', filename);
//trigger download
element.style.display = 'none';
document.body.appendChild(element);
element.click();
//remove temporary link element
document.body.removeChild(element);
}
if (this.table.options.downloadComplete) {
this.table.options.downloadComplete();
}
}
};
//nested field lookup
Download.prototype.getFieldValue = function (field, data) {
var column = this.columnsByField[field];
if (column) {
return column.getFieldValue(data);
}
return false;
};
Download.prototype.commsReceived = function (table, action, data) {
switch (action) {
case "intercept":
this.download(data.type, "", data.options, data.intercept);
break;
}
};
//downloaders
Download.prototype.downloaders = {
csv: function csv(columns, data, options, setFileContents, config) {
var self = this,
titles = [],
fields = [],
delimiter = options && options.delimiter ? options.delimiter : ",",
fileContents;
//build column headers
function parseSimpleTitles() {
columns.forEach(function (column) {
titles.push('"' + String(column.title).split('"').join('""') + '"');
fields.push(column.field);
});
}
function parseColumnGroup(column, level) {
if (column.subGroups) {
column.subGroups.forEach(function (subGroup) {
parseColumnGroup(subGroup, level + 1);
});
} else {
titles.push('"' + String(column.title).split('"').join('""') + '"');
fields.push(column.definition.field);
}
}
if (config.columnGroups) {
console.warn("Download Warning - CSV downloader cannot process column groups");
columns.forEach(function (column) {
parseColumnGroup(column, 0);
});
} else {
parseSimpleTitles();
}
//generate header row
fileContents = [titles.join(delimiter)];
function parseRows(data) {
//generate each row of the table
data.forEach(function (row) {
var rowData = [];
fields.forEach(function (field) {
var value = self.getFieldValue(field, row);
switch (typeof value === "undefined" ? "undefined" : _typeof(value)) {
case "object":
value = JSON.stringify(value);
break;
case "undefined":
case "null":
value = "";
break;
default:
value = value;
}
//escape quotation marks
rowData.push('"' + String(value).split('"').join('""') + '"');
});
fileContents.push(rowData.join(delimiter));
});
}
function parseGroup(group) {
if (group.subGroups) {
group.subGroups.forEach(function (subGroup) {
parseGroup(subGroup);
});
} else {
parseRows(group.rows);
}
}
if (config.rowGroups) {
console.warn("Download Warning - CSV downloader cannot process row groups");
data.forEach(function (group) {
parseGroup(group);
});
} else {
parseRows(data);
}
setFileContents(fileContents.join("\n"), "text/csv");
},
json: function json(columns, data, options, setFileContents, config) {
var fileContents = JSON.stringify(data, null, '\t');
setFileContents(fileContents, "application/json");
},
pdf: function pdf(columns, data, options, setFileContents, config) {
var self = this,
fields = [],
header = [],
body = [],
table = "",
groupRowIndexs = [],
autoTableParams = {},
rowGroupStyles = {},
jsPDFParams = options.jsPDF || {},
title = options && options.title ? options.title : "";
if (!jsPDFParams.orientation) {
jsPDFParams.orientation = options.orientation || "landscape";
}
if (!jsPDFParams.unit) {
jsPDFParams.unit = "pt";
}
//build column headers
function parseSimpleTitles() {
columns.forEach(function (column) {
if (column.field) {
header.push(column.title || "");
fields.push(column.field);
}
});
}
function parseColumnGroup(column, level) {
if (column.subGroups) {
column.subGroups.forEach(function (subGroup) {
parseColumnGroup(subGroup, level + 1);
});
} else {
header.push(column.title || "");
fields.push(column.definition.field);
}
}
if (config.columnGroups) {
console.warn("Download Warning - PDF downloader cannot process column groups");
columns.forEach(function (column) {
parseColumnGroup(column, 0);
});
} else {
parseSimpleTitles();
}
function parseValue(value) {
switch (typeof value === "undefined" ? "undefined" : _typeof(value)) {
case "object":
value = JSON.stringify(value);
break;
case "undefined":
case "null":
value = "";
break;
default:
value = value;
}
return value;
}
function parseRows(data) {
//build table rows
data.forEach(function (row) {
var rowData = [];
fields.forEach(function (field) {
var value = self.getFieldValue(field, row);
rowData.push(parseValue(value));
});
body.push(rowData);
});
}
function parseGroup(group) {
var groupData = [];
groupData.push(parseValue(group.key));
groupRowIndexs.push(body.length);
body.push(groupData);
if (group.subGroups) {
group.subGroups.forEach(function (subGroup) {
parseGroup(subGroup);
});
} else {
parseRows(group.rows);
}
}
if (config.rowGroups) {
data.forEach(function (group) {
parseGroup(group);
});
} else {
parseRows(data);
}
var doc = new jsPDF(jsPDFParams); //set document to landscape, better for most tables
if (options && options.autoTable) {
if (typeof options.autoTable === "function") {
autoTableParams = options.autoTable(doc) || {};
} else {
autoTableParams = options.autoTable;
}
}
if (config.rowGroups) {
var createdCell = function createdCell(cell, data) {
if (groupRowIndexs.indexOf(data.row.index) > -1) {
for (var key in rowGroupStyles) {
cell.styles[key] = rowGroupStyles[key];
}
}
};
rowGroupStyles = options.rowGroupStyles || {
fontStyle: "bold",
fontSize: 12,
cellPadding: 6,
fillColor: 220
};
if (!autoTableParams.createdCell) {
autoTableParams.createdCell = createdCell;
} else {
var createdCellHolder = autoTableParams.createdCell;
autoTableParams.createdCell = function (cell, data) {
createdCell(cell, data);
createdCellHolder(cell, data);
};
}
}
if (title) {
autoTableParams.addPageContent = function (data) {
doc.text(title, 40, 30);
};
}
doc.autoTable(header, body, autoTableParams);
setFileContents(doc.output("arraybuffer"), "application/pdf");
},
xlsx: function xlsx(columns, data, options, setFileContents, config) {
var self = this,
sheetName = options.sheetName || "Sheet1",
workbook = { SheetNames: [], Sheets: {} },
groupRowIndexs = [],
groupColumnIndexs = [],
output;
function generateSheet() {
var titles = [],
fields = [],
rows = [],
worksheet;
//convert rows to worksheet
function rowsToSheet() {
var sheet = {};
var range = { s: { c: 0, r: 0 }, e: { c: fields.length, r: rows.length } };
XLSX.utils.sheet_add_aoa(sheet, rows);
sheet['!ref'] = XLSX.utils.encode_range(range);
var merges = generateMerges();
if (merges.length) {
sheet["!merges"] = merges;
}
return sheet;
}
function parseSimpleTitles() {
//get field lists
columns.forEach(function (column) {
titles.push(column.title);
fields.push(column.field);
});
rows.push(titles);
}
function parseColumnGroup(column, level) {
if (typeof titles[level] === "undefined") {
titles[level] = [];
}
if (typeof groupColumnIndexs[level] === "undefined") {
groupColumnIndexs[level] = [];
}
if (column.width > 1) {
groupColumnIndexs[level].push({
type: "hoz",
start: titles[level].length,
end: titles[level].length + column.width - 1
});
}
titles[level].push(column.title);
if (column.subGroups) {
column.subGroups.forEach(function (subGroup) {
parseColumnGroup(subGroup, level + 1);
});
} else {
fields.push(column.definition.field);
padColumnTitles(fields.length - 1, level);
groupColumnIndexs[level].push({
type: "vert",
start: fields.length - 1
});
}
}
function padColumnTitles() {
var max = 0;
titles.forEach(function (title) {
var len = title.length;
if (len > max) {
max = len;
}
});
titles.forEach(function (title) {
var len = title.length;
if (len < max) {
for (var i = len; i < max; i++) {
title.push("");
}
}
});
}
if (config.columnGroups) {
columns.forEach(function (column) {
parseColumnGroup(column, 0);
});
titles.forEach(function (title) {
rows.push(title);
});
} else {
parseSimpleTitles();
}
function generateMerges() {
var output = [];
groupRowIndexs.forEach(function (index) {
output.push({ s: { r: index, c: 0 }, e: { r: index, c: fields.length - 1 } });
});
groupColumnIndexs.forEach(function (merges, level) {
merges.forEach(function (merge) {
if (merge.type === "hoz") {
output.push({ s: { r: level, c: merge.start }, e: { r: level, c: merge.end } });
} else {
if (level != titles.length - 1) {
output.push({ s: { r: level, c: merge.start }, e: { r: titles.length - 1, c: merge.start } });
}
}
});
});
return output;
}
//generate each row of the table
function parseRows(data) {
data.forEach(function (row) {
var rowData = [];
fields.forEach(function (field) {
var value = self.getFieldValue(field, row);
rowData.push((typeof value === "undefined" ? "undefined" : _typeof(value)) === "object" ? JSON.stringify(value) : value);
});
rows.push(rowData);
});
}
function parseGroup(group) {
var groupData = [];
groupData.push(group.key);
groupRowIndexs.push(rows.length);
rows.push(groupData);
if (group.subGroups) {
group.subGroups.forEach(function (subGroup) {
parseGroup(subGroup);
});
} else {
parseRows(group.rows);
}
}
if (config.rowGroups) {
data.forEach(function (group) {
parseGroup(group);
});
} else {
parseRows(data);
}
worksheet = rowsToSheet();
return worksheet;
}
if (options.sheetOnly) {
setFileContents(generateSheet());
return;
}
if (options.sheets) {
for (var sheet in options.sheets) {
if (options.sheets[sheet] === true) {
workbook.SheetNames.push(sheet);
workbook.Sheets[sheet] = generateSheet();
} else {
workbook.SheetNames.push(sheet);
this.table.modules.comms.send(options.sheets[sheet], "download", "intercept", {
type: "xlsx",
options: { sheetOnly: true },
intercept: function intercept(data) {
workbook.Sheets[sheet] = data;
}
});
}
}
} else {
workbook.SheetNames.push(sheetName);
workbook.Sheets[sheetName] = generateSheet();
}
//convert workbook to binary array
function s2ab(s) {
var buf = new ArrayBuffer(s.length);
var view = new Uint8Array(buf);
for (var i = 0; i != s.length; ++i) {
view[i] = s.charCodeAt(i) & 0xFF;
}return buf;
}
output = XLSX.write(workbook, { bookType: 'xlsx', bookSST: true, type: 'binary' });
setFileContents(s2ab(output), "application/octet-stream");
}
};
Tabulator.prototype.registerModule("download", Download);
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1,695 @@
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
/* Tabulator v4.1.2 (c) Oliver Folkerd */
var Filter = function Filter(table) {
this.table = table; //hold Tabulator object
this.filterList = []; //hold filter list
this.headerFilters = {}; //hold column filters
this.headerFilterElements = []; //hold header filter elements for manipulation
this.headerFilterColumns = []; //hold columns that use header filters
this.changed = false; //has filtering changed since last render
};
//initialize column header filter
Filter.prototype.initializeColumn = function (column, value) {
var self = this,
field = column.getField(),
prevSuccess,
params;
//handle successfull value change
function success(value) {
var filterType = column.modules.filter.tagType == "input" && column.modules.filter.attrType == "text" || column.modules.filter.tagType == "textarea" ? "partial" : "match",
type = "",
filterFunc;
if (typeof prevSuccess === "undefined" || prevSuccess !== value) {
prevSuccess = value;
if (!column.modules.filter.emptyFunc(value)) {
column.modules.filter.value = value;
switch (_typeof(column.definition.headerFilterFunc)) {
case "string":
if (self.filters[column.definition.headerFilterFunc]) {
type = column.definition.headerFilterFunc;
filterFunc = function filterFunc(data) {
return self.filters[column.definition.headerFilterFunc](value, column.getFieldValue(data));
};
} else {
console.warn("Header Filter Error - Matching filter function not found: ", column.definition.headerFilterFunc);
}
break;
case "function":
filterFunc = function filterFunc(data) {
var params = column.definition.headerFilterFuncParams || {};
var fieldVal = column.getFieldValue(data);
params = typeof params === "function" ? params(value, fieldVal, data) : params;
return column.definition.headerFilterFunc(value, fieldVal, data, params);
};
type = filterFunc;
break;
}
if (!filterFunc) {
switch (filterType) {
case "partial":
filterFunc = function filterFunc(data) {
return String(column.getFieldValue(data)).toLowerCase().indexOf(String(value).toLowerCase()) > -1;
};
type = "like";
break;
default:
filterFunc = function filterFunc(data) {
return column.getFieldValue(data) == value;
};
type = "=";
}
}
self.headerFilters[field] = { value: value, func: filterFunc, type: type };
} else {
delete self.headerFilters[field];
}
self.changed = true;
self.table.rowManager.filterRefresh();
}
}
column.modules.filter = {
success: success,
attrType: false,
tagType: false,
emptyFunc: false
};
this.generateHeaderFilterElement(column);
};
Filter.prototype.generateHeaderFilterElement = function (column, initialValue) {
var self = this,
success = column.modules.filter.success,
field = column.getField(),
filterElement,
editor,
editorElement,
cellWrapper,
typingTimer,
searchTrigger,
params;
//handle aborted edit
function cancel() {}
if (column.modules.filter.headerElement && column.modules.filter.headerElement.parentNode) {
column.modules.filter.headerElement.parentNode.removeChild(column.modules.filter.headerElement);
}
if (field) {
//set empty value function
column.modules.filter.emptyFunc = column.definition.headerFilterEmptyCheck || function (value) {
return !value && value !== "0";
};
filterElement = document.createElement("div");
filterElement.classList.add("tabulator-header-filter");
//set column editor
switch (_typeof(column.definition.headerFilter)) {
case "string":
if (self.table.modules.edit.editors[column.definition.headerFilter]) {
editor = self.table.modules.edit.editors[column.definition.headerFilter];
if ((column.definition.headerFilter === "tick" || column.definition.headerFilter === "tickCross") && !column.definition.headerFilterEmptyCheck) {
column.modules.filter.emptyFunc = function (value) {
return value !== true && value !== false;
};
}
} else {
console.warn("Filter Error - Cannot build header filter, No such editor found: ", column.definition.editor);
}
break;
case "function":
editor = column.definition.headerFilter;
break;
case "boolean":
if (column.modules.edit && column.modules.edit.editor) {
editor = column.modules.edit.editor;
} else {
if (column.definition.formatter && self.table.modules.edit.editors[column.definition.formatter]) {
editor = self.table.modules.edit.editors[column.definition.formatter];
if ((column.definition.formatter === "tick" || column.definition.formatter === "tickCross") && !column.definition.headerFilterEmptyCheck) {
column.modules.filter.emptyFunc = function (value) {
return value !== true && value !== false;
};
}
} else {
editor = self.table.modules.edit.editors["input"];
}
}
break;
}
if (editor) {
cellWrapper = {
getValue: function getValue() {
return typeof initialValue !== "undefined" ? initialValue : "";
},
getField: function getField() {
return column.definition.field;
},
getElement: function getElement() {
return filterElement;
},
getColumn: function getColumn() {
return column.getComponent();
},
getRow: function getRow() {
return {
normalizeHeight: function normalizeHeight() {}
};
}
};
params = column.definition.headerFilterParams || {};
params = typeof params === "function" ? params.call(self.table) : params;
editorElement = editor.call(this.table.modules.edit, cellWrapper, function () {}, success, cancel, params);
if (!editorElement) {
console.warn("Filter Error - Cannot add filter to " + field + " column, editor returned a value of false");
return;
}
if (!(editorElement instanceof Node)) {
console.warn("Filter Error - Cannot add filter to " + field + " column, editor should return an instance of Node, the editor returned:", editorElement);
return;
}
//set Placeholder Text
if (field) {
self.table.modules.localize.bind("headerFilters|columns|" + column.definition.field, function (value) {
editorElement.setAttribute("placeholder", typeof value !== "undefined" && value ? value : self.table.modules.localize.getText("headerFilters|default"));
});
} else {
self.table.modules.localize.bind("headerFilters|default", function (value) {
editorElement.setAttribute("placeholder", typeof self.column.definition.headerFilterPlaceholder !== "undefined" && self.column.definition.headerFilterPlaceholder ? self.column.definition.headerFilterPlaceholder : value);
});
}
//focus on element on click
editorElement.addEventListener("click", function (e) {
e.stopPropagation();
editorElement.focus();
});
//live update filters as user types
typingTimer = false;
searchTrigger = function searchTrigger(e) {
if (typingTimer) {
clearTimeout(typingTimer);
}
typingTimer = setTimeout(function () {
success(editorElement.value);
}, 300);
};
column.modules.filter.headerElement = editorElement;
column.modules.filter.attrType = editorElement.hasAttribute("type") ? editorElement.getAttribute("type").toLowerCase() : "";
column.modules.filter.tagType = editorElement.tagName.toLowerCase();
if (column.definition.headerFilterLiveFilter !== false) {
if (!(column.definition.headerFilter === "autocomplete" || column.definition.editor === "autocomplete" && column.definition.headerFilter === true)) {
editorElement.addEventListener("keyup", searchTrigger);
editorElement.addEventListener("search", searchTrigger);
//update number filtered columns on change
if (column.modules.filter.attrType == "number") {
editorElement.addEventListener("change", function (e) {
success(editorElement.value);
});
}
//change text inputs to search inputs to allow for clearing of field
if (column.modules.filter.attrType == "text" && this.table.browser !== "ie") {
editorElement.setAttribute("type", "search");
// editorElement.off("change blur"); //prevent blur from triggering filter and preventing selection click
}
}
//prevent input and select elements from propegating click to column sorters etc
if (column.modules.filter.tagType == "input" || column.modules.filter.tagType == "select" || column.modules.filter.tagType == "textarea") {
editorElement.addEventListener("mousedown", function (e) {
e.stopPropagation();
});
}
}
filterElement.appendChild(editorElement);
column.contentElement.appendChild(filterElement);
self.headerFilterElements.push(editorElement);
self.headerFilterColumns.push(column);
}
} else {
console.warn("Filter Error - Cannot add header filter, column has no field set:", column.definition.title);
}
};
//hide all header filter elements (used to ensure correct column widths in "fitData" layout mode)
Filter.prototype.hideHeaderFilterElements = function () {
this.headerFilterElements.forEach(function (element) {
element.style.display = 'none';
});
};
//show all header filter elements (used to ensure correct column widths in "fitData" layout mode)
Filter.prototype.showHeaderFilterElements = function () {
this.headerFilterElements.forEach(function (element) {
element.style.display = '';
});
};
//programatically set value of header filter
Filter.prototype.setHeaderFilterFocus = function (column) {
if (column.modules.filter && column.modules.filter.headerElement) {
column.modules.filter.headerElement.focus();
} else {
console.warn("Column Filter Focus Error - No header filter set on column:", column.getField());
}
};
//programatically set value of header filter
Filter.prototype.setHeaderFilterValue = function (column, value) {
if (column) {
if (column.modules.filter && column.modules.filter.headerElement) {
this.generateHeaderFilterElement(column, value);
column.modules.filter.success(value);
} else {
console.warn("Column Filter Error - No header filter set on column:", column.getField());
}
}
};
Filter.prototype.reloadHeaderFilter = function (column) {
if (column) {
if (column.modules.filter && column.modules.filter.headerElement) {
this.generateHeaderFilterElement(column, column.modules.filter.value);
} else {
console.warn("Column Filter Error - No header filter set on column:", column.getField());
}
}
};
//check if the filters has changed since last use
Filter.prototype.hasChanged = function () {
var changed = this.changed;
this.changed = false;
return changed;
};
//set standard filters
Filter.prototype.setFilter = function (field, type, value) {
var self = this;
self.filterList = [];
if (!Array.isArray(field)) {
field = [{ field: field, type: type, value: value }];
}
self.addFilter(field);
};
//add filter to array
Filter.prototype.addFilter = function (field, type, value) {
var self = this;
if (!Array.isArray(field)) {
field = [{ field: field, type: type, value: value }];
}
field.forEach(function (filter) {
filter = self.findFilter(filter);
if (filter) {
self.filterList.push(filter);
self.changed = true;
}
});
if (this.table.options.persistentFilter && this.table.modExists("persistence", true)) {
this.table.modules.persistence.save("filter");
}
};
Filter.prototype.findFilter = function (filter) {
var self = this,
column;
if (Array.isArray(filter)) {
return this.findSubFilters(filter);
}
var filterFunc = false;
if (typeof filter.field == "function") {
filterFunc = function filterFunc(data) {
return filter.field(data, filter.type || {}); // pass params to custom filter function
};
} else {
if (self.filters[filter.type]) {
column = self.table.columnManager.getColumnByField(filter.field);
if (column) {
filterFunc = function filterFunc(data) {
return self.filters[filter.type](filter.value, column.getFieldValue(data));
};
} else {
filterFunc = function filterFunc(data) {
return self.filters[filter.type](filter.value, data[filter.field]);
};
}
} else {
console.warn("Filter Error - No such filter type found, ignoring: ", filter.type);
}
}
filter.func = filterFunc;
return filter.func ? filter : false;
};
Filter.prototype.findSubFilters = function (filters) {
var self = this,
output = [];
filters.forEach(function (filter) {
filter = self.findFilter(filter);
if (filter) {
output.push(filter);
}
});
return output.length ? output : false;
};
//get all filters
Filter.prototype.getFilters = function (all, ajax) {
var self = this,
output = [];
if (all) {
output = self.getHeaderFilters();
}
self.filterList.forEach(function (filter) {
output.push({ field: filter.field, type: filter.type, value: filter.value });
});
if (ajax) {
output.forEach(function (item) {
if (typeof item.type == "function") {
item.type = "function";
}
});
}
return output;
};
//get all filters
Filter.prototype.getHeaderFilters = function () {
var self = this,
output = [];
for (var key in this.headerFilters) {
output.push({ field: key, type: this.headerFilters[key].type, value: this.headerFilters[key].value });
}
return output;
};
//remove filter from array
Filter.prototype.removeFilter = function (field, type, value) {
var self = this;
if (!Array.isArray(field)) {
field = [{ field: field, type: type, value: value }];
}
field.forEach(function (filter) {
var index = -1;
if (_typeof(filter.field) == "object") {
index = self.filterList.findIndex(function (element) {
return filter === element;
});
} else {
index = self.filterList.findIndex(function (element) {
return filter.field === element.field && filter.type === element.type && filter.value === element.value;
});
}
if (index > -1) {
self.filterList.splice(index, 1);
self.changed = true;
} else {
console.warn("Filter Error - No matching filter type found, ignoring: ", filter.type);
}
});
if (this.table.options.persistentFilter && this.table.modExists("persistence", true)) {
this.table.modules.persistence.save("filter");
}
};
//clear filters
Filter.prototype.clearFilter = function (all) {
this.filterList = [];
if (all) {
this.clearHeaderFilter();
}
this.changed = true;
if (this.table.options.persistentFilter && this.table.modExists("persistence", true)) {
this.table.modules.persistence.save("filter");
}
};
//clear header filters
Filter.prototype.clearHeaderFilter = function () {
var self = this;
this.headerFilters = {};
this.headerFilterColumns.forEach(function (column) {
column.modules.filter.value = null;
self.reloadHeaderFilter(column);
});
this.changed = true;
};
//search data and return matching rows
Filter.prototype.search = function (searchType, field, type, value) {
var self = this,
activeRows = [],
filterList = [];
if (!Array.isArray(field)) {
field = [{ field: field, type: type, value: value }];
}
field.forEach(function (filter) {
filter = self.findFilter(filter);
if (filter) {
filterList.push(filter);
}
});
this.table.rowManager.rows.forEach(function (row) {
var match = true;
filterList.forEach(function (filter) {
if (!self.filterRecurse(filter, row.getData())) {
match = false;
}
});
if (match) {
activeRows.push(searchType === "data" ? row.getData("data") : row.getComponent());
}
});
return activeRows;
};
//filter row array
Filter.prototype.filter = function (rowList, filters) {
var self = this,
activeRows = [],
activeRowComponents = [];
if (self.table.options.dataFiltering) {
self.table.options.dataFiltering.call(self.table, self.getFilters());
}
if (!self.table.options.ajaxFiltering && (self.filterList.length || Object.keys(self.headerFilters).length)) {
rowList.forEach(function (row) {
if (self.filterRow(row)) {
activeRows.push(row);
}
});
} else {
activeRows = rowList.slice(0);
}
if (self.table.options.dataFiltered) {
activeRows.forEach(function (row) {
activeRowComponents.push(row.getComponent());
});
self.table.options.dataFiltered.call(self.table, self.getFilters(), activeRowComponents);
}
return activeRows;
};
//filter individual row
Filter.prototype.filterRow = function (row, filters) {
var self = this,
match = true,
data = row.getData();
self.filterList.forEach(function (filter) {
if (!self.filterRecurse(filter, data)) {
match = false;
}
});
for (var field in self.headerFilters) {
if (!self.headerFilters[field].func(data)) {
match = false;
}
}
return match;
};
Filter.prototype.filterRecurse = function (filter, data) {
var self = this,
match = false;
if (Array.isArray(filter)) {
filter.forEach(function (subFilter) {
if (self.filterRecurse(subFilter, data)) {
match = true;
}
});
} else {
match = filter.func(data);
}
return match;
};
//list of available filters
Filter.prototype.filters = {
//equal to
"=": function _(filterVal, rowVal) {
return rowVal == filterVal ? true : false;
},
//less than
"<": function _(filterVal, rowVal) {
return rowVal < filterVal ? true : false;
},
//less than or equal to
"<=": function _(filterVal, rowVal) {
return rowVal <= filterVal ? true : false;
},
//greater than
">": function _(filterVal, rowVal) {
return rowVal > filterVal ? true : false;
},
//greater than or equal to
">=": function _(filterVal, rowVal) {
return rowVal >= filterVal ? true : false;
},
//not equal to
"!=": function _(filterVal, rowVal) {
return rowVal != filterVal ? true : false;
},
"regex": function regex(filterVal, rowVal) {
if (typeof filterVal == "string") {
filterVal = new RegExp(filterVal);
}
return filterVal.test(rowVal);
},
//contains the string
"like": function like(filterVal, rowVal) {
if (filterVal === null || typeof filterVal === "undefined") {
return rowVal === filterVal ? true : false;
} else {
if (typeof rowVal !== 'undefined' && rowVal !== null) {
return String(rowVal).toLowerCase().indexOf(filterVal.toLowerCase()) > -1 ? true : false;
} else {
return false;
}
}
},
//in array
"in": function _in(filterVal, rowVal) {
if (Array.isArray(filterVal)) {
return filterVal.indexOf(rowVal) > -1;
} else {
console.warn("Filter Error - filter value is not an array:", filterVal);
return false;
}
}
};
Tabulator.prototype.registerModule("filter", Filter);
File diff suppressed because one or more lines are too long
@@ -0,0 +1,539 @@
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
/* Tabulator v4.1.2 (c) Oliver Folkerd */
var Format = function Format(table) {
this.table = table; //hold Tabulator object
};
//initialize column formatter
Format.prototype.initializeColumn = function (column) {
var self = this,
config = { params: column.definition.formatterParams || {} };
//set column formatter
switch (_typeof(column.definition.formatter)) {
case "string":
if (column.definition.formatter === "tick") {
column.definition.formatter = "tickCross";
if (typeof config.params.crossElement == "undefined") {
config.params.crossElement = false;
}
console.warn("DEPRECATION WANRING - the tick formatter has been depricated, please use the tickCross formatter with the crossElement param set to false");
}
if (self.formatters[column.definition.formatter]) {
config.formatter = self.formatters[column.definition.formatter];
} else {
console.warn("Formatter Error - No such formatter found: ", column.definition.formatter);
config.formatter = self.formatters.plaintext;
}
break;
case "function":
config.formatter = column.definition.formatter;
break;
default:
config.formatter = self.formatters.plaintext;
break;
}
column.modules.format = config;
};
Format.prototype.cellRendered = function (cell) {
if (cell.column.modules.format.renderedCallback) {
cell.column.modules.format.renderedCallback();
}
};
//return a formatted value for a cell
Format.prototype.formatValue = function (cell) {
var component = cell.getComponent(),
params = typeof cell.column.modules.format.params === "function" ? cell.column.modules.format.params(component) : cell.column.modules.format.params;
function onRendered(callback) {
cell.column.modules.format.renderedCallback = callback;
}
return cell.column.modules.format.formatter.call(this, component, params, onRendered);
};
Format.prototype.sanitizeHTML = function (value) {
if (value) {
var entityMap = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#39;',
'/': '&#x2F;',
'`': '&#x60;',
'=': '&#x3D;'
};
return String(value).replace(/[&<>"'`=\/]/g, function (s) {
return entityMap[s];
});
} else {
return value;
}
};
Format.prototype.emptyToSpace = function (value) {
return value === null || typeof value === "undefined" ? "&nbsp" : value;
};
//get formatter for cell
Format.prototype.getFormatter = function (formatter) {
var formatter;
switch (typeof formatter === "undefined" ? "undefined" : _typeof(formatter)) {
case "string":
if (this.formatters[formatter]) {
formatter = this.formatters[formatter];
} else {
console.warn("Formatter Error - No such formatter found: ", formatter);
formatter = this.formatters.plaintext;
}
break;
case "function":
formatter = formatter;
break;
default:
formatter = this.formatters.plaintext;
break;
}
return formatter;
};
//default data formatters
Format.prototype.formatters = {
//plain text value
plaintext: function plaintext(cell, formatterParams, onRendered) {
return this.emptyToSpace(this.sanitizeHTML(cell.getValue()));
},
//html text value
html: function html(cell, formatterParams, onRendered) {
return cell.getValue();
},
//multiline text area
textarea: function textarea(cell, formatterParams, onRendered) {
cell.getElement().style.whiteSpace = "pre-wrap";
return this.emptyToSpace(this.sanitizeHTML(cell.getValue()));
},
//currency formatting
money: function money(cell, formatterParams, onRendered) {
var floatVal = parseFloat(cell.getValue()),
number,
integer,
decimal,
rgx;
var decimalSym = formatterParams.decimal || ".";
var thousandSym = formatterParams.thousand || ",";
var symbol = formatterParams.symbol || "";
var after = !!formatterParams.symbolAfter;
var precision = typeof formatterParams.precision !== "undefined" ? formatterParams.precision : 2;
if (isNaN(floatVal)) {
return this.emptyToSpace(this.sanitizeHTML(cell.getValue()));
}
number = precision !== false ? floatVal.toFixed(precision) : floatVal;
number = String(number).split(".");
integer = number[0];
decimal = number.length > 1 ? decimalSym + number[1] : "";
rgx = /(\d+)(\d{3})/;
while (rgx.test(integer)) {
integer = integer.replace(rgx, "$1" + thousandSym + "$2");
}
return after ? integer + decimal + symbol : symbol + integer + decimal;
},
//clickable anchor tag
link: function link(cell, formatterParams, onRendered) {
var value = this.sanitizeHTML(cell.getValue()),
urlPrefix = formatterParams.urlPrefix || "",
label = this.emptyToSpace(value),
el = document.createElement("a"),
data;
if (formatterParams.labelField) {
data = cell.getData();
label = data[formatterParams.labelField];
}
if (formatterParams.label) {
switch (_typeof(formatterParams.label)) {
case "string":
label = formatterParams.label;
break;
case "function":
label = formatterParams.label(cell);
break;
}
}
if (formatterParams.urlField) {
data = cell.getData();
value = data[formatterParams.urlField];
}
if (formatterParams.url) {
switch (_typeof(formatterParams.url)) {
case "string":
value = formatterParams.url;
break;
case "function":
value = formatterParams.url(cell);
break;
}
}
el.setAttribute("href", urlPrefix + value);
if (formatterParams.target) {
el.setAttribute("target", formatterParams.target);
}
el.innerHTML = this.emptyToSpace(label);
return el;
},
//image element
image: function image(cell, formatterParams, onRendered) {
var el = document.createElement("img");
el.setAttribute("src", cell.getValue());
switch (_typeof(formatterParams.height)) {
case "number":
element.style.height = formatterParams.height + "px";
break;
case "string":
element.style.height = formatterParams.height;
break;
}
switch (_typeof(formatterParams.width)) {
case "number":
element.style.width = formatterParams.width + "px";
break;
case "string":
element.style.width = formatterParams.width;
break;
}
el.addEventListener("load", function () {
cell.getRow().normalizeHeight();
});
return el;
},
//tick or cross
tickCross: function tickCross(cell, formatterParams, onRendered) {
var value = cell.getValue(),
element = cell.getElement(),
empty = formatterParams.allowEmpty,
truthy = formatterParams.allowTruthy,
tick = typeof formatterParams.tickElement !== "undefined" ? formatterParams.tickElement : '<svg enable-background="new 0 0 24 24" height="14" width="14" viewBox="0 0 24 24" xml:space="preserve" ><path fill="#2DC214" clip-rule="evenodd" d="M21.652,3.211c-0.293-0.295-0.77-0.295-1.061,0L9.41,14.34 c-0.293,0.297-0.771,0.297-1.062,0L3.449,9.351C3.304,9.203,3.114,9.13,2.923,9.129C2.73,9.128,2.534,9.201,2.387,9.351 l-2.165,1.946C0.078,11.445,0,11.63,0,11.823c0,0.194,0.078,0.397,0.223,0.544l4.94,5.184c0.292,0.296,0.771,0.776,1.062,1.07 l2.124,2.141c0.292,0.293,0.769,0.293,1.062,0l14.366-14.34c0.293-0.294,0.293-0.777,0-1.071L21.652,3.211z" fill-rule="evenodd"/></svg>',
cross = typeof formatterParams.crossElement !== "undefined" ? formatterParams.crossElement : '<svg enable-background="new 0 0 24 24" height="14" width="14" viewBox="0 0 24 24" xml:space="preserve" ><path fill="#CE1515" d="M22.245,4.015c0.313,0.313,0.313,0.826,0,1.139l-6.276,6.27c-0.313,0.312-0.313,0.826,0,1.14l6.273,6.272 c0.313,0.313,0.313,0.826,0,1.14l-2.285,2.277c-0.314,0.312-0.828,0.312-1.142,0l-6.271-6.271c-0.313-0.313-0.828-0.313-1.141,0 l-6.276,6.267c-0.313,0.313-0.828,0.313-1.141,0l-2.282-2.28c-0.313-0.313-0.313-0.826,0-1.14l6.278-6.269 c0.313-0.312,0.313-0.826,0-1.14L1.709,5.147c-0.314-0.313-0.314-0.827,0-1.14l2.284-2.278C4.308,1.417,4.821,1.417,5.135,1.73 L11.405,8c0.314,0.314,0.828,0.314,1.141,0.001l6.276-6.267c0.312-0.312,0.826-0.312,1.141,0L22.245,4.015z"/></svg>';
if (truthy && value || value === true || value === "true" || value === "True" || value === 1 || value === "1") {
element.setAttribute("aria-checked", true);
return tick || "";
} else {
if (empty && (value === "null" || value === "" || value === null || typeof value === "undefined")) {
element.setAttribute("aria-checked", "mixed");
return "";
} else {
element.setAttribute("aria-checked", false);
return cross || "";
}
}
},
datetime: function datetime(cell, formatterParams, onRendered) {
var inputFormat = formatterParams.inputFormat || "YYYY-MM-DD hh:mm:ss";
var outputFormat = formatterParams.outputFormat || "DD/MM/YYYY hh:mm:ss";
var invalid = typeof formatterParams.invalidPlaceholder !== "undefined" ? formatterParams.invalidPlaceholder : "";
var value = cell.getValue();
var newDatetime = moment(value, inputFormat);
if (newDatetime.isValid()) {
return newDatetime.format(outputFormat);
} else {
if (invalid === true) {
return value;
} else if (typeof invalid === "function") {
return invalid(value);
} else {
return invalid;
}
}
},
datetimediff: function datetime(cell, formatterParams, onRendered) {
var inputFormat = formatterParams.inputFormat || "YYYY-MM-DD hh:mm:ss";
var invalid = typeof formatterParams.invalidPlaceholder !== "undefined" ? formatterParams.invalidPlaceholder : "";
var suffix = typeof formatterParams.suffix !== "undefined" ? formatterParams.suffix : false;
var unit = typeof formatterParams.unit !== "undefined" ? formatterParams.unit : undefined;
var humanize = typeof formatterParams.humanize !== "undefined" ? formatterParams.humanize : false;
var date = typeof formatterParams.date !== "undefined" ? formatterParams.date : moment();
var value = cell.getValue();
var newDatetime = moment(value, inputFormat);
if (newDatetime.isValid()) {
if (humanize) {
return moment.duration(newDatetime.diff(date)).humanize(suffix);
} else {
return newDatetime.diff(date, unit) + (suffix ? " " + suffix : "");
}
} else {
if (invalid === true) {
return value;
} else if (typeof invalid === "function") {
return invalid(value);
} else {
return invalid;
}
}
},
//select
lookup: function lookup(cell, formatterParams, onRendered) {
var value = cell.getValue();
if (typeof formatterParams[value] === "undefined") {
console.warn('Missing display value for ' + value);
return value;
}
return formatterParams[value];
},
//star rating
star: function star(cell, formatterParams, onRendered) {
var value = cell.getValue(),
element = cell.getElement(),
maxStars = formatterParams && formatterParams.stars ? formatterParams.stars : 5,
stars = document.createElement("span"),
star = document.createElementNS('http://www.w3.org/2000/svg', "svg"),
starActive = '<polygon fill="#FFEA00" stroke="#C1AB60" stroke-width="37.6152" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="259.216,29.942 330.27,173.919 489.16,197.007 374.185,309.08 401.33,467.31 259.216,392.612 117.104,467.31 144.25,309.08 29.274,197.007 188.165,173.919 "/>',
starInactive = '<polygon fill="#D2D2D2" stroke="#686868" stroke-width="37.6152" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="259.216,29.942 330.27,173.919 489.16,197.007 374.185,309.08 401.33,467.31 259.216,392.612 117.104,467.31 144.25,309.08 29.274,197.007 188.165,173.919 "/>';
//style stars holder
stars.style.verticalAlign = "middle";
//style star
star.setAttribute("width", "14");
star.setAttribute("height", "14");
star.setAttribute("viewBox", "0 0 512 512");
star.setAttribute("xml:space", "preserve");
star.style.padding = "0 1px";
value = parseInt(value) < maxStars ? parseInt(value) : maxStars;
for (var i = 1; i <= maxStars; i++) {
var nextStar = star.cloneNode(true);
nextStar.innerHTML = i <= value ? starActive : starInactive;
stars.appendChild(nextStar);
}
element.style.whiteSpace = "nowrap";
element.style.overflow = "hidden";
element.style.textOverflow = "ellipsis";
element.setAttribute("aria-label", value);
return stars;
},
//progress bar
progress: function progress(cell, formatterParams, onRendered) {
//progress bar
var value = this.sanitizeHTML(cell.getValue()) || 0,
element = cell.getElement(),
max = formatterParams && formatterParams.max ? formatterParams.max : 100,
min = formatterParams && formatterParams.min ? formatterParams.min : 0,
legendAlign = formatterParams && formatterParams.legendAlign ? formatterParams.legendAlign : "center",
percent,
percentValue,
color,
legend,
legendColor,
top,
left,
right,
bottom;
//make sure value is in range
percentValue = parseFloat(value) <= max ? parseFloat(value) : max;
percentValue = parseFloat(percentValue) >= min ? parseFloat(percentValue) : min;
//workout percentage
percent = (max - min) / 100;
percentValue = Math.round((percentValue - min) / percent);
//set bar color
switch (_typeof(formatterParams.color)) {
case "string":
color = formatterParams.color;
break;
case "function":
color = formatterParams.color(value);
break;
case "object":
if (Array.isArray(formatterParams.color)) {
var unit = 100 / formatterParams.color.length;
var index = Math.floor(percentValue / unit);
index = Math.min(index, formatterParams.color.length - 1);
index = Math.max(index, 0);
color = formatterParams.color[index];
break;
}
default:
color = "#2DC214";
}
//generate legend
switch (_typeof(formatterParams.legend)) {
case "string":
legend = formatterParams.legend;
break;
case "function":
legend = formatterParams.legend(value);
break;
case "boolean":
legend = value;
break;
default:
legend = false;
}
//set legend color
switch (_typeof(formatterParams.legendColor)) {
case "string":
legendColor = formatterParams.legendColor;
break;
case "function":
legendColor = formatterParams.legendColor(value);
break;
case "object":
if (Array.isArray(formatterParams.legendColor)) {
var unit = 100 / formatterParams.legendColor.length;
var index = Math.floor(percentValue / unit);
index = Math.min(index, formatterParams.legendColor.length - 1);
index = Math.max(index, 0);
legendColor = formatterParams.legendColor[index];
}
break;
default:
legendColor = "#000";
}
element.style.minWidth = "30px";
element.style.position = "relative";
element.setAttribute("aria-label", percentValue);
return "<div style='position:absolute; top:8px; bottom:8px; left:4px; right:4px;' data-max='" + max + "' data-min='" + min + "'><div style='position:relative; height:100%; width:calc(" + percentValue + "%); background-color:" + color + "; display:inline-block;'></div></div>" + (legend ? "<div style='position:absolute; top:4px; left:0; text-align:" + legendAlign + "; width:100%; color:" + legendColor + ";'>" + legend + "</div>" : "");
},
//background color
color: function color(cell, formatterParams, onRendered) {
cell.getElement().style.backgroundColor = this.sanitizeHTML(cell.getValue());
return "";
},
//tick icon
buttonTick: function buttonTick(cell, formatterParams, onRendered) {
return '<svg enable-background="new 0 0 24 24" height="14" width="14" viewBox="0 0 24 24" xml:space="preserve" ><path fill="#2DC214" clip-rule="evenodd" d="M21.652,3.211c-0.293-0.295-0.77-0.295-1.061,0L9.41,14.34 c-0.293,0.297-0.771,0.297-1.062,0L3.449,9.351C3.304,9.203,3.114,9.13,2.923,9.129C2.73,9.128,2.534,9.201,2.387,9.351 l-2.165,1.946C0.078,11.445,0,11.63,0,11.823c0,0.194,0.078,0.397,0.223,0.544l4.94,5.184c0.292,0.296,0.771,0.776,1.062,1.07 l2.124,2.141c0.292,0.293,0.769,0.293,1.062,0l14.366-14.34c0.293-0.294,0.293-0.777,0-1.071L21.652,3.211z" fill-rule="evenodd"/></svg>';
},
//cross icon
buttonCross: function buttonCross(cell, formatterParams, onRendered) {
return '<svg enable-background="new 0 0 24 24" height="14" width="14" viewBox="0 0 24 24" xml:space="preserve" ><path fill="#CE1515" d="M22.245,4.015c0.313,0.313,0.313,0.826,0,1.139l-6.276,6.27c-0.313,0.312-0.313,0.826,0,1.14l6.273,6.272 c0.313,0.313,0.313,0.826,0,1.14l-2.285,2.277c-0.314,0.312-0.828,0.312-1.142,0l-6.271-6.271c-0.313-0.313-0.828-0.313-1.141,0 l-6.276,6.267c-0.313,0.313-0.828,0.313-1.141,0l-2.282-2.28c-0.313-0.313-0.313-0.826,0-1.14l6.278-6.269 c0.313-0.312,0.313-0.826,0-1.14L1.709,5.147c-0.314-0.313-0.314-0.827,0-1.14l2.284-2.278C4.308,1.417,4.821,1.417,5.135,1.73 L11.405,8c0.314,0.314,0.828,0.314,1.141,0.001l6.276-6.267c0.312-0.312,0.826-0.312,1.141,0L22.245,4.015z"/></svg>';
},
//current row number
rownum: function rownum(cell, formatterParams, onRendered) {
return this.table.rowManager.activeRows.indexOf(cell.getRow()._getSelf()) + 1;
},
//row handle
handle: function handle(cell, formatterParams, onRendered) {
cell.getElement().classList.add("tabulator-row-handle");
return "<div class='tabulator-row-handle-box'><div class='tabulator-row-handle-bar'></div><div class='tabulator-row-handle-bar'></div><div class='tabulator-row-handle-bar'></div></div>";
},
responsiveCollapse: function responsiveCollapse(cell, formatterParams, onRendered) {
var self = this,
open = false,
el = document.createElement("div");
function toggleList(isOpen) {
var collapse = cell.getRow().getElement().getElementsByClassName("tabulator-responsive-collapse")[0];
open = isOpen;
if (open) {
el.classList.add("open");
if (collapse) {
collapse.style.display = '';
}
} else {
el.classList.remove("open");
if (collapse) {
collapse.style.display = 'none';
}
}
}
el.classList.add("tabulator-responsive-collapse-toggle");
el.innerHTML = "<span class='tabulator-responsive-collapse-toggle-open'>+</span><span class='tabulator-responsive-collapse-toggle-close'>-</span>";
cell.getElement().classList.add("tabulator-row-handle");
if (self.table.options.responsiveLayoutCollapseStartOpen) {
open = true;
}
el.addEventListener("click", function () {
toggleList(!open);
});
toggleList(open);
return el;
}
};
Tabulator.prototype.registerModule("format", Format);
File diff suppressed because one or more lines are too long
@@ -0,0 +1,160 @@
/* Tabulator v4.1.2 (c) Oliver Folkerd */
var FrozenColumns = function FrozenColumns(table) {
this.table = table; //hold Tabulator object
this.leftColumns = [];
this.rightColumns = [];
this.leftMargin = 0;
this.rightMargin = 0;
this.initializationMode = "left";
this.active = false;
};
//reset initial state
FrozenColumns.prototype.reset = function () {
this.initializationMode = "left";
this.leftColumns = [];
this.rightColumns = [];
this.active = false;
};
//initialize specific column
FrozenColumns.prototype.initializeColumn = function (column) {
var config = { margin: 0, edge: false };
if (column.definition.frozen) {
if (!column.parent.isGroup) {
if (!column.isGroup) {
config.position = this.initializationMode;
if (this.initializationMode == "left") {
this.leftColumns.push(column);
} else {
this.rightColumns.unshift(column);
}
this.active = true;
column.modules.frozen = config;
} else {
console.warn("Frozen Column Error - Column Groups cannot be frozen");
}
} else {
console.warn("Frozen Column Error - Grouped columns cannot be frozen");
}
} else {
this.initializationMode = "right";
}
};
//layout columns appropropriatly
FrozenColumns.prototype.layout = function () {
var self = this,
tableHolder = this.table.rowManager.element,
rightMargin = 0;
if (self.active) {
//calculate row padding
self.leftMargin = self._calcSpace(self.leftColumns, self.leftColumns.length);
self.table.columnManager.headersElement.style.marginLeft = self.leftMargin + "px";
self.rightMargin = self._calcSpace(self.rightColumns, self.rightColumns.length);
self.table.columnManager.element.style.paddingRight = self.rightMargin + "px";
self.table.rowManager.activeRows.forEach(function (row) {
self.layoutRow(row);
});
if (self.table.modExists("columnCalcs")) {
if (self.table.modules.columnCalcs.topInitialized && self.table.modules.columnCalcs.topRow) {
self.layoutRow(self.table.modules.columnCalcs.topRow);
}
if (self.table.modules.columnCalcs.botInitialized && self.table.modules.columnCalcs.botRow) {
self.layoutRow(self.table.modules.columnCalcs.botRow);
}
}
//calculate left columns
self.leftColumns.forEach(function (column, i) {
column.modules.frozen.margin = self._calcSpace(self.leftColumns, i) + self.table.columnManager.scrollLeft;
if (i == self.leftColumns.length - 1) {
column.modules.frozen.edge = true;
} else {
column.modules.frozen.edge = false;
}
self.layoutColumn(column);
});
//calculate right frozen columns
rightMargin = self.table.rowManager.element.clientWidth + self.table.columnManager.scrollLeft;
// if(tableHolder.scrollHeight > tableHolder.clientHeight){
// rightMargin -= tableHolder.offsetWidth - tableHolder.clientWidth;
// }
self.rightColumns.forEach(function (column, i) {
column.modules.frozen.margin = rightMargin - self._calcSpace(self.rightColumns, i + 1);
if (i == self.rightColumns.length - 1) {
column.modules.frozen.edge = true;
} else {
column.modules.frozen.edge = false;
}
self.layoutColumn(column);
});
this.table.rowManager.tableElement.style.marginRight = this.rightMargin + "px";
}
};
FrozenColumns.prototype.layoutColumn = function (column) {
var self = this;
self.layoutElement(column.getElement(), column);
column.cells.forEach(function (cell) {
self.layoutElement(cell.getElement(), column);
});
};
FrozenColumns.prototype.layoutRow = function (row) {
var rowEl = row.getElement();
rowEl.style.paddingLeft = this.leftMargin + "px";
// rowEl.style.paddingRight = this.rightMargin + "px";
};
FrozenColumns.prototype.layoutElement = function (element, column) {
if (column.modules.frozen) {
element.style.position = "absolute";
element.style.left = column.modules.frozen.margin + "px";
element.classList.add("tabulator-frozen");
if (column.modules.frozen.edge) {
element.classList.add("tabulator-frozen-" + column.modules.frozen.position);
}
}
};
FrozenColumns.prototype._calcSpace = function (columns, index) {
var width = 0;
for (var i = 0; i < index; i++) {
if (columns[i].visible) {
width += columns[i].getWidth();
}
}
return width;
};
Tabulator.prototype.registerModule("frozenColumns", FrozenColumns);
@@ -0,0 +1,2 @@
/* Tabulator v4.1.2 (c) Oliver Folkerd */
var FrozenColumns=function(o){this.table=o,this.leftColumns=[],this.rightColumns=[],this.leftMargin=0,this.rightMargin=0,this.initializationMode="left",this.active=!1};FrozenColumns.prototype.reset=function(){this.initializationMode="left",this.leftColumns=[],this.rightColumns=[],this.active=!1},FrozenColumns.prototype.initializeColumn=function(o){var e={margin:0,edge:!1};o.definition.frozen?o.parent.isGroup?console.warn("Frozen Column Error - Grouped columns cannot be frozen"):o.isGroup?console.warn("Frozen Column Error - Column Groups cannot be frozen"):(e.position=this.initializationMode,"left"==this.initializationMode?this.leftColumns.push(o):this.rightColumns.unshift(o),this.active=!0,o.modules.frozen=e):this.initializationMode="right"},FrozenColumns.prototype.layout=function(){var o=this,e=(this.table.rowManager.element,0);o.active&&(o.leftMargin=o._calcSpace(o.leftColumns,o.leftColumns.length),o.table.columnManager.headersElement.style.marginLeft=o.leftMargin+"px",o.rightMargin=o._calcSpace(o.rightColumns,o.rightColumns.length),o.table.columnManager.element.style.paddingRight=o.rightMargin+"px",o.table.rowManager.activeRows.forEach(function(e){o.layoutRow(e)}),o.table.modExists("columnCalcs")&&(o.table.modules.columnCalcs.topInitialized&&o.table.modules.columnCalcs.topRow&&o.layoutRow(o.table.modules.columnCalcs.topRow),o.table.modules.columnCalcs.botInitialized&&o.table.modules.columnCalcs.botRow&&o.layoutRow(o.table.modules.columnCalcs.botRow)),o.leftColumns.forEach(function(e,t){e.modules.frozen.margin=o._calcSpace(o.leftColumns,t)+o.table.columnManager.scrollLeft,t==o.leftColumns.length-1?e.modules.frozen.edge=!0:e.modules.frozen.edge=!1,o.layoutColumn(e)}),e=o.table.rowManager.element.clientWidth+o.table.columnManager.scrollLeft,o.rightColumns.forEach(function(t,n){t.modules.frozen.margin=e-o._calcSpace(o.rightColumns,n+1),n==o.rightColumns.length-1?t.modules.frozen.edge=!0:t.modules.frozen.edge=!1,o.layoutColumn(t)}),this.table.rowManager.tableElement.style.marginRight=this.rightMargin+"px")},FrozenColumns.prototype.layoutColumn=function(o){var e=this;e.layoutElement(o.getElement(),o),o.cells.forEach(function(t){e.layoutElement(t.getElement(),o)})},FrozenColumns.prototype.layoutRow=function(o){o.getElement().style.paddingLeft=this.leftMargin+"px"},FrozenColumns.prototype.layoutElement=function(o,e){e.modules.frozen&&(o.style.position="absolute",o.style.left=e.modules.frozen.margin+"px",o.classList.add("tabulator-frozen"),e.modules.frozen.edge&&o.classList.add("tabulator-frozen-"+e.modules.frozen.position))},FrozenColumns.prototype._calcSpace=function(o,e){for(var t=0,n=0;n<e;n++)o[n].visible&&(t+=o[n].getWidth());return t},Tabulator.prototype.registerModule("frozenColumns",FrozenColumns);
@@ -0,0 +1,98 @@
/* Tabulator v4.1.2 (c) Oliver Folkerd */
var FrozenRows = function FrozenRows(table) {
this.table = table; //hold Tabulator object
this.topElement = document.createElement("div");
this.rows = [];
this.displayIndex = 0; //index in display pipeline
};
FrozenRows.prototype.initialize = function () {
this.rows = [];
this.topElement.classList.add("tabulator-frozen-rows-holder");
// this.table.columnManager.element.append(this.topElement);
this.table.columnManager.getElement().insertBefore(this.topElement, this.table.columnManager.headersElement.nextSibling);
};
FrozenRows.prototype.setDisplayIndex = function (index) {
this.displayIndex = index;
};
FrozenRows.prototype.getDisplayIndex = function () {
return this.displayIndex;
};
FrozenRows.prototype.isFrozen = function () {
return !!this.rows.length;
};
//filter frozen rows out of display data
FrozenRows.prototype.getRows = function (rows) {
var self = this,
frozen = [],
output = rows.slice(0);
this.rows.forEach(function (row) {
var index = output.indexOf(row);
if (index > -1) {
output.splice(index, 1);
}
});
return output;
};
FrozenRows.prototype.freezeRow = function (row) {
if (!row.modules.frozen) {
row.modules.frozen = true;
this.topElement.appendChild(row.getElement());
row.initialize();
row.normalizeHeight();
this.table.rowManager.adjustTableSize();
this.rows.push(row);
this.table.rowManager.refreshActiveData("display");
this.styleRows();
} else {
console.warn("Freeze Error - Row is already frozen");
}
};
FrozenRows.prototype.unfreezeRow = function (row) {
var index = this.rows.indexOf(row);
if (row.modules.frozen) {
row.modules.frozen = false;
var rowEl = row.getElement();
rowEl.parentNode.removeChild(rowEl);
this.table.rowManager.adjustTableSize();
this.rows.splice(index, 1);
this.table.rowManager.refreshActiveData("display");
if (this.rows.length) {
this.styleRows();
}
} else {
console.warn("Freeze Error - Row is already unfrozen");
}
};
FrozenRows.prototype.styleRows = function (row) {
var self = this;
this.rows.forEach(function (row, i) {
self.table.rowManager.styleRow(row, i);
});
};
Tabulator.prototype.registerModule("frozenRows", FrozenRows);

Some files were not shown because too many files have changed in this diff Show More