diff --git a/composer.json b/composer.json index 6380b9d7e..786884acc 100644 --- a/composer.json +++ b/composer.json @@ -66,7 +66,7 @@ "oat-sa/generis" : ">=15.22", "oat-sa/tao-core": ">=54.0.0", "oat-sa/extension-tao-item" : ">=12.1.0", - "oat-sa/extension-tao-itemqti" : ">=30.0.0", + "oat-sa/extension-tao-itemqti" : ">=30.10.0", "oat-sa/extension-tao-test" : ">=16.0.0", "oat-sa/extension-tao-delivery" : ">=15.0.0", "oat-sa/extension-tao-outcome" : ">=13.0.0", diff --git a/manifest.php b/manifest.php index f6cfc386b..6840e9446 100755 --- a/manifest.php +++ b/manifest.php @@ -21,6 +21,7 @@ use oat\tao\model\user\TaoRoles; use oat\taoQtiTest\model\Container\TestQtiServiceProvider; +use oat\taoQtiTest\models\classes\metadata\MetadataServiceProvider; // phpcs:disable Generic.Files.LineLength use oat\taoQtiTest\models\classes\render\CustomInteraction\ServiceProvider\CustomInteractionPostProcessingServiceProvider; // phpcs:enable Generic.Files.LineLength @@ -182,6 +183,7 @@ CustomInteractionPostProcessingServiceProvider::class, ItemsReferencesServiceProvider::class, TestQtiServiceProvider::class, - TestSessionStateServiceProvider::class + TestSessionStateServiceProvider::class, + MetadataServiceProvider::class ], ]; diff --git a/models/classes/class.QtiTestService.php b/models/classes/class.QtiTestService.php index a3d6339a4..a7841f830 100644 --- a/models/classes/class.QtiTestService.php +++ b/models/classes/class.QtiTestService.php @@ -29,8 +29,12 @@ use oat\taoItems\model\Command\DeleteItemCommand; use oat\taoQtiItem\model\qti\ImportService; use oat\taoQtiItem\model\qti\metadata\importer\MetadataImporter; +use oat\taoQtiItem\model\qti\metadata\imsManifest\MetaMetadataExtractor; +use oat\taoQtiItem\model\qti\metadata\importer\MetaMetadataImportMapper; +use oat\taoQtiItem\model\qti\metadata\importer\PropertyDoesNotExistException; use oat\taoQtiItem\model\qti\metadata\MetadataGuardianResource; use oat\taoQtiItem\model\qti\metadata\MetadataService; +use oat\taoQtiItem\model\qti\metadata\ontology\MappedMetadataInjector; use oat\taoQtiItem\model\qti\Resource; use oat\taoQtiItem\model\qti\Service; use oat\taoQtiTest\models\cat\AdaptiveSectionInjectionException; @@ -50,6 +54,8 @@ use qtism\data\storage\xml\XmlDocument; use qtism\data\storage\xml\XmlStorageException; use taoTests_models_classes_TestsService as TestService; +use oat\oatbox\reporting\Report; +use taoQtiTest_models_classes_import_TestImportForm as TestImportForm; /** * the QTI TestModel service. @@ -349,7 +355,8 @@ public function importMultipleTests( core_kernel_classes_Class $targetClass, $file, bool $overwriteTest = false, - ?string $itemClassUri = null + ?string $itemClassUri = null, + array $form = [] ) { $testClass = $targetClass; $report = new common_report_Report(common_report_Report::TYPE_INFO); @@ -417,7 +424,8 @@ public function importMultipleTests( $folder, $alreadyImportedQtiResources, $overwriteTest, - $itemClassUri + $itemClassUri, + !empty($form[TestImportForm::METADATA_FORM_ELEMENT_NAME]) ?? false ); $report->add($importTestReport); @@ -537,7 +545,8 @@ protected function importTest( $folder, array $ignoreQtiResources = [], bool $overwriteTest = false, - ?string $itemClassUri = null + ?string $itemClassUri = null, + bool $importMetadata = false ) { /** @var ImportService $itemImportService */ $itemImportService = $this->getServiceLocator()->get(ImportService::SERVICE_ID); @@ -585,6 +594,8 @@ protected function importTest( $reportCtx->testMetadata = $metadataValues[$qtiTestResourceIdentifier] ?? []; $reportCtx->createdClasses = []; + + // 'uriResource' key is needed by javascript in tao/views/templates/form/import.tpl $reportCtx->uriResource = $testResource->getUri(); @@ -630,6 +641,15 @@ protected function importTest( $targetItemClass->label = $testLabel; $reportCtx->itemClass = $targetItemClass; + + $mappedProperties = $this->getMappedProperties( + $importMetadata, + $domManifest, + $reportCtx, + $testClass, + $targetItemClass + ); + // -- Load all items related to test. $itemError = false; @@ -679,7 +699,6 @@ protected function importTest( ); } } - // Skip if $qtiFile already imported (multiple assessmentItemRef "hrefing" the same // file). if (array_key_exists($qtiFile, $alreadyImportedTestItemFiles) === false) { @@ -697,7 +716,9 @@ protected function importTest( $this->useMetadataValidators, $this->itemMustExist, $this->itemMustBeOverwritten, - $reportCtx->overwrittenItems + $reportCtx->overwrittenItems, + $mappedProperties['itemProperties'] ?? [], + $importMetadata ); $reportCtx->createdClasses = array_merge( @@ -780,6 +801,11 @@ protected function importTest( // 4. Import metadata for the resource (use same mechanics as item resources). // Metadata will be set as property values. $this->getMetadataImporter()->inject($qtiTestResource->getIdentifier(), $testResource); + $this->getServiceManager()->getContainer()->get(MappedMetadataInjector::class)->inject( + $mappedProperties['testProperties'] ?? [], + $metadataValues[$qtiTestResourceIdentifier], + $testResource + ); // 5. if $targetClass does not contain any instances // (because everything resolved by class lookups), @@ -833,6 +859,9 @@ protected function importTest( $msg = __("Error found in the IMS QTI Test:\n%s", $finalErrorString); $report->add(common_report_Report::createFailure($msg)); + } catch (PropertyDoesNotExistException $e) { + $reportCtx->itemClass = $targetItemClass; + $report->add(Report::createError($e->getMessage())); } catch (CatEngineNotFoundException $e) { $report->add( new common_report_Report( @@ -1411,6 +1440,12 @@ protected function getMetadataImporter() return $this->metadataImporter; } + private function getMetaMetadataExtractor(): MetaMetadataExtractor + { + return $this->getPsrContainer()->get(MetaMetadataExtractor::class); + return $this->getServiceManager()->getContainer()->get(MetaMetadataExtractor::class); + } + private function getSecureResourceService(): SecureResourceServiceInterface { return $this->getServiceLocator()->get(SecureResourceServiceInterface::SERVICE_ID); @@ -1488,4 +1523,26 @@ private function getPsrContainer(): ContainerInterface { return $this->getServiceLocator()->getContainer(); } + + private function getMetaMetadataImporter(): MetaMetadataImportMapper + { + return $this->getServiceManager()->getContainer()->get(MetaMetadataImportMapper::class); + } + + private function getMappedProperties( + bool $importMetadata, + DOMDocument $domManifest, + stdClass $reportCtx, + core_kernel_classes_Class $testClass, + core_kernel_classes_Class $targetItemClass + ): array { + if ($importMetadata === true) { + $metaMetadataValues = $this->getMetaMetadataExtractor()->extract($domManifest); + $reportCtx->metaMetadata = $metaMetadataValues; + return $this->getMetaMetadataImporter() + ->mapMetaMetadataToProperties($metaMetadataValues, $targetItemClass, $testClass); + } + + return []; + } } diff --git a/models/classes/export/AbstractQtiTestExporter.php b/models/classes/export/AbstractQtiTestExporter.php index 0de4e8c55..fbac75b30 100644 --- a/models/classes/export/AbstractQtiTestExporter.php +++ b/models/classes/export/AbstractQtiTestExporter.php @@ -32,6 +32,9 @@ use DOMXPath; use oat\oatbox\reporting\Report; use oat\oatbox\reporting\ReportInterface; +use oat\tao\model\featureFlag\FeatureFlagChecker; +use oat\taoQtiTest\models\classes\metadata\GenericLomOntologyExtractor; +use oat\taoQtiTest\models\classes\metadata\MetadataLomService; use qtism\data\storage\xml\marshalling\MarshallingException; use qtism\data\storage\xml\XmlDocument; use oat\oatbox\filesystem\Directory; @@ -174,6 +177,13 @@ public function export(array $options = []): Report // 3. Export test metadata to manifest $this->getMetadataExporter()->export($this->getItem(), $this->getManifest()); + if ($this->getFeatureFlagChecker()->isEnabled(MetadataLomService::FEATURE_FLAG)) { + $this->genericLomOntologyExtractor()->extract( + array_merge([$this->getItem()], $this->getItems()), + $this->getManifest() + ); + } + // 4. Persist manifest in archive. $this->getZip()->addFromString('imsmanifest.xml', $this->getManifest()->saveXML()); @@ -350,4 +360,14 @@ protected function getServiceManager(): ServiceManager { return ServiceManager::getServiceManager(); } + + private function genericLomOntologyExtractor(): GenericLomOntologyExtractor + { + return $this->getServiceManager()->getContainer()->get(GenericLomOntologyExtractor::class); + } + + private function getFeatureFlagChecker(): FeatureFlagChecker + { + return $this->getServiceManager()->getContainer()->get(FeatureFlagChecker::class); + } } diff --git a/models/classes/import/class.TestImport.php b/models/classes/import/class.TestImport.php index 43b7a0aab..418f9d509 100755 --- a/models/classes/import/class.TestImport.php +++ b/models/classes/import/class.TestImport.php @@ -22,10 +22,14 @@ use oat\oatbox\event\EventManagerAwareTrait; use oat\oatbox\PhpSerializable; use oat\oatbox\PhpSerializeStateless; +use oat\tao\model\featureFlag\FeatureFlagChecker; use oat\tao\model\import\ImportHandlerHelperTrait; use oat\tao\model\import\TaskParameterProviderInterface; +use oat\tao\model\upload\UploadService; +use oat\taoQtiTest\models\classes\metadata\MetadataLomService; use oat\taoQtiTest\models\event\QtiTestImportEvent; use Zend\ServiceManager\ServiceLocatorAwareInterface; +use taoQtiTest_models_classes_import_TestImportForm as TestImportForm; /** * Import handler for QTI packages @@ -44,6 +48,9 @@ class taoQtiTest_models_classes_import_TestImport implements use EventManagerAwareTrait; use ImportHandlerHelperTrait; + public const DISABLED_FIELDS = 'disabledFields'; + public const METADATA_FIELD = 'metadataImport'; + /** * (non-PHPdoc) * @see tao_models_classes_import_ImportHandler::getLabel() @@ -59,7 +66,7 @@ public function getLabel() */ public function getForm() { - $form = new taoQtiTest_models_classes_import_TestImportForm(); + $form = new taoQtiTest_models_classes_import_TestImportForm([], $this->getFormOptions()); return $form->getForm(); } @@ -78,7 +85,8 @@ public function import($class, $form, $userId = null) // The zip extraction is a long process that can exceed the 30s timeout helpers_TimeOutHelper::setTimeOutLimit(helpers_TimeOutHelper::LONG); - $report = taoQtiTest_models_classes_QtiTestService::singleton()->importMultipleTests($class, $uploadedFile); + $report = taoQtiTest_models_classes_QtiTestService::singleton() + ->importMultipleTests($class, $uploadedFile, false, null, $form); helpers_TimeOutHelper::reset(); @@ -93,4 +101,32 @@ public function import($class, $form, $userId = null) return common_report_Report::createFailure($e->getMessage()); } } + public function getTaskParameters(tao_helpers_form_Form $importForm) + { + $file = $this->getUploadService()->getUploadedFlyFile($importForm->getValue('importFile') + ?: $importForm->getValue('source')['uploaded_file']); + + return [ + 'uploaded_file' => $file->getPrefix(), // because of Async, we need the full path of the uploaded file + TestImportForm::METADATA_FORM_ELEMENT_NAME => $importForm->getValue('metadata'), + ]; + } + + private function getFeatureFlagChecker(): FeatureFlagChecker + { + return $this->serviceLocator->getContainer()->get(FeatureFlagChecker::class); + } + + private function getFormOptions(): array + { + $options = []; + if (!$this->getFeatureFlagChecker()->isEnabled(MetadataLomService::FEATURE_FLAG)) { + $options[self::DISABLED_FIELDS] = [self::METADATA_FIELD]; + } + return $options; + } + private function getUploadService() + { + return $this->serviceLocator->get(UploadService::SERVICE_ID); + } } diff --git a/models/classes/import/class.TestImportForm.php b/models/classes/import/class.TestImportForm.php index 4720efda7..a35e355bc 100755 --- a/models/classes/import/class.TestImportForm.php +++ b/models/classes/import/class.TestImportForm.php @@ -31,12 +31,8 @@ */ class taoQtiTest_models_classes_import_TestImportForm extends tao_helpers_form_FormContainer { - // --- ASSOCIATIONS --- + public const METADATA_FORM_ELEMENT_NAME = 'metadata'; - - // --- ATTRIBUTES --- - - // --- OPERATIONS --- /** * (non-PHPdoc) * @see tao_helpers_form_FormContainer::initForm() @@ -99,18 +95,41 @@ public function initElements() ) ]); + $this->form->addElement($fileElt); - /* - $disableValidationElt = tao_helpers_form_FormFactory::getElement("disable_validation", 'Checkbox'); - $disableValidationElt->setDescription(__("Disable validation")); - $disableValidationElt->setOptions(array("on" => "")); - $this->form->addElement($disableValidationElt); - */ - $this->form->createGroup('file', __('Import a QTI/APIP Content Package'), ['source']); + $this->form->createGroup( + 'file', + __('Import a QTI/APIP Content Package'), + [ + 'source', + ] + ); + $this->addMetadataImportElement(); $qtiSentElt = tao_helpers_form_FormFactory::getElement('import_sent_qti', 'Hidden'); $qtiSentElt->setValue(1); $this->form->addElement($qtiSentElt); } + + private function isMetadataDisabled(): bool + { + return isset($this->options[taoQtiTest_models_classes_import_TestImport::DISABLED_FIELDS]) && + in_array( + taoQtiTest_models_classes_import_TestImport::METADATA_FIELD, + $this->options[taoQtiTest_models_classes_import_TestImport::DISABLED_FIELDS] + ); + } + + private function addMetadataImportElement() + { + if (!$this->isMetadataDisabled()) { + $metadataImport = tao_helpers_form_FormFactory::getElement(self::METADATA_FORM_ELEMENT_NAME, 'Checkbox'); + $metadataImport->setOptions([self::METADATA_FORM_ELEMENT_NAME => __('Import metadata or fail')]); + $metadataImport->setDescription(__('Metadata import')); + $metadataImport->setLevel(1); + $this->form->addElement($metadataImport); + $this->form->addToGroup('file', self::METADATA_FORM_ELEMENT_NAME); + } + } } diff --git a/models/classes/metadata/GenericLomOntologyExtractor.php b/models/classes/metadata/GenericLomOntologyExtractor.php new file mode 100644 index 000000000..03b310293 --- /dev/null +++ b/models/classes/metadata/GenericLomOntologyExtractor.php @@ -0,0 +1,86 @@ +ontology = $ontology; + $this->propertyMapper = $propertyMapper; + $this->metadataLomService = $metadataLomService; + } + + /** + * @param Resource[] $resourceCollection + * @throws MetadataExtractionException + */ + public function extract(array $resourceCollection, DOMDocument $manifest): void + { + $properties = []; + + foreach ($resourceCollection as $resource) { + if (!$resource instanceof Resource) { + throw new MetadataExtractionException( + __('The given target is not an instance of core_kernel_classes_Resource') + ); + } + + foreach ($resource->getRdfTriples() as $triple) { + if ($this->mappingRequired($properties, $triple)) { + $properties[] = $this->propertyMapper + ->getMetadataProperties( + $this->ontology->getProperty($triple->predicate) + ); + } + } + } + + $this->metadataLomService->addPropertiesToMetadataBlock($properties, $manifest); + } + + /** + * Mapping action only applies for confirmed properties that are not already mapped + */ + private function mappingRequired(array $properties, Triple $triple): bool + { + return $this->ontology->getProperty($triple->predicate)->isProperty() && + array_filter($properties, function ($property) use ($triple) { + return $property['uri'] === $triple->predicate; + }) === []; + } +} diff --git a/models/classes/metadata/MetadataLomService.php b/models/classes/metadata/MetadataLomService.php new file mode 100644 index 000000000..cc60b2fe5 --- /dev/null +++ b/models/classes/metadata/MetadataLomService.php @@ -0,0 +1,59 @@ +getElementsByTagName('metadata'); + + if ($metadataBlock === null) { + $metadataBlock = $manifest->createElement('metadata'); + $manifest->documentElement->appendChild($metadataBlock); + } + + $metadataBlock->item(0) + ->appendChild($manifest->createElement('imsmd:lom')) + ->appendChild($manifest->createElement('imsmd:metaMetadata')) + ->appendChild($manifest->createElement('extension')) + ->appendChild($manifest->createElement('customProperties')); + + foreach ($properties as $property) { + $propertyNode = $manifest->createElement('property'); + foreach ($property as $key => $value) { + $propertyNode->appendChild($manifest->createElement($key, $value)); + } + $metadataBlock->item(0) + ->getElementsByTagName('customProperties') + ->item(0) + ->appendChild($propertyNode); + } + } +} diff --git a/models/classes/metadata/MetadataServiceProvider.php b/models/classes/metadata/MetadataServiceProvider.php new file mode 100644 index 000000000..c252528ef --- /dev/null +++ b/models/classes/metadata/MetadataServiceProvider.php @@ -0,0 +1,62 @@ +services(); + + $services->set(MetadataLomService::class, MetadataLomService::class); + + $services->set(PropertyMapper::class, PropertyMapper::class) + ->args([ + service(ChecksumGenerator::class), + [ + 'label' => RDFS_LABEL, + 'domain' => RDFS_DOMAIN, + 'alias' => GenerisRdf::PROPERTY_ALIAS, + 'multiple' => GenerisRdf::PROPERTY_MULTIPLE + ] + ]); + + $services + ->set(GenericLomOntologyExtractor::class, GenericLomOntologyExtractor::class) + ->public() + ->args([ + service(Ontology::SERVICE_ID), + service(PropertyMapper::class), + service(MetadataLomService::class) + ]); + } +} diff --git a/models/classes/metadata/metaMetadata/PropertyMapper.php b/models/classes/metadata/metaMetadata/PropertyMapper.php new file mode 100644 index 000000000..af4fb9a19 --- /dev/null +++ b/models/classes/metadata/metaMetadata/PropertyMapper.php @@ -0,0 +1,78 @@ +metaMetadataCollectionToExport = $metaMetadataCollectionToExport; + $this->checksumGenerator = $checksumGenerator; + } + + public function getMetadataProperties(Property $property): array + { + $fields = []; + + foreach ($this->metaMetadataCollectionToExport as $key => $stringProperty) { + $fields['uri'] = $property->getUri(); + $metaProperty = $property->getOnePropertyValue(new Property($stringProperty)); + if ($metaProperty !== null) { + $fields[$key] = $metaProperty instanceof Resource + ? $metaProperty->getUri() + : (string) $metaProperty; + } + } + + if (!$this->isIgnoredForCollectionGathering($property)) { + $fields[self::DATATYPE_CHECKSUM] = $this->checksumGenerator->getRangeChecksum($property); + } + + return $fields; + } + + private function isIgnoredForCollectionGathering(Property $property): bool + { + return in_array($property->getUri(), $this->getIgnoredProperties()); + } + + private function getIgnoredProperties(): array + { + return [ + OntologyRdf::RDF_TYPE, + taoTests_models_classes_TestsService::PROPERTY_TEST_TESTMODEL, + RDFS_LABEL + ]; + } +} diff --git a/test/unit/models/classes/metadata/GenericLomOntologyExtractorTest.php b/test/unit/models/classes/metadata/GenericLomOntologyExtractorTest.php new file mode 100644 index 000000000..10971293a --- /dev/null +++ b/test/unit/models/classes/metadata/GenericLomOntologyExtractorTest.php @@ -0,0 +1,112 @@ +ontologyMock = $this->createMock(Ontology::class); + $this->propertyMapperMock = $this->createMock(PropertyMapper::class); + $this->metadataLomServiceMock = $this->createMock(MetadataLomService::class); + + $this->subject = new GenericLomOntologyExtractor( + $this->ontologyMock, + $this->propertyMapperMock, + $this->metadataLomServiceMock, + ); + } + + /** + * @noinspection PhpParamsInspection + */ + public function testExtractExceptionForCollectionWithNonResourceContent(): void + { + $this->expectException(MetadataExtractionException::class); + $resourceCollection = ['ResourceThatIsAString']; + $manifest = new DOMDocument(); + + $this->subject->extract($resourceCollection, $manifest); + } + + public function testExtract(): void + { + $resourceMock = $this->createMock(Resource::class); + $tripleMock1 = $this->createMock(Triple::class); + $tripleMock2 = $this->createMock(Triple::class); + $tripleMock3 = $this->createMock(Triple::class); + $propertyMock = $this->createMock(Property::class); + $manifest = new DOMDocument(); + $tripleMock1->predicate = 'predicate1'; + $tripleMock2->predicate = 'predicate2'; + $tripleMock3->predicate = 'predicate3'; + + $resourceMock->method('getRdfTriples')->willReturn([ + $tripleMock1, + $tripleMock2, + $tripleMock3 + ]); + + $propertyMock + ->method('isProperty') + ->willReturn(true); + + $this->ontologyMock + ->method('getProperty') + ->willReturn($propertyMock); + + $this->propertyMapperMock + ->method('getMetadataProperties') + ->willReturnOnConsecutiveCalls( + ['uri' => 'predicate1'], + ['uri' => 'predicate2'], + ['uri' => 'predicate3'], + ['uri' => 'predicate1'], + ['uri' => 'predicate2'], + ['uri' => 'predicate3'] + ); + + $this->metadataLomServiceMock + ->expects($this->once()) + ->method('addPropertiesToMetadataBlock') + ->with([ + ['uri' => 'predicate1'], + ['uri' => 'predicate2'], + ['uri' => 'predicate3'], + ], $manifest); + + $this->subject->extract([$resourceMock, $resourceMock], $manifest); + } +} diff --git a/test/unit/models/classes/metadata/MetadataLomServiceTest.php b/test/unit/models/classes/metadata/MetadataLomServiceTest.php new file mode 100644 index 000000000..cb5a697e3 --- /dev/null +++ b/test/unit/models/classes/metadata/MetadataLomServiceTest.php @@ -0,0 +1,62 @@ +metadataLomService = new MetadataLomService(); + } + + public function testAddPropertiesToMetadataBlock(): void + { + $manifest = new DOMDocument(); + $manifest->appendChild($manifest->createElement('metadata')); + + $proerties = [ + [ + 'label' => 'label_example', + 'domain' => 'domain_example', + 'alias' => 'alias_example', + 'multiple' => 'multiple_example', + ], + [ + 'label' => 'label_another_example', + 'domain' => 'domain_another_example', + 'alias' => 'alias_another_example', + 'multiple' => 'multiple_another_example', + ] + ]; + + $this->metadataLomService->addPropertiesToMetadataBlock($proerties, $manifest); + self::assertXmlStringEqualsXmlFile( + __DIR__ . '/imsManifestMetadata.xml', + $manifest->saveXML() + ); + } +} diff --git a/test/unit/models/classes/metadata/imsManifestMetadata.xml b/test/unit/models/classes/metadata/imsManifestMetadata.xml new file mode 100644 index 000000000..5fdf00e69 --- /dev/null +++ b/test/unit/models/classes/metadata/imsManifestMetadata.xml @@ -0,0 +1,23 @@ + + + + + + + + + domain_example + alias_example + multiple_example + + + + domain_another_example + alias_another_example + multiple_another_example + + + + + + diff --git a/test/unit/models/classes/metadata/metaMetadata/PropertyMapperTest.php b/test/unit/models/classes/metadata/metaMetadata/PropertyMapperTest.php new file mode 100644 index 000000000..056e50843 --- /dev/null +++ b/test/unit/models/classes/metadata/metaMetadata/PropertyMapperTest.php @@ -0,0 +1,84 @@ +checksumGeneratorMock = $this->createMock(ChecksumGenerator::class); + $this->metaMetadataCollectionToExport = [ + 'label' => RDFS_LABEL, + 'domain' => RDFS_DOMAIN, + 'alias' => GenerisRdf::PROPERTY_ALIAS, + 'multiple' => GenerisRdf::PROPERTY_MULTIPLE + ]; + + $this->subject = new PropertyMapper($this->checksumGeneratorMock, $this->metaMetadataCollectionToExport); + } + + public function testGetMetadataProperties(): void + { + $property = $this->createMock(Property::class); + $resourceMock = $this->createMock(Resource::class); + $property->method('getUri')->willReturn('uri'); + $resourceMock->method('getUri')->willReturn('resource_uri'); + + $property + ->method('getOnePropertyValue') + ->willReturnOnConsecutiveCalls( + $resourceMock, + 'value', + new core_kernel_classes_Literal('literal_value'), + null + ); + + $this->checksumGeneratorMock + ->method('getRangeChecksum') + ->willReturn('c315a4bd4fa0f4479b1ea4b5998aa548eed3b670'); + + + $result = $this->subject->getMetadataProperties($property); + + $this->assertIsArray($result); + $this->assertArrayHasKey('uri', $result); + $this->assertArrayHasKey('label', $result); + $this->assertArrayHasKey('domain', $result); + $this->assertArrayHasKey('alias', $result); + $this->assertArrayNotHasKey('multiple', $result); + $this->assertArrayHasKey(PropertyMapper::DATATYPE_CHECKSUM, $result); + $this->assertEquals('uri', $result['uri']); + $this->assertEquals('resource_uri', $result['label']); + $this->assertEquals('value', $result['domain']); + $this->assertEquals('literal_value', $result['alias']); + $this->assertEquals('c315a4bd4fa0f4479b1ea4b5998aa548eed3b670', $result['checksum']); + } +} diff --git a/views/css/test-runner.css b/views/css/test-runner.css index 10e25f133..14742d835 100644 --- a/views/css/test-runner.css +++ b/views/css/test-runner.css @@ -1,3 +1,3 @@ -@-o-keyframes loadingbar{0%{left:-10%}50%{left:90%}100%{left:-10%}}@-moz-keyframes loadingbar{0%{left:-10%}50%{left:90%}100%{left:-10%}}@-webkit-keyframes loadingbar{0%{left:-10%}50%{left:90%}100%{left:-10%}}@keyframes loadingbar{0%{left:-10%}50%{left:90%}100%{left:-10%}}.loading-bar{height:6px;position:absolute;width:100%;top:0px;display:none;z-index:10000;cursor:progress}.loading-bar.fixed{position:fixed;width:100%}.loading-bar.fixed:before{top:0 !important}.loading-bar.loading{display:block;overflow:hidden;top:58px}.loading-bar.loading:before{position:absolute;content:"";height:6px;width:20%;display:block;transform:translateZ(0);background:-webkit-linear-gradient(to right, transparent 0%, rgb(195, 90, 19) 20%, rgb(195, 90, 19) 80%, transparent 100%);background:-moz-linear-gradient(to right, transparent 0%, rgb(195, 90, 19) 20%, rgb(195, 90, 19) 80%, transparent 100%);background:-ms-linear-gradient(to right, transparent 0%, rgb(195, 90, 19) 20%, rgb(195, 90, 19) 80%, transparent 100%);background:-o-linear-gradient(to right, transparent 0%, rgb(195, 90, 19) 20%, rgb(195, 90, 19) 80%, transparent 100%);background:linear-gradient(to right, transparent 0%, rgb(195, 90, 19) 20%, rgb(195, 90, 19) 80%, transparent 100%);-webkit-animation:loadingbar 5s linear infinite;-moz-animation:loadingbar 5s linear infinite;-ms-animation:loadingbar 5s linear infinite;-o-animation:loadingbar 5s linear infinite;animation:loadingbar 5s linear infinite}.loading-bar.loading.loadingbar-covered{top:0px;overflow-y:visible}.loading-bar.loading.loadingbar-covered:before{top:86px}.no-version-warning .loading-bar.loadingbar-covered:before{top:58px}.section-container{top:0 !important}.section-container .flex-container-full{-ms-order:0;-webkit-order:0;order:0;flex-item-align:stretch;-ms-flex-item-align:stretch;-webkit-align-self:stretch;align-self:stretch;-ms-flex:0 0 100%;-webkit-flex:0 0 100%;flex:0 0 100%}.section-container .flex-container-half{-ms-order:0;-webkit-order:0;order:0;flex-item-align:stretch;-ms-flex-item-align:stretch;-webkit-align-self:stretch;align-self:stretch;-ms-flex:0 0 50%;-webkit-flex:0 0 50%;flex:0 0 50%}.section-container .flex-container-third{-ms-order:0;-webkit-order:0;order:0;flex-item-align:stretch;-ms-flex-item-align:stretch;-webkit-align-self:stretch;align-self:stretch;-ms-flex:0 0 33.3333333333%;-webkit-flex:0 0 33.3333333333%;flex:0 0 33.3333333333%}.section-container .flex-container-quarter{-ms-order:0;-webkit-order:0;order:0;flex-item-align:stretch;-ms-flex-item-align:stretch;-webkit-align-self:stretch;align-self:stretch;-ms-flex:0 0 25%;-webkit-flex:0 0 25%;flex:0 0 25%}.section-container .flex-container-remaining{-ms-order:0;-webkit-order:0;order:0;flex-item-align:stretch;-ms-flex-item-align:stretch;-webkit-align-self:stretch;align-self:stretch;-ms-flex:1 1 480px;-webkit-flex:1 1 480px;flex:1 1 480px}.section-container .flex-container-main-form{-ms-order:0;-webkit-order:0;order:0;flex-item-align:stretch;-ms-flex-item-align:stretch;-webkit-align-self:stretch;align-self:stretch;-ms-flex:0 0 500px;-webkit-flex:0 0 500px;flex:0 0 500px;margin:0 20px 20px 0;width:100%}.section-container .flex-container-main-form .form-content{max-width:100%}.section-container .flex-container-navi{-ms-order:0;-webkit-order:0;order:0;flex-item-align:stretch;-ms-flex-item-align:stretch;-webkit-align-self:stretch;align-self:stretch;-ms-flex:0 0 280px;-webkit-flex:0 0 280px;flex:0 0 280px}.section-container .section-header{border:none}.section-container .content-panel{width:100%;height:100%;margin:0;padding:0;border:none !important;display:-ms-flex;display:-webkit-flex;display:flex;-ms-flex-direction:row;-webkit-flex-direction:row;flex-direction:row;-ms-flex-wrap:nowrap;-webkit-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-justify-content:flex-start;justify-content:flex-start;-webkit-align-content:flex-start;align-content:flex-start;-webkit-align-items:stretch;align-items:stretch}.section-container .tab-container{border:none;display:none;list-style-type:none;padding:0;margin:0}.section-container .tab-container li{float:left;position:relative;top:0;padding:0;margin:0 1px 0px 0;border-top:1px solid #f3f1ef !important;border-bottom:1px solid #f3f1ef !important;background:#f3f1ef !important}.section-container .tab-container li a{top:0 !important;margin-bottom:0 !important;padding:6px 16px;text-decoration:none;min-height:32px;color:#222;float:left}.section-container .tab-container li.active,.section-container .tab-container li:hover{border-bottom-color:#4a86ad !important;border-top-color:#6e9ebd !important;background:#266d9c !important}.section-container .tab-container li.active a,.section-container .tab-container li:hover a{background:rgba(0,0,0,0) !important;border-color:rgba(0,0,0,0) !important;color:#fff !important;text-shadow:1px 1px 0 rgba(0,0,0,.2)}.section-container .tab-container li.disabled:hover{background:#f3f1ef !important}.section-container .tab-container li.disabled:hover a{cursor:not-allowed !important;color:#222 !important}.section-container .navi-container{display:none;background:#f3f1ef;-ms-order:0;-webkit-order:0;order:0;flex-item-align:stretch;-ms-flex-item-align:stretch;-webkit-align-self:stretch;align-self:stretch;-ms-flex:0 0 280px;-webkit-flex:0 0 280px;flex:0 0 280px;border-right:1px #ddd solid}.section-container .navi-container .block-title{font-size:14px;font-size:1.4rem;padding:2px 8px;margin:0}.section-container .navi-container .tree-action-bar-box{margin:10px 0;opacity:0}.section-container .navi-container .tree-action-bar-box.active{opacity:1;-webkit-opacity:0.25s ease-in-out;-moz-opacity:0.25s ease-in-out;opacity:0.25s ease-in-out}.section-container .content-container{border:none;-ms-order:0;-webkit-order:0;order:0;flex-item-align:stretch;-ms-flex-item-align:stretch;-webkit-align-self:stretch;align-self:stretch;-ms-flex:1 1 auto;-webkit-flex:1 1 auto;flex:1 1 auto;-ms-flex:1 1;-webkit-flex:1 1;flex:1 1;max-width:100%}.section-container .navi-container+.content-container{max-width:calc(100% - 280px)}.section-container .content-block{padding:20px;overflow-y:auto;display:-ms-flex;display:-webkit-flex;display:flex;-ms-flex-direction:row;-webkit-flex-direction:row;flex-direction:row;-ms-flex-wrap:wrap;-webkit-flex-wrap:wrap;flex-wrap:wrap;-webkit-justify-content:flex-start;justify-content:flex-start;-webkit-align-content:flex-start;align-content:flex-start;-webkit-align-items:stretch;align-items:stretch}.section-container .content-block>.grid-container{width:100%}.section-container .content-block .data-container-wrapper{padding:0px 20px 0 0}.section-container .content-block .data-container-wrapper:before,.section-container .content-block .data-container-wrapper:after{content:" ";display:table}.section-container .content-block .data-container-wrapper:after{clear:both}.section-container .content-block .data-container-wrapper>section,.section-container .content-block .data-container-wrapper .data-container{width:260px;margin:0 20px 20px 0;float:left;border:1px solid #ddd;border-radius:2px;-webkit-border-radius:2px}.section-container .content-block .data-container-wrapper>section.double,.section-container .content-block .data-container-wrapper .data-container.double{width:540px}.section-container .content-block .data-container-wrapper>section .emptyContentFooter,.section-container .content-block .data-container-wrapper .data-container .emptyContentFooter{display:none}.section-container .content-block .data-container-wrapper>section .tree,.section-container .content-block .data-container-wrapper .data-container .tree{border:none;max-width:none;max-height:none}.section-container .content-block .data-container-wrapper>section form,.section-container .content-block .data-container-wrapper .data-container form{background:none;border:none;margin:0;padding:0}.section-container .content-block .data-container-wrapper>section>header,.section-container .content-block .data-container-wrapper>section .ui-widget-header,.section-container .content-block .data-container-wrapper .data-container>header,.section-container .content-block .data-container-wrapper .data-container .ui-widget-header{background:#f3f1ef;border-width:0px !important;border-bottom:1px #ddd solid !important}.section-container .content-block .data-container-wrapper>section>header h1,.section-container .content-block .data-container-wrapper>section>header h6,.section-container .content-block .data-container-wrapper>section .ui-widget-header h1,.section-container .content-block .data-container-wrapper>section .ui-widget-header h6,.section-container .content-block .data-container-wrapper .data-container>header h1,.section-container .content-block .data-container-wrapper .data-container>header h6,.section-container .content-block .data-container-wrapper .data-container .ui-widget-header h1,.section-container .content-block .data-container-wrapper .data-container .ui-widget-header h6{padding:4px;margin:0;font-size:14px;font-size:1.4rem}.section-container .content-block .data-container-wrapper>section>div,.section-container .content-block .data-container-wrapper>section .ui-widget-content,.section-container .content-block .data-container-wrapper>section .container-content,.section-container .content-block .data-container-wrapper .data-container>div,.section-container .content-block .data-container-wrapper .data-container .ui-widget-content,.section-container .content-block .data-container-wrapper .data-container .container-content{border-width:0px !important;overflow-y:auto;min-height:250px;padding:5px}.section-container .content-block .data-container-wrapper>section>div .icon-grip,.section-container .content-block .data-container-wrapper>section .ui-widget-content .icon-grip,.section-container .content-block .data-container-wrapper>section .container-content .icon-grip,.section-container .content-block .data-container-wrapper .data-container>div .icon-grip,.section-container .content-block .data-container-wrapper .data-container .ui-widget-content .icon-grip,.section-container .content-block .data-container-wrapper .data-container .container-content .icon-grip{cursor:move}.section-container .content-block .data-container-wrapper>section>footer,.section-container .content-block .data-container-wrapper .data-container>footer{min-height:33px}.section-container .content-block .data-container-wrapper>section>footer,.section-container .content-block .data-container-wrapper>section .data-container-footer,.section-container .content-block .data-container-wrapper .data-container>footer,.section-container .content-block .data-container-wrapper .data-container .data-container-footer{background:#f3f1ef;text-align:right !important;padding:4px;border-width:0px !important;border-top:1px #ddd solid !important}.section-container .content-block .data-container-wrapper>section>footer .square,.section-container .content-block .data-container-wrapper>section .data-container-footer .square,.section-container .content-block .data-container-wrapper .data-container>footer .square,.section-container .content-block .data-container-wrapper .data-container .data-container-footer .square{width:28px}.section-container .content-block .data-container-wrapper>section>footer .square span,.section-container .content-block .data-container-wrapper>section .data-container-footer .square span,.section-container .content-block .data-container-wrapper .data-container>footer .square span,.section-container .content-block .data-container-wrapper .data-container .data-container-footer .square span{padding:0;left:0}.section-container .content-block .data-container-wrapper>section ol,.section-container .content-block .data-container-wrapper .data-container ol{margin:0 0 0 15px;padding:10px}.section-container .content-block #form-container.ui-widget-content{border:none !important}.section-container .content-block form:not(.list-container){border:1px #ddd solid;background:#f3f1ef;padding:30px;border:1px solid #ddd;border-radius:2px;-webkit-border-radius:2px}.section-container .content-block [class^=btn-],.section-container .content-block [class*=" btn-"]{margin:0 2px}.qti-navigator-default{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none;display:-ms-flex;display:-webkit-flex;display:flex;-ms-flex-direction:row;-webkit-flex-direction:row;flex-direction:row;-ms-flex-wrap:nowrap;-webkit-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-justify-content:flex-start;justify-content:flex-start;-webkit-align-content:flex-start;align-content:flex-start;-webkit-align-items:stretch;align-items:stretch;-webkit-flex-direction:column;-moz-flex-direction:column;-ms-flex-direction:column;-o-flex-direction:column;flex-direction:column;padding:0;cursor:default;min-width:calc(18rem - 8px);height:100%;position:relative}.qti-navigator-default span{display:inline-block}.qti-navigator-default .collapsed .collapsible-panel{display:none !important}.qti-navigator-default .collapsed .qti-navigator-label .icon-up{display:none}.qti-navigator-default .collapsed .qti-navigator-label .icon-down{display:inline-block}.qti-navigator-default .collapsible>.qti-navigator-label,.qti-navigator-default .qti-navigator-item>.qti-navigator-label{cursor:pointer}.qti-navigator-default.scope-test-section .qti-navigator-part>.qti-navigator-label{display:none !important}.qti-navigator-default .qti-navigator-label{display:-ms-flex;display:-webkit-flex;display:flex;-ms-flex-direction:row;-webkit-flex-direction:row;flex-direction:row;-ms-flex-wrap:nowrap;-webkit-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-justify-content:flex-start;justify-content:flex-start;-webkit-align-content:flex-start;align-content:flex-start;-webkit-align-items:stretch;align-items:stretch;min-width:calc(100% - 12px);padding:0 6px;line-height:3rem}.qti-navigator-default .qti-navigator-label .icon-up,.qti-navigator-default .qti-navigator-label .icon-down{line-height:3rem;margin-left:auto}.qti-navigator-default .qti-navigator-label .icon-down{display:none}.qti-navigator-default .qti-navigator-label .qti-navigator-number{display:none}.qti-navigator-default .qti-navigator-icon,.qti-navigator-default .icon{position:relative;top:1px;display:inline-block;line-height:2.8rem;margin-right:.5rem}.qti-navigator-default .unseen .qti-navigator-icon{cursor:default}.qti-navigator-default.prevents-unseen:not(.skipahead-enabled) .unseen .qti-navigator-icon,.qti-navigator-default.prevents-unseen:not(.skipahead-enabled) .unseen .qti-navigator-label{cursor:not-allowed !important}.qti-navigator-default .icon-answered:before{content:""}.qti-navigator-default .icon-viewed:before{content:""}.qti-navigator-default .icon-flagged:before{content:""}.qti-navigator-default .icon-unanswered:before,.qti-navigator-default .icon-unseen:before{content:""}.qti-navigator-default .qti-navigator-counter{text-align:right;margin-left:auto;font-size:12px;font-size:1.2rem}.qti-navigator-default .qti-navigator-actions{text-align:center}.qti-navigator-default .qti-navigator-info.collapsed{height:calc(3rem + 1px)}.qti-navigator-default .qti-navigator-info{height:calc(5*(3rem + 1px));overflow:hidden}.qti-navigator-default .qti-navigator-info>.qti-navigator-label{min-width:calc(100% - 16px);padding:0 8px}.qti-navigator-default .qti-navigator-info ul{padding:0 4px}.qti-navigator-default .qti-navigator-info ul .qti-navigator-label span.qti-navigator-text{padding:0 6px;min-width:10rem}.qti-navigator-default .qti-navigator-info ul .qti-navigator-label span.qti-navigator-icon{min-width:1.5rem}.qti-navigator-default .qti-navigator-info ul .qti-navigator-label span.qti-navigator-counter{min-width:5rem}.qti-navigator-default .qti-navigator-filters{margin-top:1rem;text-align:center;width:15rem;height:calc(3rem + 2*1px)}.qti-navigator-default .qti-navigator-filters ul{display:-ms-flex;display:-webkit-flex;display:flex;-ms-flex-direction:row;-webkit-flex-direction:row;flex-direction:row;-ms-flex-wrap:nowrap;-webkit-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-justify-content:flex-start;justify-content:flex-start;-webkit-align-content:flex-start;align-content:flex-start;-webkit-align-items:stretch;align-items:stretch}.qti-navigator-default .qti-navigator-filters li{display:block}.qti-navigator-default .qti-navigator-filters li .qti-navigator-tab{border:1px solid #ddd;border-radius:2px;-webkit-border-radius:2px;border-left:none;line-height:3rem;min-width:5rem;cursor:pointer;white-space:nowrap}.qti-navigator-default .qti-navigator-tree{-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1;overflow-y:auto}.qti-navigator-default .qti-navigator-linear,.qti-navigator-default .qti-navigator-linear-part{padding:8px}.qti-navigator-default .qti-navigator-linear .icon,.qti-navigator-default .qti-navigator-linear-part .icon{display:none}.qti-navigator-default .qti-navigator-linear .qti-navigator-label,.qti-navigator-default .qti-navigator-linear-part .qti-navigator-label{font-size:14px;font-size:1.4rem}.qti-navigator-default .qti-navigator-linear .qti-navigator-title,.qti-navigator-default .qti-navigator-linear-part .qti-navigator-title{font-size:14px;font-size:1.4rem;margin:8px 0}.qti-navigator-default .qti-navigator-linear .qti-navigator-message,.qti-navigator-default .qti-navigator-linear-part .qti-navigator-message{font-size:14px;font-size:1.4rem}.qti-navigator-default .qti-navigator-part>.qti-navigator-label{padding:0 8px}.qti-navigator-default .qti-navigator-part:not(:first-child){margin-top:1px}.qti-navigator-default .qti-navigator-section>.qti-navigator-label{padding:0 8px}.qti-navigator-default .qti-navigator-item{margin:1px 0;padding-left:10px}.qti-navigator-default .qti-navigator-item:first-child{margin-top:0}.qti-navigator-default .qti-navigator-item.disabled>.qti-navigator-label{cursor:not-allowed}.qti-navigator-default .qti-navigator-collapsible{cursor:pointer;text-align:center;display:none;position:absolute;top:0;bottom:0;right:0;padding-top:50%}.qti-navigator-default .qti-navigator-collapsible .icon{font-size:20px;font-size:2rem;width:1rem !important;height:2rem !important}.qti-navigator-default .qti-navigator-collapsible .qti-navigator-expand{display:none}.qti-navigator-default.collapsible{padding-right:calc(1rem + 10px) !important}.qti-navigator-default.collapsible .qti-navigator-collapsible{display:block}.qti-navigator-default.collapsed{width:calc(8rem + 1rem + 10px);min-width:8rem}.qti-navigator-default.collapsed ul{padding:0 !important}.qti-navigator-default.collapsed .qti-navigator-text,.qti-navigator-default.collapsed .qti-navigator-info>.qti-navigator-label,.qti-navigator-default.collapsed .qti-navigator-part>.qti-navigator-label,.qti-navigator-default.collapsed .qti-navigator-section>.qti-navigator-label,.qti-navigator-default.collapsed .qti-navigator-message{display:none !important}.qti-navigator-default.collapsed .qti-navigator-label{padding:0 2px !important;width:calc(8rem - 4px);min-width:calc(8rem - 4px)}.qti-navigator-default.collapsed .qti-navigator-icon,.qti-navigator-default.collapsed .icon{width:auto}.qti-navigator-default.collapsed .qti-navigator-counter{margin-left:0;min-width:4rem !important}.qti-navigator-default.collapsed .qti-navigator-collapsible .qti-navigator-collapse{display:none}.qti-navigator-default.collapsed .qti-navigator-collapsible .qti-navigator-expand{display:block}.qti-navigator-default.collapsed .qti-navigator-info{height:calc(4*(3rem + 1px))}.qti-navigator-default.collapsed .qti-navigator-info.collapsed .collapsible-panel{display:block !important}.qti-navigator-default.collapsed .qti-navigator-filters{width:calc(8rem - 16px)}.qti-navigator-default.collapsed .qti-navigator-filter span{display:none}.qti-navigator-default.collapsed .qti-navigator-filter.active span{display:block;border:0 none;width:calc(8rem - 16px)}.qti-navigator-default.collapsed .qti-navigator-item,.qti-navigator-default.collapsed .qti-navigator-linear,.qti-navigator-default.collapsed .qti-navigator-linear-part{padding-left:2px;text-align:center}.qti-navigator-default.collapsed .qti-navigator-item{overflow:hidden}.qti-navigator-default.collapsed .qti-navigator-item .qti-navigator-icon{padding-left:6px;width:2rem}.qti-navigator-default.collapsed .qti-navigator-item .qti-navigator-number{display:inline-block;margin-left:6px;margin-right:8rem}.qti-navigator-default.collapsed .qti-navigator-linear,.qti-navigator-default.collapsed .qti-navigator-linear-part{padding:0 0 8px 0}.qti-navigator-default.collapsed .qti-navigator-linear .icon,.qti-navigator-default.collapsed .qti-navigator-linear-part .icon{display:block}.qti-navigator-default.collapsed .qti-navigator-actions button{padding:0 9px 0 5px}.qti-navigator-default .qti-navigator-info>.qti-navigator-label{background-color:#d4d5d7;color:#222;border-top:1px solid #d4d5d7}.qti-navigator-default .qti-navigator-info li{border-bottom:1px solid #fff}.qti-navigator-default .qti-navigator-filter .qti-navigator-tab{background-color:#fff}.qti-navigator-default .qti-navigator-filter .qti-navigator-tab:hover{background-color:#3e7da7;color:#fff}.qti-navigator-default .qti-navigator-filter.active .qti-navigator-tab{background-color:#a4a9b1;color:#fff}.qti-navigator-default .qti-navigator-linear,.qti-navigator-default .qti-navigator-linear-part{background:#fff}.qti-navigator-default .qti-navigator-part>.qti-navigator-label{background-color:#dddfe2}.qti-navigator-default .qti-navigator-part>.qti-navigator-label:hover{background-color:#c6cacf}.qti-navigator-default .qti-navigator-part.active>.qti-navigator-label{background-color:#c0c4ca}.qti-navigator-default .qti-navigator-section>.qti-navigator-label{border-bottom:1px solid #fff}.qti-navigator-default .qti-navigator-section>.qti-navigator-label:hover{background-color:#ebe8e4}.qti-navigator-default .qti-navigator-section.active>.qti-navigator-label{background-color:#ded9d4}.qti-navigator-default .qti-navigator-item{background:#fff}.qti-navigator-default .qti-navigator-item.active{background:#0e5d91;color:#fff}.qti-navigator-default .qti-navigator-item:hover{background:#0a3f62;color:#fff}.qti-navigator-default .qti-navigator-item.disabled{background-color:#e2deda !important}.qti-navigator-default .qti-navigator-collapsible{background-color:#dfe1e4;color:#222}.qti-navigator-default .qti-navigator-collapsible .icon{color:#fff}.qti-test-scope .action-bar li{margin:0 5px}.qti-test-scope .action-bar li.btn-info{border-color:rgba(255,255,255,.3)}.qti-test-scope .action-bar li.btn-info.btn-group{border:none !important;overflow:hidden;padding:0}.qti-test-scope .action-bar li.btn-info.btn-group a{float:left;margin:0 2px;padding:0 15px;border:1px solid rgba(255,255,255,.3);border-radius:0px;display:inline-block;height:inherit}.qti-test-scope .action-bar li.btn-info.btn-group a:first-of-type{border-top-left-radius:3px;border-bottom-left-radius:3px;margin-left:0}.qti-test-scope .action-bar li.btn-info.btn-group a:last-of-type{border-top-right-radius:3px;border-bottom-right-radius:3px;margin-right:0}.qti-test-scope .action-bar li.btn-info.btn-group a:hover,.qti-test-scope .action-bar li.btn-info.btn-group a.active{border-color:rgba(255,255,255,.8)}.qti-test-scope .action-bar li.btn-info.btn-group a .no-label{padding-right:0}.qti-test-scope .action-bar li.btn-info:hover,.qti-test-scope .action-bar li.btn-info.active{border-color:rgba(255,255,255,.8)}.qti-test-scope .action-bar.horizontal-action-bar{opacity:0}.qti-test-scope .action-bar.horizontal-action-bar .title-box{padding-top:4px}.qti-test-scope .action-bar.horizontal-action-bar .progress-box,.qti-test-scope .action-bar.horizontal-action-bar .timer-box,.qti-test-scope .action-bar.horizontal-action-bar .item-number-box{padding-top:4px;display:inline-block;white-space:nowrap;-webkit-flex:0 0 auto;flex:0 1 auto}.qti-test-scope .action-bar.horizontal-action-bar .progress-box .qti-controls,.qti-test-scope .action-bar.horizontal-action-bar .timer-box .qti-controls,.qti-test-scope .action-bar.horizontal-action-bar .item-number-box .qti-controls{display:inline-block;margin-left:20px;white-space:nowrap}.qti-test-scope .action-bar.horizontal-action-bar .progressbar{margin-top:5px;min-width:150px;max-width:200px;height:.6em}.qti-test-scope .action-bar.horizontal-action-bar.top-action-bar>.control-box{display:-webkit-flex;-webkit-justify-content:space-between;-webkit-flex-flow:row nowrap;display:flex;justify-content:space-between;flex-flow:row nowrap}.qti-test-scope .action-bar.horizontal-action-bar>.control-box{color:rgba(255,255,255,.9);text-shadow:1px 1px 0 #000}.qti-test-scope .action-bar.horizontal-action-bar>.control-box .lft,.qti-test-scope .action-bar.horizontal-action-bar>.control-box .rgt{padding-left:20px}.qti-test-scope .action-bar.horizontal-action-bar>.control-box .lft:first-child,.qti-test-scope .action-bar.horizontal-action-bar>.control-box .rgt:first-child{padding-left:0}.qti-test-scope .action-bar.horizontal-action-bar>.control-box .lft:last-child ul,.qti-test-scope .action-bar.horizontal-action-bar>.control-box .rgt:last-child ul{display:inline-block}.qti-test-scope .action-bar.horizontal-action-bar>.control-box [class^=btn-],.qti-test-scope .action-bar.horizontal-action-bar>.control-box [class*=" btn-"]{white-space:nowrap}.qti-test-scope .action-bar.horizontal-action-bar .tools-box .action{position:relative;overflow:visible}.qti-test-scope .action-bar.horizontal-action-bar .tools-box .menu{color:#222;background:#f3f1ef;overflow:auto;list-style:none;min-width:150px;margin:0;padding:0;position:absolute;bottom:30px;left:0}.qti-test-scope .action-bar.horizontal-action-bar .tools-box .menu .action{display:inline-block;text-align:left;width:100%;white-space:nowrap;overflow:hidden;color:#222;margin:0;-moz-border-radius:0px;-webkit-border-radius:0px;border-radius:0px;height:32px;padding:6px 15px;line-height:1}.qti-test-scope .action-bar.horizontal-action-bar .tools-box .menu .action.selected{background-color:#3e7da7;color:#fff}.qti-test-scope .action-bar.horizontal-action-bar .tools-box .menu .action.selected .label,.qti-test-scope .action-bar.horizontal-action-bar .tools-box .menu .action.selected .icon{color:#fff}.qti-test-scope .action-bar.horizontal-action-bar .tools-box .menu .action:hover{background-color:#0e5d91;color:#fff}.qti-test-scope .action-bar.horizontal-action-bar .tools-box .menu .action:hover .label,.qti-test-scope .action-bar.horizontal-action-bar .tools-box .menu .action:hover .icon{color:#fff}.qti-test-scope .action-bar.horizontal-action-bar .tools-box .menu .action .label,.qti-test-scope .action-bar.horizontal-action-bar .tools-box .menu .action .icon{font-size:14px;font-size:1.4rem;text-shadow:none;color:#222}.qti-test-scope .action-bar.horizontal-action-bar.bottom-action-bar{overflow:visible}.qti-test-scope .action-bar.horizontal-action-bar.bottom-action-bar .action{line-height:1.6}.qti-test-scope .action-bar.horizontal-action-bar.has-timers{height:47px}.qti-test-scope .action-bar.horizontal-action-bar.has-timers .progress-box,.qti-test-scope .action-bar.horizontal-action-bar.has-timers .title-box{padding-top:10px}.qti-test-scope .action-bar.horizontal-action-bar .bottom-action-bar .action{display:none}.qti-test-scope .test-sidebar{background:#f3f1ef;overflow:auto}.qti-test-scope .test-sidebar-left{border-right:1px #ddd solid}.qti-test-scope .test-sidebar-right{border-left:1px #ddd solid}.qti-test-scope .content-panel{height:auto !important}.qti-test-scope .content-panel #qti-content{-webkit-overflow-scrolling:touch;overflow-y:auto;font-size:0}.qti-test-scope .content-panel #qti-content #qti-rubrics{font-size:14px}.qti-test-scope #qti-item{width:100%;min-width:100%;height:auto;overflow:visible}.qti-test-scope .size-wrapper{max-width:1280px;margin:auto;width:100%}.qti-test-scope .tools-box{position:relative;overflow:visible}.qti-test-scope [data-control=qti-comment]{background-color:#f3f1ef;position:absolute;bottom:33px;left:8px;z-index:9999;text-align:right;padding:5px;border:1px solid #ddd;border-radius:2px;-webkit-border-radius:2px;-webkit-box-shadow:0 0 15px 1px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 0 15px 1px rgba(0, 0, 0, 0.2);-ms-box-shadow:0 0 15px 1px rgba(0, 0, 0, 0.2);-o-box-shadow:0 0 15px 1px rgba(0, 0, 0, 0.2);box-shadow:0 0 15px 1px rgba(0, 0, 0, 0.2)}.qti-test-scope [data-control=qti-comment] textarea{display:block;height:100px;resize:none;width:350px;padding:3px;margin:0 0 10px 0;border:none;font-size:13px;font-size:1.3rem;border:1px solid #ddd;border-radius:2px;-webkit-border-radius:2px}.qti-test-scope #qti-timers{display:none}.qti-test-scope [data-control=exit]{margin-left:20px}.qti-test-scope [data-control=comment-toggle]{display:none}.qti-test-scope .qti-timer{display:inline-block;text-align:center;vertical-align:top;line-height:1.2;position:relative;padding:0 20px}.qti-test-scope .qti-timer .qti-timer_label{max-width:130px;font-size:12px;font-size:1.2rem}.qti-test-scope .qti-timer::before{content:" ";background:rgba(255,255,255,.3);width:1px;height:20px;position:absolute;left:0;top:5px}.qti-test-scope .qti-timer:first-child::before{content:none}.qti-test-scope.non-lti-context .title-box{display:none}.qti-test-scope #qti-rubrics{margin:auto;max-width:1024px;width:100%;padding:15px}.qti-test-scope #qti-rubrics .qti-rubricBlock{margin:20px 0}.qti-test-scope #qti-rubrics .hidden{display:none} +@-o-keyframes loadingbar{0%{left:-10%}50%{left:90%}100%{left:-10%}}@-moz-keyframes loadingbar{0%{left:-10%}50%{left:90%}100%{left:-10%}}@-webkit-keyframes loadingbar{0%{left:-10%}50%{left:90%}100%{left:-10%}}@keyframes loadingbar{0%{left:-10%}50%{left:90%}100%{left:-10%}}.loading-bar{height:6px;position:absolute;width:100%;top:0px;display:none;z-index:10000;cursor:progress}.loading-bar.fixed{position:fixed;width:100%}.loading-bar.fixed:before{top:0 !important}.loading-bar.loading{display:block;overflow:hidden;top:58px}.loading-bar.loading:before{position:absolute;content:"";height:6px;width:20%;display:block;transform:translateZ(0);background:-webkit-linear-gradient(to right, transparent 0%, rgb(195, 90, 19) 20%, rgb(195, 90, 19) 80%, transparent 100%);background:-moz-linear-gradient(to right, transparent 0%, rgb(195, 90, 19) 20%, rgb(195, 90, 19) 80%, transparent 100%);background:-ms-linear-gradient(to right, transparent 0%, rgb(195, 90, 19) 20%, rgb(195, 90, 19) 80%, transparent 100%);background:-o-linear-gradient(to right, transparent 0%, rgb(195, 90, 19) 20%, rgb(195, 90, 19) 80%, transparent 100%);background:linear-gradient(to right, transparent 0%, rgb(195, 90, 19) 20%, rgb(195, 90, 19) 80%, transparent 100%);-webkit-animation:loadingbar 5s linear infinite;-moz-animation:loadingbar 5s linear infinite;-ms-animation:loadingbar 5s linear infinite;-o-animation:loadingbar 5s linear infinite;animation:loadingbar 5s linear infinite}.loading-bar.loading.loadingbar-covered{top:0px;overflow-y:visible}.loading-bar.loading.loadingbar-covered:before{top:86px}.no-version-warning .loading-bar.loadingbar-covered:before{top:58px}.section-container{top:0 !important}.section-container .flex-container-full{-ms-order:0;-webkit-order:0;order:0;flex-item-align:stretch;-ms-flex-item-align:stretch;-webkit-align-self:stretch;align-self:stretch;-ms-flex:0 0 100%;-webkit-flex:0 0 100%;flex:0 0 100%}.section-container .flex-container-half{-ms-order:0;-webkit-order:0;order:0;flex-item-align:stretch;-ms-flex-item-align:stretch;-webkit-align-self:stretch;align-self:stretch;-ms-flex:0 0 50%;-webkit-flex:0 0 50%;flex:0 0 50%}.section-container .flex-container-third{-ms-order:0;-webkit-order:0;order:0;flex-item-align:stretch;-ms-flex-item-align:stretch;-webkit-align-self:stretch;align-self:stretch;-ms-flex:0 0 33.3333333333%;-webkit-flex:0 0 33.3333333333%;flex:0 0 33.3333333333%}.section-container .flex-container-quarter{-ms-order:0;-webkit-order:0;order:0;flex-item-align:stretch;-ms-flex-item-align:stretch;-webkit-align-self:stretch;align-self:stretch;-ms-flex:0 0 25%;-webkit-flex:0 0 25%;flex:0 0 25%}.section-container .flex-container-remaining{-ms-order:0;-webkit-order:0;order:0;flex-item-align:stretch;-ms-flex-item-align:stretch;-webkit-align-self:stretch;align-self:stretch;-ms-flex:1 1 480px;-webkit-flex:1 1 480px;flex:1 1 480px}.section-container .flex-container-main-form{-ms-order:0;-webkit-order:0;order:0;flex-item-align:stretch;-ms-flex-item-align:stretch;-webkit-align-self:stretch;align-self:stretch;-ms-flex:0 0 500px;-webkit-flex:0 0 500px;flex:0 0 500px;margin:0 20px 20px 0;width:100%}.section-container .flex-container-main-form .form-content{max-width:100%}.section-container .flex-container-navi{-ms-order:0;-webkit-order:0;order:0;flex-item-align:stretch;-ms-flex-item-align:stretch;-webkit-align-self:stretch;align-self:stretch;-ms-flex:0 0 380px;-webkit-flex:0 0 380px;flex:0 0 380px}.section-container .section-header{border:none}.section-container .content-panel{width:100%;height:100%;margin:0;padding:0;border:none !important;display:-ms-flex;display:-webkit-flex;display:flex;-ms-flex-direction:row;-webkit-flex-direction:row;flex-direction:row;-ms-flex-wrap:nowrap;-webkit-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-justify-content:flex-start;justify-content:flex-start;-webkit-align-content:flex-start;align-content:flex-start;-webkit-align-items:stretch;align-items:stretch}.section-container .tab-container{border:none;display:none;list-style-type:none;padding:0;margin:0}.section-container .tab-container li{float:left;position:relative;top:0;padding:0;margin:0 1px 0px 0;border-top:1px solid #f3f1ef !important;border-bottom:1px solid #f3f1ef !important;background:#f3f1ef !important}.section-container .tab-container li a{top:0 !important;margin-bottom:0 !important;padding:6px 16px;text-decoration:none;min-height:32px;color:#222;float:left}.section-container .tab-container li.active,.section-container .tab-container li:hover{border-bottom-color:#4a86ad !important;border-top-color:#6e9ebd !important;background:#266d9c !important}.section-container .tab-container li.active a,.section-container .tab-container li:hover a{background:rgba(0,0,0,0) !important;border-color:rgba(0,0,0,0) !important;color:#fff !important;text-shadow:1px 1px 0 rgba(0,0,0,.2)}.section-container .tab-container li.disabled:hover{background:#f3f1ef !important}.section-container .tab-container li.disabled:hover a{cursor:not-allowed !important;color:#222 !important}.section-container .navi-container{display:none;background:#f3f1ef;-ms-order:0;-webkit-order:0;order:0;flex-item-align:stretch;-ms-flex-item-align:stretch;-webkit-align-self:stretch;align-self:stretch;-ms-flex:0 0 380px;-webkit-flex:0 0 380px;flex:0 0 380px;border-right:1px #ddd solid}.section-container .navi-container .block-title{font-size:14px;font-size:1.4rem;padding:2px 8px;margin:0}.section-container .navi-container .tree-action-bar-box{margin:10px 0;opacity:0}.section-container .navi-container .tree-action-bar-box.active{opacity:1;-webkit-opacity:0.25s ease-in-out;-moz-opacity:0.25s ease-in-out;opacity:0.25s ease-in-out}.section-container .content-container{border:none;-ms-order:0;-webkit-order:0;order:0;flex-item-align:stretch;-ms-flex-item-align:stretch;-webkit-align-self:stretch;align-self:stretch;-ms-flex:1 1 auto;-webkit-flex:1 1 auto;flex:1 1 auto;-ms-flex:1 1;-webkit-flex:1 1;flex:1 1;max-width:100%}.section-container .navi-container+.content-container{max-width:calc(100% - 380px)}.section-container .content-block{padding:20px;overflow-y:auto;display:-ms-flex;display:-webkit-flex;display:flex;-ms-flex-direction:row;-webkit-flex-direction:row;flex-direction:row;-ms-flex-wrap:wrap;-webkit-flex-wrap:wrap;flex-wrap:wrap;-webkit-justify-content:flex-start;justify-content:flex-start;-webkit-align-content:flex-start;align-content:flex-start;-webkit-align-items:stretch;align-items:stretch}.section-container .content-block>.grid-container{width:100%}.section-container .content-block .data-container-wrapper{padding:0px 20px 0 0}.section-container .content-block .data-container-wrapper:before,.section-container .content-block .data-container-wrapper:after{content:" ";display:table}.section-container .content-block .data-container-wrapper:after{clear:both}.section-container .content-block .data-container-wrapper>section,.section-container .content-block .data-container-wrapper .data-container{width:260px;margin:0 20px 20px 0;float:left;border:1px solid #ddd;border-radius:2px;-webkit-border-radius:2px}.section-container .content-block .data-container-wrapper>section.double,.section-container .content-block .data-container-wrapper .data-container.double{width:540px}.section-container .content-block .data-container-wrapper>section .emptyContentFooter,.section-container .content-block .data-container-wrapper .data-container .emptyContentFooter{display:none}.section-container .content-block .data-container-wrapper>section .tree,.section-container .content-block .data-container-wrapper .data-container .tree{border:none;max-width:none;max-height:none}.section-container .content-block .data-container-wrapper>section form,.section-container .content-block .data-container-wrapper .data-container form{background:none;border:none;margin:0;padding:0}.section-container .content-block .data-container-wrapper>section>header,.section-container .content-block .data-container-wrapper>section .ui-widget-header,.section-container .content-block .data-container-wrapper .data-container>header,.section-container .content-block .data-container-wrapper .data-container .ui-widget-header{background:#f3f1ef;border-width:0px !important;border-bottom:1px #ddd solid !important}.section-container .content-block .data-container-wrapper>section>header h1,.section-container .content-block .data-container-wrapper>section>header h6,.section-container .content-block .data-container-wrapper>section .ui-widget-header h1,.section-container .content-block .data-container-wrapper>section .ui-widget-header h6,.section-container .content-block .data-container-wrapper .data-container>header h1,.section-container .content-block .data-container-wrapper .data-container>header h6,.section-container .content-block .data-container-wrapper .data-container .ui-widget-header h1,.section-container .content-block .data-container-wrapper .data-container .ui-widget-header h6{padding:4px;margin:0;font-size:14px;font-size:1.4rem}.section-container .content-block .data-container-wrapper>section>div,.section-container .content-block .data-container-wrapper>section .ui-widget-content,.section-container .content-block .data-container-wrapper>section .container-content,.section-container .content-block .data-container-wrapper .data-container>div,.section-container .content-block .data-container-wrapper .data-container .ui-widget-content,.section-container .content-block .data-container-wrapper .data-container .container-content{border-width:0px !important;overflow-y:auto;min-height:250px;padding:5px}.section-container .content-block .data-container-wrapper>section>div .icon-grip,.section-container .content-block .data-container-wrapper>section .ui-widget-content .icon-grip,.section-container .content-block .data-container-wrapper>section .container-content .icon-grip,.section-container .content-block .data-container-wrapper .data-container>div .icon-grip,.section-container .content-block .data-container-wrapper .data-container .ui-widget-content .icon-grip,.section-container .content-block .data-container-wrapper .data-container .container-content .icon-grip{cursor:move}.section-container .content-block .data-container-wrapper>section>footer,.section-container .content-block .data-container-wrapper .data-container>footer{min-height:33px}.section-container .content-block .data-container-wrapper>section>footer,.section-container .content-block .data-container-wrapper>section .data-container-footer,.section-container .content-block .data-container-wrapper .data-container>footer,.section-container .content-block .data-container-wrapper .data-container .data-container-footer{background:#f3f1ef;text-align:right !important;padding:4px;border-width:0px !important;border-top:1px #ddd solid !important}.section-container .content-block .data-container-wrapper>section>footer .square,.section-container .content-block .data-container-wrapper>section .data-container-footer .square,.section-container .content-block .data-container-wrapper .data-container>footer .square,.section-container .content-block .data-container-wrapper .data-container .data-container-footer .square{width:28px}.section-container .content-block .data-container-wrapper>section>footer .square span,.section-container .content-block .data-container-wrapper>section .data-container-footer .square span,.section-container .content-block .data-container-wrapper .data-container>footer .square span,.section-container .content-block .data-container-wrapper .data-container .data-container-footer .square span{padding:0;left:0}.section-container .content-block .data-container-wrapper>section ol,.section-container .content-block .data-container-wrapper .data-container ol{margin:0 0 0 15px;padding:10px}.section-container .content-block #form-container.ui-widget-content{border:none !important}.section-container .content-block form:not(.list-container){border:1px #ddd solid;background:#f3f1ef;padding:30px;border:1px solid #ddd;border-radius:2px;-webkit-border-radius:2px}.section-container .content-block [class^=btn-],.section-container .content-block [class*=" btn-"]{margin:0 2px}.qti-navigator-default{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none;display:-ms-flex;display:-webkit-flex;display:flex;-ms-flex-direction:row;-webkit-flex-direction:row;flex-direction:row;-ms-flex-wrap:nowrap;-webkit-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-justify-content:flex-start;justify-content:flex-start;-webkit-align-content:flex-start;align-content:flex-start;-webkit-align-items:stretch;align-items:stretch;-webkit-flex-direction:column;-moz-flex-direction:column;-ms-flex-direction:column;-o-flex-direction:column;flex-direction:column;padding:0;cursor:default;min-width:calc(18rem - 8px);height:100%;position:relative}.qti-navigator-default span{display:inline-block}.qti-navigator-default .collapsed .collapsible-panel{display:none !important}.qti-navigator-default .collapsed .qti-navigator-label .icon-up{display:none}.qti-navigator-default .collapsed .qti-navigator-label .icon-down{display:inline-block}.qti-navigator-default .collapsible>.qti-navigator-label,.qti-navigator-default .qti-navigator-item>.qti-navigator-label{cursor:pointer}.qti-navigator-default.scope-test-section .qti-navigator-part>.qti-navigator-label{display:none !important}.qti-navigator-default .qti-navigator-label{display:-ms-flex;display:-webkit-flex;display:flex;-ms-flex-direction:row;-webkit-flex-direction:row;flex-direction:row;-ms-flex-wrap:nowrap;-webkit-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-justify-content:flex-start;justify-content:flex-start;-webkit-align-content:flex-start;align-content:flex-start;-webkit-align-items:stretch;align-items:stretch;min-width:calc(100% - 12px);padding:0 6px;line-height:3rem}.qti-navigator-default .qti-navigator-label .icon-up,.qti-navigator-default .qti-navigator-label .icon-down{line-height:3rem;margin-left:auto}.qti-navigator-default .qti-navigator-label .icon-down{display:none}.qti-navigator-default .qti-navigator-label .qti-navigator-number{display:none}.qti-navigator-default .qti-navigator-icon,.qti-navigator-default .icon{position:relative;top:1px;display:inline-block;line-height:2.8rem;margin-right:.5rem}.qti-navigator-default .unseen .qti-navigator-icon{cursor:default}.qti-navigator-default.prevents-unseen:not(.skipahead-enabled) .unseen .qti-navigator-icon,.qti-navigator-default.prevents-unseen:not(.skipahead-enabled) .unseen .qti-navigator-label{cursor:not-allowed !important}.qti-navigator-default .icon-answered:before{content:""}.qti-navigator-default .icon-viewed:before{content:""}.qti-navigator-default .icon-flagged:before{content:""}.qti-navigator-default .icon-unanswered:before,.qti-navigator-default .icon-unseen:before{content:""}.qti-navigator-default .qti-navigator-counter{text-align:right;margin-left:auto;font-size:12px;font-size:1.2rem}.qti-navigator-default .qti-navigator-actions{text-align:center}.qti-navigator-default .qti-navigator-info.collapsed{height:calc(3rem + 1px)}.qti-navigator-default .qti-navigator-info{height:calc(5*(3rem + 1px));overflow:hidden}.qti-navigator-default .qti-navigator-info>.qti-navigator-label{min-width:calc(100% - 16px);padding:0 8px}.qti-navigator-default .qti-navigator-info ul{padding:0 4px}.qti-navigator-default .qti-navigator-info ul .qti-navigator-label span.qti-navigator-text{padding:0 6px;min-width:10rem}.qti-navigator-default .qti-navigator-info ul .qti-navigator-label span.qti-navigator-icon{min-width:1.5rem}.qti-navigator-default .qti-navigator-info ul .qti-navigator-label span.qti-navigator-counter{min-width:5rem}.qti-navigator-default .qti-navigator-filters{margin-top:1rem;text-align:center;width:15rem;height:calc(3rem + 2*1px)}.qti-navigator-default .qti-navigator-filters ul{display:-ms-flex;display:-webkit-flex;display:flex;-ms-flex-direction:row;-webkit-flex-direction:row;flex-direction:row;-ms-flex-wrap:nowrap;-webkit-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-justify-content:flex-start;justify-content:flex-start;-webkit-align-content:flex-start;align-content:flex-start;-webkit-align-items:stretch;align-items:stretch}.qti-navigator-default .qti-navigator-filters li{display:block}.qti-navigator-default .qti-navigator-filters li .qti-navigator-tab{border:1px solid #ddd;border-radius:2px;-webkit-border-radius:2px;border-left:none;line-height:3rem;min-width:5rem;cursor:pointer;white-space:nowrap}.qti-navigator-default .qti-navigator-tree{-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1;overflow-y:auto}.qti-navigator-default .qti-navigator-linear,.qti-navigator-default .qti-navigator-linear-part{padding:8px}.qti-navigator-default .qti-navigator-linear .icon,.qti-navigator-default .qti-navigator-linear-part .icon{display:none}.qti-navigator-default .qti-navigator-linear .qti-navigator-label,.qti-navigator-default .qti-navigator-linear-part .qti-navigator-label{font-size:14px;font-size:1.4rem}.qti-navigator-default .qti-navigator-linear .qti-navigator-title,.qti-navigator-default .qti-navigator-linear-part .qti-navigator-title{font-size:14px;font-size:1.4rem;margin:8px 0}.qti-navigator-default .qti-navigator-linear .qti-navigator-message,.qti-navigator-default .qti-navigator-linear-part .qti-navigator-message{font-size:14px;font-size:1.4rem}.qti-navigator-default .qti-navigator-part>.qti-navigator-label{padding:0 8px}.qti-navigator-default .qti-navigator-part:not(:first-child){margin-top:1px}.qti-navigator-default .qti-navigator-section>.qti-navigator-label{padding:0 8px}.qti-navigator-default .qti-navigator-item{margin:1px 0;padding-left:10px}.qti-navigator-default .qti-navigator-item:first-child{margin-top:0}.qti-navigator-default .qti-navigator-item.disabled>.qti-navigator-label{cursor:not-allowed}.qti-navigator-default .qti-navigator-collapsible{cursor:pointer;text-align:center;display:none;position:absolute;top:0;bottom:0;right:0;padding-top:50%}.qti-navigator-default .qti-navigator-collapsible .icon{font-size:20px;font-size:2rem;width:1rem !important;height:2rem !important}.qti-navigator-default .qti-navigator-collapsible .qti-navigator-expand{display:none}.qti-navigator-default.collapsible{padding-right:calc(1rem + 10px) !important}.qti-navigator-default.collapsible .qti-navigator-collapsible{display:block}.qti-navigator-default.collapsed{width:calc(8rem + 1rem + 10px);min-width:8rem}.qti-navigator-default.collapsed ul{padding:0 !important}.qti-navigator-default.collapsed .qti-navigator-text,.qti-navigator-default.collapsed .qti-navigator-info>.qti-navigator-label,.qti-navigator-default.collapsed .qti-navigator-part>.qti-navigator-label,.qti-navigator-default.collapsed .qti-navigator-section>.qti-navigator-label,.qti-navigator-default.collapsed .qti-navigator-message{display:none !important}.qti-navigator-default.collapsed .qti-navigator-label{padding:0 2px !important;width:calc(8rem - 4px);min-width:calc(8rem - 4px)}.qti-navigator-default.collapsed .qti-navigator-icon,.qti-navigator-default.collapsed .icon{width:auto}.qti-navigator-default.collapsed .qti-navigator-counter{margin-left:0;min-width:4rem !important}.qti-navigator-default.collapsed .qti-navigator-collapsible .qti-navigator-collapse{display:none}.qti-navigator-default.collapsed .qti-navigator-collapsible .qti-navigator-expand{display:block}.qti-navigator-default.collapsed .qti-navigator-info{height:calc(4*(3rem + 1px))}.qti-navigator-default.collapsed .qti-navigator-info.collapsed .collapsible-panel{display:block !important}.qti-navigator-default.collapsed .qti-navigator-filters{width:calc(8rem - 16px)}.qti-navigator-default.collapsed .qti-navigator-filter span{display:none}.qti-navigator-default.collapsed .qti-navigator-filter.active span{display:block;border:0 none;width:calc(8rem - 16px)}.qti-navigator-default.collapsed .qti-navigator-item,.qti-navigator-default.collapsed .qti-navigator-linear,.qti-navigator-default.collapsed .qti-navigator-linear-part{padding-left:2px;text-align:center}.qti-navigator-default.collapsed .qti-navigator-item{overflow:hidden}.qti-navigator-default.collapsed .qti-navigator-item .qti-navigator-icon{padding-left:6px;width:2rem}.qti-navigator-default.collapsed .qti-navigator-item .qti-navigator-number{display:inline-block;margin-left:6px;margin-right:8rem}.qti-navigator-default.collapsed .qti-navigator-linear,.qti-navigator-default.collapsed .qti-navigator-linear-part{padding:0 0 8px 0}.qti-navigator-default.collapsed .qti-navigator-linear .icon,.qti-navigator-default.collapsed .qti-navigator-linear-part .icon{display:block}.qti-navigator-default.collapsed .qti-navigator-actions button{padding:0 9px 0 5px}.qti-navigator-default .qti-navigator-info>.qti-navigator-label{background-color:#d4d5d7;color:#222;border-top:1px solid #d4d5d7}.qti-navigator-default .qti-navigator-info li{border-bottom:1px solid #fff}.qti-navigator-default .qti-navigator-filter .qti-navigator-tab{background-color:#fff}.qti-navigator-default .qti-navigator-filter .qti-navigator-tab:hover{background-color:#3e7da7;color:#fff}.qti-navigator-default .qti-navigator-filter.active .qti-navigator-tab{background-color:#a4a9b1;color:#fff}.qti-navigator-default .qti-navigator-linear,.qti-navigator-default .qti-navigator-linear-part{background:#fff}.qti-navigator-default .qti-navigator-part>.qti-navigator-label{background-color:#dddfe2}.qti-navigator-default .qti-navigator-part>.qti-navigator-label:hover{background-color:#c6cacf}.qti-navigator-default .qti-navigator-part.active>.qti-navigator-label{background-color:#c0c4ca}.qti-navigator-default .qti-navigator-section>.qti-navigator-label{border-bottom:1px solid #fff}.qti-navigator-default .qti-navigator-section>.qti-navigator-label:hover{background-color:#ebe8e4}.qti-navigator-default .qti-navigator-section.active>.qti-navigator-label{background-color:#ded9d4}.qti-navigator-default .qti-navigator-item{background:#fff}.qti-navigator-default .qti-navigator-item.active{background:#0e5d91;color:#fff}.qti-navigator-default .qti-navigator-item:hover{background:#0a3f62;color:#fff}.qti-navigator-default .qti-navigator-item.disabled{background-color:#e2deda !important}.qti-navigator-default .qti-navigator-collapsible{background-color:#dfe1e4;color:#222}.qti-navigator-default .qti-navigator-collapsible .icon{color:#fff}.qti-test-scope .action-bar li{margin:0 5px}.qti-test-scope .action-bar li.btn-info{border-color:rgba(255,255,255,.3)}.qti-test-scope .action-bar li.btn-info.btn-group{border:none !important;overflow:hidden;padding:0}.qti-test-scope .action-bar li.btn-info.btn-group a{float:left;margin:0 2px;padding:0 15px;border:1px solid rgba(255,255,255,.3);border-radius:0px;display:inline-block;height:inherit}.qti-test-scope .action-bar li.btn-info.btn-group a:first-of-type{border-top-left-radius:3px;border-bottom-left-radius:3px;margin-left:0}.qti-test-scope .action-bar li.btn-info.btn-group a:last-of-type{border-top-right-radius:3px;border-bottom-right-radius:3px;margin-right:0}.qti-test-scope .action-bar li.btn-info.btn-group a:hover,.qti-test-scope .action-bar li.btn-info.btn-group a.active{border-color:rgba(255,255,255,.8)}.qti-test-scope .action-bar li.btn-info.btn-group a .no-label{padding-right:0}.qti-test-scope .action-bar li.btn-info:hover,.qti-test-scope .action-bar li.btn-info.active{border-color:rgba(255,255,255,.8)}.qti-test-scope .action-bar.horizontal-action-bar{opacity:0}.qti-test-scope .action-bar.horizontal-action-bar .title-box{padding-top:4px}.qti-test-scope .action-bar.horizontal-action-bar .progress-box,.qti-test-scope .action-bar.horizontal-action-bar .timer-box,.qti-test-scope .action-bar.horizontal-action-bar .item-number-box{padding-top:4px;display:inline-block;white-space:nowrap;-webkit-flex:0 0 auto;flex:0 1 auto}.qti-test-scope .action-bar.horizontal-action-bar .progress-box .qti-controls,.qti-test-scope .action-bar.horizontal-action-bar .timer-box .qti-controls,.qti-test-scope .action-bar.horizontal-action-bar .item-number-box .qti-controls{display:inline-block;margin-left:20px;white-space:nowrap}.qti-test-scope .action-bar.horizontal-action-bar .progressbar{margin-top:5px;min-width:150px;max-width:200px;height:.6em}.qti-test-scope .action-bar.horizontal-action-bar.top-action-bar>.control-box{display:-webkit-flex;-webkit-justify-content:space-between;-webkit-flex-flow:row nowrap;display:flex;justify-content:space-between;flex-flow:row nowrap}.qti-test-scope .action-bar.horizontal-action-bar>.control-box{color:rgba(255,255,255,.9);text-shadow:1px 1px 0 #000}.qti-test-scope .action-bar.horizontal-action-bar>.control-box .lft,.qti-test-scope .action-bar.horizontal-action-bar>.control-box .rgt{padding-left:20px}.qti-test-scope .action-bar.horizontal-action-bar>.control-box .lft:first-child,.qti-test-scope .action-bar.horizontal-action-bar>.control-box .rgt:first-child{padding-left:0}.qti-test-scope .action-bar.horizontal-action-bar>.control-box .lft:last-child ul,.qti-test-scope .action-bar.horizontal-action-bar>.control-box .rgt:last-child ul{display:inline-block}.qti-test-scope .action-bar.horizontal-action-bar>.control-box [class^=btn-],.qti-test-scope .action-bar.horizontal-action-bar>.control-box [class*=" btn-"]{white-space:nowrap}.qti-test-scope .action-bar.horizontal-action-bar .tools-box .action{position:relative;overflow:visible}.qti-test-scope .action-bar.horizontal-action-bar .tools-box .menu{color:#222;background:#f3f1ef;overflow:auto;list-style:none;min-width:150px;margin:0;padding:0;position:absolute;bottom:30px;left:0}.qti-test-scope .action-bar.horizontal-action-bar .tools-box .menu .action{display:inline-block;text-align:left;width:100%;white-space:nowrap;overflow:hidden;color:#222;margin:0;-moz-border-radius:0px;-webkit-border-radius:0px;border-radius:0px;height:32px;padding:6px 15px;line-height:1}.qti-test-scope .action-bar.horizontal-action-bar .tools-box .menu .action.selected{background-color:#3e7da7;color:#fff}.qti-test-scope .action-bar.horizontal-action-bar .tools-box .menu .action.selected .label,.qti-test-scope .action-bar.horizontal-action-bar .tools-box .menu .action.selected .icon{color:#fff}.qti-test-scope .action-bar.horizontal-action-bar .tools-box .menu .action:hover{background-color:#0e5d91;color:#fff}.qti-test-scope .action-bar.horizontal-action-bar .tools-box .menu .action:hover .label,.qti-test-scope .action-bar.horizontal-action-bar .tools-box .menu .action:hover .icon{color:#fff}.qti-test-scope .action-bar.horizontal-action-bar .tools-box .menu .action .label,.qti-test-scope .action-bar.horizontal-action-bar .tools-box .menu .action .icon{font-size:14px;font-size:1.4rem;text-shadow:none;color:#222}.qti-test-scope .action-bar.horizontal-action-bar.bottom-action-bar{overflow:visible}.qti-test-scope .action-bar.horizontal-action-bar.bottom-action-bar .action{line-height:1.6}.qti-test-scope .action-bar.horizontal-action-bar.has-timers{height:47px}.qti-test-scope .action-bar.horizontal-action-bar.has-timers .progress-box,.qti-test-scope .action-bar.horizontal-action-bar.has-timers .title-box{padding-top:10px}.qti-test-scope .action-bar.horizontal-action-bar .bottom-action-bar .action{display:none}.qti-test-scope .test-sidebar{background:#f3f1ef;overflow:auto}.qti-test-scope .test-sidebar-left{border-right:1px #ddd solid}.qti-test-scope .test-sidebar-right{border-left:1px #ddd solid}.qti-test-scope .content-panel{height:auto !important}.qti-test-scope .content-panel #qti-content{-webkit-overflow-scrolling:touch;overflow-y:auto;font-size:0}.qti-test-scope .content-panel #qti-content #qti-rubrics{font-size:14px}.qti-test-scope #qti-item{width:100%;min-width:100%;height:auto;overflow:visible}.qti-test-scope .size-wrapper{max-width:1280px;margin:auto;width:100%}.qti-test-scope .tools-box{position:relative;overflow:visible}.qti-test-scope [data-control=qti-comment]{background-color:#f3f1ef;position:absolute;bottom:33px;left:8px;z-index:9999;text-align:right;padding:5px;border:1px solid #ddd;border-radius:2px;-webkit-border-radius:2px;-webkit-box-shadow:0 0 15px 1px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 0 15px 1px rgba(0, 0, 0, 0.2);-ms-box-shadow:0 0 15px 1px rgba(0, 0, 0, 0.2);-o-box-shadow:0 0 15px 1px rgba(0, 0, 0, 0.2);box-shadow:0 0 15px 1px rgba(0, 0, 0, 0.2)}.qti-test-scope [data-control=qti-comment] textarea{display:block;height:100px;resize:none;width:350px;padding:3px;margin:0 0 10px 0;border:none;font-size:13px;font-size:1.3rem;border:1px solid #ddd;border-radius:2px;-webkit-border-radius:2px}.qti-test-scope #qti-timers{display:none}.qti-test-scope [data-control=exit]{margin-left:20px}.qti-test-scope [data-control=comment-toggle]{display:none}.qti-test-scope .qti-timer{display:inline-block;text-align:center;vertical-align:top;line-height:1.2;position:relative;padding:0 20px}.qti-test-scope .qti-timer .qti-timer_label{max-width:130px;font-size:12px;font-size:1.2rem}.qti-test-scope .qti-timer::before{content:" ";background:rgba(255,255,255,.3);width:1px;height:20px;position:absolute;left:0;top:5px}.qti-test-scope .qti-timer:first-child::before{content:none}.qti-test-scope.non-lti-context .title-box{display:none}.qti-test-scope #qti-rubrics{margin:auto;max-width:1024px;width:100%;padding:15px}.qti-test-scope #qti-rubrics .qti-rubricBlock{margin:20px 0}.qti-test-scope #qti-rubrics .hidden{display:none} /*# sourceMappingURL=test-runner.css.map */ \ No newline at end of file