diff --git a/.claude/data/open_no_case.csv b/.claude/data/open_no_case.csv new file mode 100644 index 0000000000..f778e0c0b9 --- /dev/null +++ b/.claude/data/open_no_case.csv @@ -0,0 +1,2094 @@ +模块,类,函数名 +action,model,getAccountFirstAction +action,model,renderAction +action,model,formatActionComment +action,model,printAction +action,model,printChanges +action,model,printActionForGitLab +action,model,processActionForAPI +action,model,buildTrashSearchForm +action,model,getAttributeByExecutionID +action,model,getObjectTypeTeamParams +action,model,checkActionCanUndelete +admin,model,getSecretKey +admin,model,getSignature +admin,model,setMenu +admin,model,checkPrivMenu +admin,model,setSubMenu +admin,model,setTabMenu +admin,model,genDateUsed +admin,model,setSwitcher +ai,model,isClickable +ai,model,setModelConfig +ai,model,useLanguageModel +ai,model,hasModelsAvailable +ai,model,getLanguageModels +ai,model,getLanguageModelNamesWithDefault +ai,model,getLanguageModel +ai,model,getDefaultLanguageModel +ai,model,serializeModel +ai,model,unserializeModel +ai,model,createModel +ai,model,updateModel +ai,model,toggleModel +ai,model,deleteModel +ai,model,testModelConnection +ai,model,makeRequest +ai,model,getProxyType +ai,model,camelCaseToSnakeCase +ai,model,standardizeParams +ai,model,assembleRequestData +ai,model,decodeResponse +ai,model,parseTextResponse +ai,model,parseChatResponse +ai,model,parseFunctionCallResponse +ai,model,complete +ai,model,edit +ai,model,converse +ai,model,converseForJSON +ai,model,converseTwiceForJSON +ai,model,getLatestMiniPrograms +ai,model,countLatestMiniPrograms +ai,model,saveMiniProgramMessage +ai,model,deleteHistoryMessagesByID +ai,model,getHistoryMessages +ai,model,getMiniProgramsByID +ai,model,getMiniProgramByID +ai,model,getCustomCategories +ai,model,getUsedCustomCategories +ai,model,getPublishedCustomCategories +ai,model,checkDuplicatedCategory +ai,model,updateCustomCategories +ai,model,getMiniPrograms +ai,model,getMiniProgramFields +ai,model,createNewVersionNotification +ai,model,publishMiniProgram +ai,model,collectMiniProgram +ai,model,canPublishMiniProgram +ai,model,createMiniProgram +ai,model,extractZtAppZip +ai,model,saveMiniProgramFields +ai,model,checkDuplicatedAppName +ai,model,getUniqueAppName +ai,model,verifyRequiredFields +ai,model,getPrompts +ai,model,getPromptById +ai,model,createPrompt +ai,model,updatePrompt +ai,model,deletePrompt +ai,model,togglePromptStatus +ai,model,serializeDataToPrompt +ai,model,generateDemoDataPrompt +ai,model,isAssoc +ai,model,getFunctionCallSchema +ai,model,getObjectForPromptById +ai,model,autoPrependNewline +ai,model,tryPunctuate +ai,model,assemblePrompt +ai,model,executePrompt +ai,model,isExecutable +ai,model,getTestingLocation +ai,model,getTargetFormLocation +ai,model,tryGetRelatedObjects +ai,model,getLastActiveStep +ai,model,getPromptsForUser +ai,model,filterPromptsForExecution +ai,model,setInjectData +ai,model,getRoleTemplates +ai,model,createRoleTemplate +ai,model,deleteRoleTemplate +ai,model,updateRoleTemplate +ai,model,getAssistants +ai,model,getAssistantsByModel +ai,model,getAssistantById +ai,model,createAssistant +ai,model,updateAssistant +ai,model,toggleAssistant +ai,model,checkAssistantDuplicate +ai,model,deleteAssistant +ai,model,__construct +aiapp,model,__construct +aiapp,model,getLatestMiniPrograms +aiapp,model,countLatestMiniPrograms +aiapp,model,saveMiniProgramMessage +aiapp,model,deleteHistoryMessagesByID +aiapp,model,getHistoryMessages +aiapp,model,getCollectedMiniProgramIDs +aiapp,model,getSquareCategoryArray +aiapp,model,getUsedCategoryArray +api,model,createDemoLib +api,model,createDemoStruct +api,model,createDemoStructSpec +api,model,createDemoModule +api,model,createDemoApi +api,model,createDemoApiSpec +api,model,getGroupedObjects +api,model,buildSearchForm +api,model,getApiSpecByData +api,model,getApiStructSpecByData +api,model,getTypeList +backup,model,backSQL +backup,model,backFile +backup,model,backCode +backup,model,restoreSQL +backup,model,restoreFile +backup,model,getDiskSpace +backup,model,getDirSize +bi,model,getViewableObject +bi,model,parseToStatement +bi,model,getTableAndFields +bi,model,getFields +bi,model,parseTableList +bi,model,getFieldsWithTable +bi,model,getFieldsWithAlias +bi,model,getTableByAlias +bi,model,explainSQL +bi,model,getColumnsType +bi,model,getScopeOptions +bi,model,getDataviewOptions +bi,model,getObjectOptions +bi,model,getOptionsFromSql +bi,model,genWaterpolo +bi,model,getMultiData +bi,model,getTableFields +bi,model,getTableFieldsMenu +bi,model,prepareBuiltinChartSQL +bi,model,preparePivotObject +bi,model,prepareBuilitinPivotDrillSQL +bi,model,prepareBuiltinMetricSQL +bi,model,prepareBuiltinScreenSQL +bi,model,getDuckDBPath +bi,model,checkDuckDBFile +bi,model,getDuckdbBinConfig +bi,model,getDuckDBTmpDir +bi,model,getSqlByMonth +bi,model,getActionSyncSql +bi,model,initParquet +bi,model,prepareCopySQL +bi,model,prepareSyncCommand +bi,model,generateParquetFile +bi,model,getLogFile +bi,model,saveLogs +bi,model,parseSqlVars +bi,model,sql2Statement +bi,model,validateSql +bi,model,prepareSqlPager +bi,model,prepareColumns +bi,model,getSqlTypeAndFields +bi,model,getParams4Rebuild +bi,model,getSQL +bi,model,querySQL +bi,model,query +bi,model,getTableList +bi,model,buildQueryResultTableColumns +bi,model,prepareFieldObjects +bi,model,prepareFieldSettingFormData +bi,model,rebuildFieldSettings +bi,model,convertDataForDtable +bi,model,getDrillFields +bi,model,processDrills +bi,model,prepareDrillConditions +bi,model,json2Array +bi,model,getCorrectGroup +bi,model,downloadDuckdb +bi,model,checkDuckdbInstall +bi,model,updateDownloadingTagFile +bi,model,unzipFile +bi,model,downloadFile +bi,model,jsonEncode +block,model,updateLayout +block,model,getModelType4Projects +branch,model,manage +bug,model,buildSearchForm +bug,model,buildSearchConfig +bug,model,getRelatedObjects +bug,model,getDatatableModules +bug,model,updateLinkedCommits +bug,model,getLinkedCommits +build,model,getRelatedReleases +build,model,addReleaseLabelForBuilds +cache,model,clear +caselib,model,setLibMenu +caselib,model,getPairs +caselib,model,buildSearchConfig +chart,model,__construct +chart,model,checkAccess +chart,model,addFormatter4Echart +chart,model,addRotate4Echart +chart,model,genRadar +chart,model,genPie +chart,model,genLineChart +chart,model,genCluBar +chart,model,getMultiData +chart,model,genWaterpolo +chart,model,isChartHaveData +cne,model,__construct +cne,model,updateConfig +cne,model,validateCert +cne,model,uploadCert +cne,model,getDefaultAccount +cne,model,getDomain +cne,model,getVolumesMetrics +cne,model,getDiskSettings +cne,model,instancesMetrics +cne,model,backup +cne,model,getBackupStatus +cne,model,getBackupList +cne,model,deleteBackup +cne,model,restore +cne,model,getRestoreStatus +cne,model,startApp +cne,model,stopApp +cne,model,installApp +cne,model,getAppVolumes +cne,model,getSettingsMapping +cne,model,getAppConfig +cne,model,queryStatus +cne,model,batchQueryStatus +cne,model,appDBList +cne,model,appDBDetail +cne,model,apiGet +cne,model,apiPost +cne,model,cneServerError +cne,model,translateError +common,model,sendHeader +common,model,initAuthorize +common,model,formConfig +common,model,strEndsWith +common,model,getMainNavList +common,model,getActiveMainMenu +common,model,checkSafeFile +common,model,checkUpgradeStatus +common,model,getUserPriv +common,model,checkIP +common,model,getSysURL +common,model,isTutorialMode +common,model,checkEntry +common,model,checkEntryToken +common,model,checkNotCN +common,model,http +common,model,setMainMenu +common,model,getRelations +common,model,setMenuVars +common,model,checkMenuVarsReplaced +common,model,processMarkdown +common,model,sortFeatureMenu +common,model,apiGet +common,model,apiPost +common,model,apiPut +common,model,apiDelete +common,model,apiError +common,model,buildActionItem +common,model,buildOperateMenu +common,model,checkPrivForOperateAction +common,model,printDuration +common,model,checkPrivByObject +common,model,buildIconButton +common,model,printAboutBar +common,model,printClientLink +common,model,printCreateList +common,model,printIcon +common,model,printMainMenu +common,model,printModuleMenu +common,model,printOrderLink +common,model,printMessageBar +common,model,printUserBar +common,model,printBack +common,model,printLink +common,model,printPreAndNext +common,model,printCommentIcon +common,model,getDotStyle +company,model,buildSearchForm +convert,model,connectDB +convert,model,dbExists +convert,model,tableExists +convert,model,tableExistsOfJira +convert,model,saveState +convert,model,getJiraData +convert,model,getJiraDataFromDB +convert,model,getJiraDataFromFile +convert,model,splitFile +convert,model,createTmpTable4Jira +convert,model,importJiraData +convert,model,deleteJiraFile +convert,model,checkDBName +convert,model,getZentaoObjectList +convert,model,getZentaoRelationList +convert,model,getZentaoFields +convert,model,getZentaoStatus +convert,model,getJiraStepList +convert,model,checkImportJira +convert,model,getObjectDefaultValue +convert,model,getJiraTypeList +convert,model,getJiraStatusList +convert,model,getJiraCustomField +convert,model,getJiraFieldGroupByProject +convert,model,getJiraWorkflowActions +convert,model,checkJiraApi +convert,model,callJiraAPI +convert,model,getJiraAccount +convert,model,processJiraUser +convert,model,getVersionGroup +convert,model,object2Array +convert,model,convertStage +convert,model,convertStatus +convert,model,getJiraSprint +convert,model,getJiraSprintIssue +convert,model,getJiraArchivedProject +convert,model,getJiraProjectRoleActor +convert,model,getIssueTypeList +cron,model,restartCron +custom,model,hasProductERData +datatable,model,getOldFieldList +datatable,model,getOldSetting +datatable,model,sortOldCols +datatable,model,printHead +datatable,model,setFixedFieldWidth +datatable,model,appendWorkflowFields +dataview,model,__construct +dataview,model,verifySqlWithModify +dataview,model,processMergeFields +dataview,model,getObjectFields +dept,model,getList +dept,model,fixDeptPath +design,model,getLinkedCommits +dev,model,getAPIData +dimension,model,__construct +dimension,model,getByID +dimension,model,getFirst +dimension,model,getList +dimension,model,getDimension +dimension,model,saveState +doc,model,isClickable +doc,model,getObjectIDByLib +doc,model,getSpaceType +doc,model,getExecutionLibPairsByProject +doc,model,filterPrivDocs +doc,model,getTeamSpaces +doc,model,getDocTemplateSpaces +doc,model,initDocTemplateSpaces +doc,model,initDocDefaultSpaces +doc,model,getSubSpacesByType +doc,model,getLibTargetSpace +doc,model,getParamFromTargetSpace +doc,model,getModulesOfLibs +doc,model,getLastViewed +doc,model,setLastViewed +doc,model,getDocBlock +doc,model,getDocBlockContent +doc,model,getZentaoList +doc,model,getDocsByParent +doc,model,getDocIdByTitle +doc,model,buildDocItems +epic,model,isClickable +epic,model,getToAndCcList +execution,model,getByBuild +execution,model,buildCaseSearchForm +extension,model,__construct +extension,model,fetchAPI +extension,model,removeExtensionFiles +extension,model,removeExtensionDirs +extension,model,cleanModelCache +file,model,__construct +file,model,deleteByObject +file,model,getByGid +file,model,query +file,model,saveUpload +file,model,saveAFile +file,model,saveChunkedFile +file,model,cropImage +file,model,imagecreatefrombmp +file,model,dwordize +git,model,linkCommit +gitea,model,apiGetMergeRequests +gitlab,model,apiCreateTag +gogs,model,apiGetMergeRequests +group,model,getProgramsForAdminGroup +group,model,getProductsForAdminGroup +group,model,processDepends +group,model,checkNavSubset +group,model,getPrivsByParents +host,model,getPairs +host,model,processTreemap +host,model,getTreeModules +instance,model,__construct +instance,model,updateInstancesDomain +instance,model,updateCpuSize +instance,model,updateVolSize +instance,model,url +instance,model,k8nameExists +instance,model,installationSettingsMap +instance,model,getValidDBSettings +instance,model,install +instance,model,installSysSLB +instance,model,createInstance +instance,model,doCneInstall +instance,model,uninstall +instance,model,start +instance,model,stop +instance,model,upgrade +instance,model,batchFresh +instance,model,freshStatus +instance,model,enoughMemory +instance,model,isClickable +instance,model,checkAppNameUnique +instance,model,saveAuthInfo +instance,model,generatePipelineName +instance,model,backup +instance,model,backupList +instance,model,saveBackupSettings +instance,model,getBackupSettings +instance,model,restore +instance,model,deleteBackup +instance,model,deleteBackupCron +job,model,initJob +job,model,execJenkinsPipeline +kanban,model,getRDKanbanByGroup +kanban,model,checkDisplayCards +kanban,model,getKanbanCallback +kanban,model,getCellByCard +mail,model,__construct +mail,model,setImages +mail,model,setErrorLang +mail,model,clear +mark,model,getNeededMarks +mark,model,getMarks +mark,model,isMark +mark,model,hasMark +mark,model,setMark +metric,model,getViewTableData +metric,model,getTimeTable +metric,model,getObjectTable +metric,model,getMetricsByCodeList +metric,model,getRecordCalcInfo +metric,model,getDAO +metric,model,getDataStatement +metric,model,calculateMetricByCode +metric,model,getResultByCodeWithArray +metric,model,mergeRecord +metric,model,getUniqueKeyByRecord +metric,model,getCalculator +metric,model,calculateReuseMetric +metric,model,calculateSingleMetric +metric,model,calculateDefaultMetric +metric,model,getLatestResultByCode +metric,model,getResultByCodes +metric,model,getLogFile +metric,model,saveLogs +metric,model,getRecordFields +metric,model,rebuildPrimaryKey +metric,model,clearOutDatedRecords +metric,model,insertMetricLib +metric,model,getDataset +metric,model,classifyCalc +metric,model,uniteFieldList +metric,model,buildSearchForm +metric,model,getWaterfullProjectPairs +metric,model,getPairsByIdList +metric,model,processScopeList +metric,model,processUnitList +metric,model,processObjectList +metric,model,createSqlFunction +metric,model,execSqlMeasurement +metric,model,updateMetricFields +metric,model,processOldMetrics +metric,model,getMetricRecordType +metric,model,getEchartLegend +metric,model,getEchartsOptions +metric,model,getObjectOptions +metric,model,getTimeOptions +metric,model,updateMetricDate +metric,model,parseDateStr +metric,model,getDateByDateType +metric,model,getStartAndEndOfWeek +metric,model,isCalcByCron +metric,model,getNoDataTip +metric,model,checkHasInferenceOfDate +metric,model,isFirstInference +metric,model,getInstallDate +metric,model,filterCalcByEdition +misc,model,getUpgradeRemind +mr,model,__construct +my,model,getProductRelatedData +my,model,getTaskAssignedByMe +my,model,buildReviewedList +personnel,model,updateParentWhitelist +pivot,model,__construct +pivot,model,checkAccess +pivot,model,filterInvisiblePivot +pivot,model,getPivotDataByID +pivot,model,getPivotSpec +pivot,model,processNameDesc +pivot,model,completePivot +pivot,model,addDrills +pivot,model,appendWhereFilterToSql +pivot,model,filterFieldsWithSettings +pivot,model,mapRecordValueWithFieldOptions +pivot,model,generateTableCols +pivot,model,getShowColPosition +pivot,model,isShowLastRow +pivot,model,columnStatistics +pivot,model,getGroupTreeWithKey +pivot,model,formatCellData +pivot,model,getColumnSummary +pivot,model,addRowSummary +pivot,model,pureCrystalData +pivot,model,flattenRow +pivot,model,flattenCrystalData +pivot,model,processRowSpan +pivot,model,getRowTotal +pivot,model,setPercentage +pivot,model,processPercentage +pivot,model,groupRecords +pivot,model,setUniqueSlices +pivot,model,getSliceRecords +pivot,model,getCellData +pivot,model,addDrillFields +pivot,model,processCrystalData +pivot,model,processRecordsForDisplay +pivot,model,getRowSpanConfig +pivot,model,getDrillsFromRecords +pivot,model,processQueryFilterDefaults +pivot,model,isFiltersAllEmpty +pivot,model,genOriginSheet +pivot,model,initVarFilter +pivot,model,getColLabel +pivot,model,getGroupsKey +pivot,model,processFilters +pivot,model,setConditionValueWithFilters +pivot,model,getFieldsFromPivot +pivot,model,getFieldsOptions +pivot,model,processDTableCols +pivot,model,processDTableData +pivot,model,buildPivotTable +pivot,model,getDrillCols +pivot,model,getReferSQL +pivot,model,getDrillSQL +pivot,model,execDrillSQL +pivot,model,getDrillResult +pivot,model,getDrillDatas +pivot,model,processKanbanDatas +pivot,model,getPivotVersions +pivot,model,getMaxVersion +pivot,model,getMaxVersionByIDList +pivot,model,isVersionChange +pivot,model,switchNewVersion +pivot,model,filterSpecialChars +product,model,buildSearchConfig +program,model,suspend +program,model,checkPriv +program,model,getChildrenPairsByID +program,model,getProductPairsByID +program,model,setMenu +program,model,getSwitcher +programplan,model,getByList +project,model,getAclListByObjectType +project,model,getListByAcl +project,model,getTeamListByType +project,model,getInvolvedListByCurrentUser +project,model,leftJoinInvolvedTable +project,model,appendInvolvedCondition +project,model,getExecutionProductGroup +project,model,addTeamMembers +project,model,checkBranchAndProduct +project,model,checkDates +project,model,updateTeamMembers +project,model,updateUserView +project,model,unlinkStoryByType +project,model,setNoMultipleMenu +project,model,formatDataForList +project,model,recordFirstEnd +projectstory,model,buildSearchConfig +release,model,getPageSummary +release,model,sendmail +release,model,getNotifyList +release,model,sendMail2Feedback +release,model,processRelated +release,model,updateRelated +release,model,deleteRelated +release,model,processReleaseListData +repo,model,startTask +repo,model,finishTask +repo,model,getLinkedBranch +repo,model,unlinkObjectBranch +repo,model,getListByProduct +report,model,__construct +report,model,getUserYearContributionCount +report,model,getContributionCountTips +requirement,model,isClickable +requirement,model,getToAndCcList +screen,model,__construct +screen,model,checkAccess +screen,model,mergeChartAndPivotFilters +screen,model,updateComponentFilters +screen,model,isFilterChange +screen,model,genNotFoundOrDraftComponentOption +screen,model,genDelistOrDeletedMetricOption +screen,model,unsetComponentDraftMarker +screen,model,genMetricComponent +screen,model,getMetricPagination +screen,model,preparePaginationBeforeFetchRecords +screen,model,updateMetricFilters +screen,model,prepareRadarDataset +screen,model,prepareTextDataset +screen,model,processMetricFilter +screen,model,formatMetricDateByType +screen,model,getOptionsFromSql +screen,model,buildGroup +screen,model,buildTableChart +screen,model,getWaterPoloOption +screen,model,getMetricChartOption +screen,model,getMetricTableOption +screen,model,filterMetricData +screen,model,getMetricCardOption +screen,model,getMetricHeaders +screen,model,buildOrgChart +screen,model,buildFunnelChart +screen,model,initMetricComponent +screen,model,initChartAndPivotComponent +screen,model,initOptionTitle +screen,model,checkIFChartInUse +screen,model,getChartType +screen,model,buildDataset +screen,model,getDatasetForUsageReport +screen,model,getActiveUserTable +screen,model,getActiveProjectCard +screen,model,getActiveProductCard +screen,model,getProductTestTable +screen,model,getProjectTaskTable +screen,model,getProductStoryTable +screen,model,getProjectStoryTable +screen,model,getUsageReportProjects +screen,model,getUsageReportProducts +screen,model,getThumbnail +screen,model,removeScheme +search,model,processSearchParams +search,model,buildOldQuery +search,model,convertQueryForm +search,model,getOldQuery +setting,model,computeSN +space,model,getSpaceInstancesAppIDs +store,model,__construct +store,model,getVersionPairs +store,model,appVersionList +store,model,getUpgradableVersions +store,model,appLatestVersion +store,model,pickHighestVersion +store,model,batchSetLatestVersions +story,model,getPairsByList +story,model,relieveTwins +story,model,batchChangeParent +story,model,batchChangeGrade +story,model,getAllChildId +story,model,getByAssignedTo +story,model,getByOpenedBy +story,model,getByReviewedBy +story,model,getByReviewBy +story,model,getByClosedBy +story,model,getByStatus +story,model,getRequirementParents +story,model,getEpicParents +story,model,getDataOfStoriesPerGrade +story,model,appendChildren +story,model,getMergeTrackCells +story,model,getStatusList +story,model,getGradeList +story,model,getGradeGroup +story,model,getGradePairs +story,model,getGradeMenu +story,model,getGradeOptions +story,model,getMaxGradeGroup +story,model,getDefaultShowGrades +story,model,checkGrade +story,model,syncGrade +story,model,updateLinkedCommits +story,model,getLinkedCommits +svn,model,__construct +system,model,updateMinioDomain +system,model,getBackupStatus +system,model,getBackupList +system,model,restore +system,model,deleteBackup +system,model,setMaintenance +system,model,unsetMaintenance +system,model,getLatestRelease +system,model,isUpgradeable +system,model,setSystemRelease +task,model,getPairsByIdList +task,model,getListByStories +task,model,addTaskLabel +task,model,updateParent +task,model,updateLinkedCommits +task,model,getLinkedCommits +testcase,model,setMenu +testcase,model,processDatas +testcase,model,processStepsOrExpects +testcase,model,processStepsChanged +testcase,model,getXmindImport +testcase,model,saveXmindImport +testcase,model,saveTestcase +testcase,model,processCaseSteps +testcase,model,xmlToArray +testcase,model,getXmlTagsArray +testreport,model,getChildBuilds +testsuite,model,getCaseLinkedStories +testtask,model,processExecutionName +testtask,model,getRunByCase +testtask,model,addPrefixToOrderBy +testtask,model,getSceneCases +testtask,model,getGroupByCases +testtask,model,initResultForAutomatedTest +testtask,model,processStepResults +testtask,model,formatZtfLog +testtask,model,importUnitResult +testtask,model,importDataOfUnitResult +testtask,model,importSuiteOfUnitResult +testtask,model,importCaseOfUnitResult +testtask,model,importRunOfUnitResult +testtask,model,linkImportedCaseToSuite +testtask,model,getExistSuitesOfUnitResult +testtask,model,getExistCasesOfUnitResult +testtask,model,parseCppXMLResult +testtask,model,parseXMLResult +testtask,model,parseZTFUnitResult +testtask,model,parseZTFFuncResult +testtask,model,initSuite +testtask,model,initCase +testtask,model,initResult +testtask,model,processResult +todo,model,dateRange +transfer,model,__construct +transfer,model,initWorkflowFieldList +transfer,model,getPageDatas +transfer,model,format +transfer,model,checkTmpFile +transfer,model,getRowsFromExcel +transfer,model,processRows4Fields +transfer,model,createTmpFile +tree,model,getOptionMenuByBranch +tree,model,buildTreeArray +tree,model,buildTree +tree,model,createEpicLink +tree,model,createManageLink +tree,model,createSceneLink +tree,model,createPracticeLink +tree,model,setModuleLang +tree,model,getGroupPairs +tutorial,model,getExecutionBurnData +tutorial,model,getStoryPairs +tutorial,model,getStory +tutorial,model,getEpic +tutorial,model,getRequirement +tutorial,model,getStoryByID +tutorial,model,getStoryGrade +tutorial,model,getGradePairs +tutorial,model,getStage +tutorial,model,getStages +tutorial,model,getTask +tutorial,model,getTasks +tutorial,model,getBuild +tutorial,model,getBuilds +tutorial,model,getBuildPairs +tutorial,model,getRun +tutorial,model,getCase +tutorial,model,getCases +tutorial,model,getResult +tutorial,model,getResults +tutorial,model,getTesttask +tutorial,model,getTesttasks +tutorial,model,getTesttaskPairs +tutorial,model,getTestReport +tutorial,model,getTestReports +tutorial,model,getBug +tutorial,model,getBugs +tutorial,model,getIssue +tutorial,model,getIssues +tutorial,model,getRisk +tutorial,model,getRisks +tutorial,model,getDesign +tutorial,model,getDesigns +tutorial,model,getReview +tutorial,model,getReviews +tutorial,model,getRegionPairs +tutorial,model,getGroups +tutorial,model,getLaneGroup +tutorial,model,getColumns +tutorial,model,getColumn +tutorial,model,getCardGroup +tutorial,model,getPlan +tutorial,model,getPlans +tutorial,model,getPlanPairs +tutorial,model,getSystem +tutorial,model,getSystemPairs +tutorial,model,getSystemList +tutorial,model,getRelease +tutorial,model,getReleases +tutorial,model,getProgramPairs +tutorial,model,getProgram +tutorial,model,getPrograms +tutorial,model,getBranchPairs +tutorial,model,getBranchesByProject +tutorial,model,getBranches +tutorial,model,getFeedback +tutorial,model,getFeedbacks +tutorial,model,getSubSpaces +tutorial,model,getDocTemplateSpaces +tutorial,model,getDocLib +tutorial,model,getDocLibs +tutorial,model,getLibTree +tutorial,model,getDoc +tutorial,model,getDocs +tutorial,model,getDemandpool +tutorial,model,getDemand +tutorial,model,getDemands +tutorial,model,getResearchStageStats +tutorial,model,getMarket +tutorial,model,getCharter +tutorial,model,getCharters +tutorial,model,getRepoPairs +tutorial,model,getRepo +tutorial,model,getCommits +user,model,getUserAcls +user,model,uploadAvatar +user,model,initViewObjects +user,model,getProgramView +user,model,getProductView +user,model,getProjectView +user,model,getSprintView +user,model,getManageListGroupByType +user,model,getProgramStakeholder +user,model,mergeAclsToUserView +user,model,getObjectsAuthedUsers +user,model,getLatestUserView +user,model,checkProgramPriv +user,model,checkProjectPriv +user,model,checkProductPriv +user,model,getProgramAuthedUsers +user,model,getProjectAuthedUsers +user,model,saveOldUserTemplate +webhook,model,getDataByType +webhook,model,fetchHook +webhook,model,sendToUser +weekly,model,save +weekly,model,getLeft +weekly,model,getReportData +zahost,model,getImagePairs +zahost,model,downloadImage +zahost,model,queryDownloadImageStatus +zahost,model,cancelDownload +zahost,model,hiddenHost +zanode,model,__construct +zanode,model,createImage +zanode,model,restoreSnapshot +zanode,model,deleteSnapshot +zanode,model,destroy +zanode,model,processNodeStatus +zanode,model,getVncUrl +zanode,model,runZTFScript +zanode,model,linkAgentService +zanode,model,setMenu +action,tao,getLinkedExtra +action,tao,processActionExtra +action,tao,processStoryGradeActionExtra +action,tao,processAttribute +action,tao,processParamString +action,tao,processCreateChildrenActionExtra +action,tao,processCreateRequirementsActionExtra +action,tao,processAppendLinkByExtra +action,tao,processLinkStoryAndBugActionExtra +action,tao,processToStoryActionExtra +action,tao,getActionTable +action,tao,addObjectNameForAction +action,tao,processMaxDocObjectLink +action,tao,getDocLibLinkParameters +action,tao,getDoclibTypeParams +action,tao,getObjectLinkParams +bi,tao,fetchAllTables +bi,tao,fetchTableQueue +bi,tao,updateSyncTime +bi,tao,fetchActionDate +caselib,tao,checkStepChanged +caselib,tao,processSteps +chart,tao,switchFieldName +common,tao,checkPrivByRights +common,tao,isProjectAdmin +common,tao,getStoryModuleAndMethod +common,tao,getBoardModuleAndMethod +common,tao,updateDBWebRoot +convert,tao,buildUserData +convert,tao,buildProjectData +convert,tao,buildIssueData +convert,tao,buildIssueTypeData +convert,tao,buildIssueLinkTypeData +convert,tao,buildResolutionData +convert,tao,buildStatusData +convert,tao,buildBuildData +convert,tao,buildIssuelinkData +convert,tao,buildActionData +convert,tao,buildFileData +convert,tao,buildPriorityData +convert,tao,buildCustomFieldData +convert,tao,buildCustomFieldValueData +convert,tao,buildCustomFieldOptionData +convert,tao,buildOSPropertyEntryData +convert,tao,buildConfigurationcontextData +convert,tao,buildOptionconfigurationData +convert,tao,buildAuditLogData +convert,tao,buildProjectRoleActorData +convert,tao,buildMemberShipData +convert,tao,buildFieldScreenLayoutItemData +convert,tao,buildFieldConfigSchemeData +convert,tao,buildFieldConfigSchemeIssueTypeData +convert,tao,buildWorkflowData +convert,tao,buildWorkflowSchemeData +convert,tao,buildWorklogData +convert,tao,buildChangeItemData +convert,tao,buildChangeGroupData +convert,tao,buildNodeAssociationData +convert,tao,buildFixVersionData +convert,tao,buildAffectsVersionData +convert,tao,getIssueData +convert,tao,importJiraUser +convert,tao,createTmpRelation +convert,tao,importJiraProject +convert,tao,importJiraIssue +convert,tao,importJiraBuild +convert,tao,importJiraIssueLink +convert,tao,importJiraWorkLog +convert,tao,importJiraAction +convert,tao,importJiraChangeItem +convert,tao,importJiraFile +convert,tao,createTeamMember +convert,tao,createDocLib +convert,tao,createProject +convert,tao,createDefaultExecution +convert,tao,createExecution +convert,tao,createProduct +convert,tao,processBuildinFieldData +convert,tao,createStory +convert,tao,createTask +convert,tao,createBug +convert,tao,createCase +convert,tao,createFeedback +convert,tao,createTicket +convert,tao,createBuild +convert,tao,createRelease +convert,tao,createBuildinField +convert,tao,createDefaultLayout +convert,tao,createWorkflow +convert,tao,createWorkflowField +convert,tao,createWorkflowStatus +convert,tao,processWorkflowHooks +convert,tao,createWorkflowAction +convert,tao,createGroup +convert,tao,createWorkflowGroup +convert,tao,createResolution +convert,tao,updateSubStory +convert,tao,updateSubTask +convert,tao,updateDuplicateStoryAndBug +convert,tao,updateRelatesObject +convert,tao,processJiraIssueContent +convert,tao,processJiraContent +doc,tao,getSpacePairs +doc,tao,doInsertLib +doc,tao,filterDeletedDocs +execution,tao,buildBatchUpdateExecutions +execution,tao,buildStoryTree +execution,tao,updateTeam +job,tao,checkIframe +job,tao,getSvnDir +job,tao,getCustomParam +kanban,tao,buildRegionData +kanban,tao,addChildColumnCell +kanban,tao,updateColumnParent +kanban,tao,updateCardAssignedTo +kanban,tao,buildObjectCard +kanban,tao,updateExecutionCell +kanban,tao,getBranchesForPlanKanban +kanban,tao,buildRDRegionData +kanban,tao,initCardItem +kanban,tao,appendTeamMember +kanban,tao,buildGroupKanban +kanban,tao,buildGroupColumn +kanban,tao,buildGroupCard +kanban,tao,getObjectPairs +kanban,tao,refreshERURCards +kanban,tao,refreshStoryCards +kanban,tao,refreshBugCards +kanban,tao,refreshTaskCards +kanban,tao,getERURCardMenu +kanban,tao,getStoryCardMenu +kanban,tao,getBugCardMenu +kanban,tao,getRiskCardMenu +mail,tao,getImages +mail,tao,getImagesByFileID +mail,tao,getImagesByPath +metric,tao,fetchMetricsByCodeList +metric,tao,getObjectsWithPager +metric,tao,processDAOWithDate +metric,tao,fetchMetricRecords +metric,tao,fetchMetricRecordsWithOption +metric,tao,fetchLatestMetricRecords +metric,tao,fetchMetricRecordByDate +metric,tao,setDeleted +metric,tao,keepLatestRecords +metric,tao,executeDelete +metric,tao,rebuildIdColumn +my,tao,getProductRelatedAssignedByMe +my,tao,fetchTasksBySearch +my,tao,fetchStoriesBySearch +my,tao,fetchEpicsBySearch +my,tao,fetchRequirementsBySearch +my,tao,buildReviewingFlows +pivot,tao,fetchPivot +pivot,tao,mergePivotSpecData +pivot,tao,processProductPlan +pivot,tao,processPlanStories +pivot,tao,getPlanStatusStatistics +pivot,tao,getExecutionList +pivot,tao,getBugGroup +pivot,tao,getNoAssignExecution +pivot,tao,getTeamTasks +pivot,tao,getAssignBugGroup +pivot,tao,getProductProjects +pivot,tao,getAllProductsIDAndName +pivot,tao,getProjectAndExecutionNameQuery +pivot,tao,fetchPivotDrills +product,tao,filterNoCasesStory +program,tao,setNoTaskExecution +programplan,tao,setPlanBaseline +project,tao,doStart +project,tao,insertMember +project,tao,updateMemberView +project,tao,buildLinkForProject +project,tao,buildLinkForBug +project,tao,buildLinkForStory +project,tao,unlinkTeamMember +project,tao,setNavGroupMenu +projectrelease,tao,getBranchName +repo,tao,copySvnDir +report,tao,getAnnualProductStat +report,tao,getAnnualExecutionStat +report,tao,buildAnnualCaseStat +report,tao,getOutputData +screen,tao,processRadarData +search,tao,initOldSession +search,tao,checkProductPriv +search,tao,checkProgramPriv +search,tao,checkProjectPriv +search,tao,checkExecutionPriv +search,tao,checkDocPriv +search,tao,checkTodoPriv +search,tao,checkTestsuitePriv +search,tao,checkFeedbackAndTicketPriv +search,tao,checkObjectPriv +search,tao,checkRelatedObjectPriv +search,tao,checkPriv +search,tao,decode +search,tao,getSummary +search,tao,markKeywords +search,tao,processRecord +search,tao,processIssueRecord +search,tao,processProjectRecord +search,tao,processExecutionRecord +search,tao,processTaskRecord +search,tao,processStoryRecord +search,tao,processDocRecord +search,tao,processRiskRecord +search,tao,unify +search,tao,appendFiles +story,tao,getStoriesCountByProductIDs +story,tao,getFinishClosedTotal +story,tao,getUnClosedTotal +story,tao,getProductReviewers +story,tao,getChildItems +story,tao,doSaveUploadImage +story,tao,checkCanSubdivide +story,tao,checkCanSplit +story,tao,computeStage +story,tao,updateLane +story,tao,getAffectedChildren +story,tao,checkConditions +story,tao,getTasksForTrack +story,tao,buildStoryTree +story,tao,buildReorderResult +task,tao,concatTeamInfo +task,tao,createChangesForTeam +task,tao,formatDatetime +task,tao,getRequiredFields4Edit +task,tao,getTeamInfoList +task,tao,recordTaskVersion +testcase,tao,saveScene +todo,tao,getCycleDailyTodoDate +webhook,tao,getDingdingSecret +webhook,tao,getWeixinSecret +webhook,tao,getFeishuSecret +webhook,tao,getActionText +zanode,tao,getSubZahostListByID +zanode,tao,getZaNodeListByQuery +zanode,tao,getHostsByIDList +action,zen,getTrashesHeaderNavigation +action,zen,saveUrlIntoSession +action,zen,processTrash +action,zen,getReplaceNameAndCode +action,zen,checkActionExist +action,zen,getConfirmNoMessage +action,zen,recoverObject +action,zen,restoreStages +admin,zen,syncExtensions +admin,zen,syncPublicClasses +admin,zen,syncDynamics +admin,zen,fetchAPI +admin,zen,sendCodeByAPI +admin,zen,certifyByAPI +admin,zen,setCompanyByAPI +admin,zen,getZentaoData +api,zen,parseDocSpaceParam +api,zen,generateLibsDropMenu +api,zen,getMethod +api,zen,request +backup,zen,getBackupList +backup,zen,backupSQL +backup,zen,backupFile +backup,zen,backupCode +backup,zen,removeExpiredFiles +backup,zen,restoreSQL +backup,zen,restoreFile +backup,zen,setHoldDays +block,zen,initBlock +block,zen,getAvailableModules +block,zen,getAvailableCodes +block,zen,getAvailableParams +block,zen,getBlockTitle +block,zen,processBlockForRender +block,zen,createMoreLink +block,zen,printDynamicBlock +block,zen,printZentaoDynamicBlock +block,zen,printWelcomeBlock +block,zen,printTaskBlock +block,zen,printBugBlock +block,zen,printCaseBlock +block,zen,printTesttaskBlock +block,zen,printStoryBlock +block,zen,printPlanBlock +block,zen,printReleaseBlock +block,zen,printRoadmapBlock +block,zen,printReleaseStatisticBlock +block,zen,printBuildBlock +block,zen,printProjectBlock +block,zen,printProductListBlock +block,zen,printProjectOverviewBlock +block,zen,printProjectStatisticBlock +block,zen,printProductStatisticBlock +block,zen,printExecutionStatisticBlock +block,zen,printWaterfallReportBlock +block,zen,printWaterfallGeneralReportBlock +block,zen,printWaterfallGanttBlock +block,zen,printWaterfallIssueBlock +block,zen,printWaterfallRiskBlock +block,zen,printWaterfallEstimateBlock +block,zen,printWaterfallProgressBlock +block,zen,printScrumOverviewBlock +block,zen,printScrumListBlock +block,zen,printScrumProductBlock +block,zen,printScrumIssueBlock +block,zen,printScrumRiskBlock +block,zen,printIssueBlock +block,zen,printRiskBlock +block,zen,printSprintBlock +block,zen,printProjectDynamicBlock +block,zen,printScrumRoadMapBlock +block,zen,printScrumTestBlock +block,zen,printQaStatisticBlock +block,zen,printProductOverviewBlock +block,zen,printShortProductOverview +block,zen,printLongProductOverview +block,zen,printExecutionOverviewBlock +block,zen,printQaOverviewBlock +block,zen,printExecutionListBlock +block,zen,printAssignToMeBlock +block,zen,printRecentProjectBlock +block,zen,printProjectTeamBlock +block,zen,printDocStatisticBlock +block,zen,printDocDynamicBlock +block,zen,printDocMyCreatedBlock +block,zen,printDocMyCollectionBlock +block,zen,printDocRecentUpdateBlock +block,zen,printDocViewListBlock +block,zen,printDocCollectListBlock +block,zen,printProductDocBlock +block,zen,printProjectDocBlock +block,zen,printGuideBlock +block,zen,printMonthlyProgressBlock +block,zen,printAnnualWorkloadBlock +block,zen,printBugStatisticBlock +block,zen,printTeamAchievementBlock +block,zen,printSingleStatisticBlock +block,zen,printSingleBugStatisticBlock +block,zen,printSingleStoryBlock +block,zen,printSingleReleaseBlock +block,zen,printSinglePlanBlock +block,zen,printSingleDynamicBlock +block,zen,printSingleMonthlyProgressBlock +block,zen,isExternalCall +block,zen,printBlock4Json +block,zen,organizaExternalData +block,zen,getProjectsStatisticData +block,zen,buildProjectStatistic +branch,zen,setParamsForLink +bug,zen,checkBugExecutionPriv +bug,zen,checkRquiredForEdit +bug,zen,checkRequiredForResolve +bug,zen,checkBugsForBatchCreate +bug,zen,checkBugsForBatchUpdate +bug,zen,getBrowseBranch +bug,zen,getBrowseBugs +bug,zen,getBranchOptions +bug,zen,getKanbanVariable +bug,zen,getProductMembersForCreate +bug,zen,getAssignedToPairs +bug,zen,getExportFileName +bug,zen,getExportFields +bug,zen,getBatchResolveVars +bug,zen,setBrowseCookie +bug,zen,setBrowseSession +bug,zen,setCreateMenu +bug,zen,setEditMenu +bug,zen,setViewMenu +bug,zen,prepareBrowseParams +bug,zen,prepareCreateExtras +bug,zen,prepareEditExtras +bug,zen,buildBrowseSearchForm +bug,zen,buildBrowseView +bug,zen,getProductsForCreate +bug,zen,getBranchesForCreate +bug,zen,getModulesForCreate +bug,zen,getProjectsForCreate +bug,zen,getExecutionsForCreate +bug,zen,getBuildsForCreate +bug,zen,getStoriesForCreate +bug,zen,getTasksForCreate +bug,zen,buildCreateForm +bug,zen,buildEditForm +bug,zen,assignVarsForEdit +bug,zen,buildBugForResolve +bug,zen,buildBugsForBatchCreate +bug,zen,assignBatchCreateVars +bug,zen,assignKanbanVars +bug,zen,assignVarsForBatchCreate +bug,zen,buildSearchFormForLinkBugs +bug,zen,buildBugsForBatchEdit +bug,zen,assignBatchEditVars +bug,zen,assignProductRelatedVars +bug,zen,assignProjectRelatedVars +bug,zen,assignUsersForBatchEdit +bug,zen,processImageForBatchCreate +bug,zen,updateKanbanAfterCreate +bug,zen,updateTodoAfterCreate +bug,zen,updateBug +bug,zen,afterCreate +bug,zen,afterUpdate +bug,zen,afterBatchCreate +bug,zen,responseAfterOperate +bug,zen,responseInModal +bug,zen,responseAfterCreate +bug,zen,responseAfterDelete +bug,zen,responseAfterBatchCreate +bug,zen,operateAfterBatchEdit +bug,zen,getToBeProcessedData +bug,zen,responseAfterBatchEdit +bug,zen,initBug +bug,zen,extractObjectFromExtras +bug,zen,mergeChartOption +bug,zen,processRepoIssueActions +build,zen,assignCreateData +build,zen,assignEditData +build,zen,assignProductVarsForView +build,zen,assignBugVarsForView +build,zen,setMenuForView +build,zen,buildBuildForCreate +build,zen,buildBuildForEdit +build,zen,getExcludeStoryIdList +build,zen,buildLinkStorySearchForm +build,zen,buildLinkBugSearchForm +caselib,zen,saveLibState +caselib,zen,setBrowseSessionAndCookie +caselib,zen,buildSearchForm +caselib,zen,assignCaseParamsForCreateCase +caselib,zen,prepareCasesForBathcCreate +caselib,zen,prepareEditExtras +caselib,zen,getFieldsForExportTemplate +caselib,zen,getRowsForExportTemplate +caselib,zen,getImportHeaderAndColumns +caselib,zen,getStepsAndExpectsFromImportFile +caselib,zen,getFieldsForImport +caselib,zen,getColumnsForShowImport +caselib,zen,getDataForImport +caselib,zen,responseAfterShowImport +caselib,zen,getExportCasesFields +caselib,zen,processCasesForExport +caselib,zen,processStepForExport +caselib,zen,processStageForExport +caselib,zen,processFileForExport +caselib,zen,processLinkCaseForExport +chart,zen,getChartsToView +chart,zen,getChartToFilter +chart,zen,getMenuItems +ci,zen,getProductIdAndJobID +ci,zen,parseZtfResult +company,zen,saveUriIntoSession +company,zen,loadAllSearchModule +company,zen,loadProduct +company,zen,loadProject +company,zen,loadExecution +company,zen,loadUserModule +company,zen,buildDyanmicSearchForm +compile,zen,buildSearchForm +custom,zen,assignFieldListForSet +custom,zen,assignVarsForSet +custom,zen,setFieldListForSet +custom,zen,checkKeysForSet +custom,zen,checkDuplicateKeys +custom,zen,checkInvalidKeys +custom,zen,checkEmptyKeys +custom,zen,setStoryReview +custom,zen,setGradeRule +custom,zen,setTestcaseReview +design,zen,setMenu +doc,zen,processFiles +doc,zen,buildOutlineList +doc,zen,getOutlineParentID +doc,zen,buildOutlineTree +doc,zen,assignVarsForMySpace +doc,zen,setAclForCreateLib +doc,zen,buildLibForCreateLib +doc,zen,responseAfterCreateLib +doc,zen,setAclForEditLib +doc,zen,checkPrivForCreate +doc,zen,responseAfterCreate +doc,zen,responseAfterMove +doc,zen,setObjectsForCreate +doc,zen,responseAfterUploadDocs +doc,zen,assignVarsForCreate +doc,zen,assignVarsForUploadDocs +doc,zen,setObjectsForEdit +doc,zen,responseAfterEdit +doc,zen,responseAfterEditTemplate +doc,zen,processOutline +doc,zen,assignVarsForView +doc,zen,setSpacePageStorage +doc,zen,assignApiVarForSpace +doc,zen,buildSearchFormForShowFiles +doc,zen,initLibForMySpace +doc,zen,initLibForTeamSpace +doc,zen,getAllSpaces +doc,zen,recordBatchMoveActions +doc,zen,responseAfterAddTemplateType +doc,zen,formFromSession +doc,zen,prepareCols +doc,zen,previewFeedback +doc,zen,previeweicket +doc,zen,previewProductplan +doc,zen,previewPlanStory +doc,zen,previewProductBug +doc,zen,previewPlanBug +doc,zen,previewProductCase +doc,zen,previewProductStory +doc,zen,previewER +doc,zen,previewUR +doc,zen,previewProjectStory +doc,zen,previewExecutionStory +doc,zen,previewStory +doc,zen,previewTask +doc,zen,previewCaselib +doc,zen,exportZentaoList +doc,zen,assignStoryGradeData +doc,zen,processReleaseListData +doc,zen,getDocChildrenByRecursion +editor,zen,buildContentByAction +execution,zen,assignBugVars +execution,zen,assignKanbanVars +execution,zen,assignManageProductsVars +execution,zen,assignCountForStory +execution,zen,assignRelationForStory +execution,zen,assignModuleForStory +execution,zen,assignTaskKanbanVars +execution,zen,assignTestcaseVars +execution,zen,assignTesttaskVars +execution,zen,buildGroupTasks +execution,zen,buildGroupMultiTask +execution,zen,buildStorySearchForm +execution,zen,buildImportBugSearchForm +execution,zen,checkPostForCreate +execution,zen,buildExecutionForCreate +execution,zen,checkCFDDate +execution,zen,processBuildListData +execution,zen,buildProductSwitcher +execution,zen,buildMembers +execution,zen,buildMembersForManageMembers +execution,zen,filterGroupTasks +execution,zen,setRecentExecutions +execution,zen,setTaskPageStorage +execution,zen,buildExecutionKanbanData +execution,zen,getImportBugs +execution,zen,getPrintKanbanData +execution,zen,processExecutionKanbanData +execution,zen,processPrintKanbanData +execution,zen,hasMultipleBranch +execution,zen,getLink +execution,zen,setStorageForStory +execution,zen,setUserMoreLink +execution,zen,initFieldsForCreate +execution,zen,setFieldsByCopyExecution +execution,zen,getLinkedProducts +execution,zen,setLinkedBranches +execution,zen,getAllProductsForCreate +execution,zen,setCopyProjects +execution,zen,correctExecutionCommonLang +execution,zen,correctErrorLang +execution,zen,displayAfterCreated +execution,zen,updateLinkedPlans +execution,zen,checkLinkPlan +execution,zen,getLinkedObjects +execution,zen,getAfterCreateLocation +extension,zen,checkSafe +extension,zen,getHookFile +extension,zen,getDependsByDB +extension,zen,checkExtension +extension,zen,checkFileConflict +extension,zen,copyHookFiles +extension,zen,installExtension +extension,zen,extractPackage +extension,zen,copyPackageFiles +extension,zen,backupDB +extension,zen,togglePackageDisable +extension,zen,checkExtensionPaths +extension,zen,checkExtractPath +extension,zen,checkCompatible +extension,zen,checkConflicts +extension,zen,checkDepends +extension,zen,checkFile +extension,zen,compareForLimit +file,zen,getDownloadMode +file,zen,buildDownloadTable +file,zen,unlinkRealFile +file,zen,updateFileName +gitea,zen,checkToken +gitea,zen,getMatchedUsers +gitlab,zen,checkUserRepeat +gitlab,zen,bindUsers +gitlab,zen,recordWebhookLogs +gitlab,zen,getGroupMemberData +gitlab,zen,getProjectMemberData +gitlab,zen,checkBindedUser +gitlab,zen,webhookParseBody +gitlab,zen,webhookParseIssue +gitlab,zen,webhookParseObject +gitlab,zen,issueToZentaoObject +gogs,zen,checkToken +gogs,zen,getMatchedUsers +group,zen,appendResourcePackages +group,zen,appendWorkflowMenu +group,zen,managePrivByGroup +group,zen,managePrivByModule +group,zen,buildUpdateViewForm +group,zen,buildProjectAdminForm +group,zen,getNavGroup +host,zen,checkFormData +index,zen,checkShowFeatures +index,zen,getViewMethodForAssetLib +instance,zen,storeView +instance,zen,checkForInstall +jenkins,zen,buildTree +jenkins,zen,checkTokenAccess +job,zen,checkRepoEmpty +job,zen,getJobList +job,zen,reponseAfterCreateEdit +job,zen,getSubversionDir +job,zen,getCompileData +job,zen,buildSearchForm +job,zen,getJobSearchQuery +kanban,zen,assignCreateVars +kanban,zen,setUserAvatar +kanban,zen,moveCardByModal +mail,zen,getConfigForEdit +mail,zen,getConfigForSave +mail,zen,getHasMailUserPairs +mail,zen,sendQueue +mail,zen,deleteSentQueue +message,zen,assignDropmenuVars +metric,zen,buildMetricForCreate +metric,zen,buildMetricForEdit +metric,zen,responseAfterCreate +metric,zen,responseAfterEdit +metric,zen,prepareDataset +metric,zen,prepareTree +metric,zen,prepareScopeList +metric,zen,startTime +metric,zen,endTime +metric,zen,getValidObjects +metric,zen,calculateMetric +metric,zen,prepareMetricRecord +metric,zen,prepareReuseMetricResult +metric,zen,getRecordByCodeAndDate +metric,zen,initMetricRecords +metric,zen,buildRecordCommonFields +metric,zen,completeMissingRecords +metric,zen,getUniqueKeyByRecord +metric,zen,calcMetric +metric,zen,getCalcFields +metric,zen,getBasicInfo +metric,zen,getCreateEditInfo +metric,zen,getOldMetricInfo +metric,zen,processWeekConf +metric,zen,getViewTableWidth +metric,zen,getPagerExtra +metric,zen,formatException +metric,zen,processUnitList +metric,zen,prepareActionPriv +misc,zen,hello +misc,zen,encodeStatistics +mr,zen,getAllProjects +mr,zen,assignEditData +mr,zen,buildLinkStorySearchForm +mr,zen,buildLinkBugSearchForm +mr,zen,buildLinkTaskSearchForm +mr,zen,processLinkTaskPager +mr,zen,checkProjectEdit +mr,zen,getBranchUrl +mr,zen,checkNewCommit +mr,zen,saveMrData +my,zen,buildTaskData +my,zen,buildCaseData +my,zen,assignRelatedData +my,zen,buildSearchFormForFeedback +my,zen,showWorkCount +my,zen,showWorkCountNotInOpen +personnel,zen,setSelectObjectTips +pivot,zen,getDefaultMethodAndParams +pivot,zen,getMenuItems +pivot,zen,getSidebarMenus +pivot,zen,setNewMark +pivot,zen,getBuiltinMenus +pivot,zen,show +pivot,zen,bugCreate +pivot,zen,bugAssign +pivot,zen,productSummary +pivot,zen,processProductsForProductSummary +pivot,zen,projectDeviation +pivot,zen,workload +pivot,zen,getDrill +pivot,zen,getFilterOptionUrl +product,zen,setMenu4All +product,zen,setProjectMenu +product,zen,setCreateMenu +product,zen,setEditMenu +product,zen,setTrackMenu +product,zen,setShowErrorNoneMenu +product,zen,setShowErrorNoneMenu4QA +product,zen,setShowErrorNoneMenu4Project +product,zen,setShowErrorNoneMenu4Execution +product,zen,getBackLink4Create +product,zen,setSelectFormOptions +product,zen,getFormFields4Create +product,zen,getFormFields4Edit +product,zen,getFormFields4Close +product,zen,getFormFields4Activate +product,zen,getProductLines +product,zen,getExportFields +product,zen,getExportData +product,zen,getUnauthProgramsOfProducts +product,zen,getProducts4DropMenu +product,zen,getCreatedLocate +product,zen,getEditedLocate +product,zen,buildBatchEditForm +product,zen,buildProductForCreate +product,zen,buildProductForEdit +product,zen,buildProductForActivate +product,zen,buildProductForClose +product,zen,prepareManageLineExtras +product,zen,responseAfterCreate +product,zen,responseAfterEdit +product,zen,responseAfterBatchEdit +product,zen,getBrowseProduct +product,zen,getBranchID +product,zen,setMenu4Browse +product,zen,saveAndModifyCookie4Browse +product,zen,getModuleId +product,zen,getModuleTree +product,zen,getProjectProductList +product,zen,getProductPlans +product,zen,getStories +product,zen,getStoriesByStoryType +product,zen,getBranchOptions +product,zen,getBranchAndTagOption +product,zen,getKanbanList +product,zen,saveSession4Browse +product,zen,buildSearchFormForBrowse +product,zen,buildSearchFormForTrack +product,zen,getStoryIdList +product,zen,saveSession4Roadmap +product,zen,responseNotFound4View +product,zen,saveBackUriSessionForDynamic +product,zen,getActionsForDynamic +product,zen,getActions4Dashboard +product,zen,saveBackUriSession4Dashboard +product,zen,getProductList4Kanban +product,zen,getEmptyHour +product,zen,assignBrowseData +product,zen,processProjectListData +product,zen,getCustomFieldsForTrack +product,zen,getActiveStoryTypeForTrack +productplan,zen,buildPlansForBatchEdit +productplan,zen,assignKanbanData +productplan,zen,buildDataForBrowse +productplan,zen,buildActionsList +productplan,zen,getSummary +productplan,zen,setSessionForViewPage +productplan,zen,assignViewData +productplan,zen,buildLinkStorySearchForm +productplan,zen,buildBugSearchForm +productplan,zen,buildViewSummary +productplan,zen,buildViewActions +productplan,zen,reorderStories +program,zen,prepareStartExtras +program,zen,buildProgramForCreate +program,zen,buildProgramForEdit +program,zen,removeSubjectToCurrent +program,zen,getProgramsByType +program,zen,getPMListByPrograms +program,zen,getKanbanList +program,zen,getProgramList4Kanban +program,zen,buildTree +program,zen,getLink +program,zen,getProductsByBrowseType +programplan,zen,buildPlansForCreate +programplan,zen,buildCreateView +programplan,zen,prepareEditPlan +programplan,zen,buildEditView +programplan,zen,buildAjaxCustomView +programplan,zen,computeFieldsCreateView +programplan,zen,buildStages +programplan,zen,buildBrowseView +programplan,zen,sortPlans +project,zen,checkWorkdaysLegtimate +project,zen,prepareProject +project,zen,checkProductAndBranch +project,zen,checkDaysAndBudget +project,zen,checkProductNameUnqiue +project,zen,buildCreateForm +project,zen,displayAfterCreated +project,zen,getCopyProject +project,zen,prepareStartExtras +project,zen,prepareSuspendExtras +project,zen,prepareClosedExtras +project,zen,prepareBranchForBug +project,zen,prepareModuleForBug +project,zen,processBugSearchParams +project,zen,processBuildSearchParams +project,zen,processGroupPrivs +project,zen,buildBugView +project,zen,buildStartForm +project,zen,responseAfterStart +project,zen,responseAfterSuspend +project,zen,buildSuspendForm +project,zen,responseAfterClose +project,zen,buildClosedForm +project,zen,buildActivateForm +project,zen,responseAfterActivate +project,zen,prepareActivateExtras +project,zen,removeAssociatedExecutions +project,zen,removeAssociatedProducts +project,zen,updateLinkedProducts +project,zen,recordExecutionsOfUnlinkedProducts +project,zen,extractUnModifyForm +project,zen,buildProductForm +project,zen,getOtherProducts +project,zen,setProjectMenu +project,zen,processBuildListData +project,zen,buildMembers +project,zen,buildUsers +project,zen,expandExecutionIdList +project,zen,assignTesttaskVars +project,zen,getKanbanData +project,zen,getUnmodifiableProducts +projectrelease,zen,commonAction +projectrelease,zen,buildReleaseForCreate +release,zen,buildReleaseForCreate +release,zen,buildSearchForm +release,zen,getSearchQuery +release,zen,getExcludeStoryIdList +release,zen,assignVarsForView +release,zen,buildLinkStorySearchForm +release,zen,buildLinkBugSearchForm +release,zen,buildStoryDataForExport +release,zen,buildBugDataForExport +repo,zen,prepareCreate +repo,zen,prepareCreateRepo +repo,zen,prepareEdit +repo,zen,checkACL +repo,zen,checkClient +repo,zen,checkConnection +repo,zen,buildCreateForm +repo,zen,buildCreateRepoForm +repo,zen,buildEditForm +repo,zen,getNotExistRepos +repo,zen,getGitlabProjectsByApi +repo,zen,getFilesInfo +repo,zen,getBranchAndTagItems +repo,zen,updateLastCommit +repo,zen,getBrowseInfo +repo,zen,setBranchTag +repo,zen,getCommits +repo,zen,setBrowseSession +repo,zen,buildRepoSearchForm +repo,zen,getLinkModules +repo,zen,getLinkBranches +repo,zen,getLinkExecutions +repo,zen,buildStorySearchForm +repo,zen,getLinkStories +repo,zen,getDataPager +repo,zen,buildBugSearchForm +repo,zen,getLinkBugs +repo,zen,buildTaskSearchForm +repo,zen,getLinkTasks +repo,zen,linkObject +repo,zen,getSCM +repo,zen,checkDeleteError +repo,zen,locateDiffPage +repo,zen,encodingDiff +repo,zen,syncLocalCommit +repo,zen,getSyncBranches +repo,zen,checkSyncResult +repo,zen,setBackSession +repo,zen,setRepoBranch +repo,zen,isBinary +repo,zen,strposAry +repo,zen,getViewTree +repo,zen,checkRepoInternet +repo,zen,parseErrorContent +repo,zen,buildRepoPaths +repo,zen,buildRepoTree +repo,zen,getBranchAndTagOptions +repo,zen,processRepoID +repo,zen,buildSearchForm +repo,zen,getSearchForm +repo,zen,getSearchFormQuery +report,zen,getReminder +report,zen,assignAnnualReport +report,zen,assignAnnualBaseData +report,zen,assignAnnualData +screen,zen,commonAction +screen,zen,prepareCardList +screen,zen,setSelectFilter +search,zen,setSessionForIndex +search,zen,getTypeList +search,zen,setOptionFields +search,zen,setOptionOperators +search,zen,setOptionAndOr +search,zen,setOptions +sonarqube,zen,checkTokenRequire +sonarqube,zen,sortAndPage +sonarqube,zen,getIssueList +sso,zen,getFeishuAccessToken +sso,zen,getFeishuUserToken +sso,zen,getBindFeishuUser +sso,zen,buildUserForCreate +sso,zen,idenfyFromSSO +sso,zen,locateNotifyLink +sso,zen,buildLocationByGET +sso,zen,buildLocationByPATHINFO +sso,zen,buildSSOParams +sso,zen,computeAuth +store,zen,getInstalledApps +story,zen,setMenuForCreate +story,zen,setMenuForBatchCreate +story,zen,setMenuForBatchEdit +story,zen,setMenuForBatchClose +story,zen,setViewVarsForKanban +story,zen,initStoryForCreate +story,zen,getInitStoryByStory +story,zen,getInitStoryByBug +story,zen,getInitStoryByTodo +story,zen,getProductsAndBranchesForCreate +story,zen,getProductsForEdit +story,zen,getFormFieldsForCreate +story,zen,getFormFieldsForEdit +story,zen,getFormFieldsForChange +story,zen,getFormFieldsForReview +story,zen,setFormOptionsForBatchEdit +story,zen,getFormOptionsForSingleProduct +story,zen,getStoriesByChecked +story,zen,setModuleField +story,zen,removeFormFieldsForCreate +story,zen,hiddenFormFieldsForEdit +story,zen,removeFormFieldsForBatchCreate +story,zen,getAssignMeBlockID +story,zen,buildStoryForCreate +story,zen,buildStoryForEdit +story,zen,buildStoryForChange +story,zen,buildDataForBatchToTask +story,zen,processDataForEdit +story,zen,buildStoryForReview +story,zen,buildStoriesForBatchCreate +story,zen,buildStoriesForBatchEdit +story,zen,buildStoriesForBatchClose +story,zen,getResponseInModal +story,zen,getAfterEditLocation +story,zen,getAfterCreateLocation +story,zen,getAfterBatchCreateLocation +story,zen,getAfterChangeLocation +story,zen,getAfterReviewLocation +story,zen,getDataFromUploadImages +story,zen,getCustomFields +story,zen,getShowFields +story,zen,buildStoryForActivate +story,zen,buildStoryForSubmitReview +story,zen,getLinkedObjects +story,zen,setHiddenFieldsForView +story,zen,convertChildID +story,zen,processFilterTitle +system,zen,getCpuUsage +system,zen,getMemUsage +task,zen,assignCreateVars +task,zen,assignExecutionForCreate +task,zen,assignStoryForCreate +task,zen,assignKanbanForCreate +task,zen,assignBatchEditVars +task,zen,buildEditForm +task,zen,buildUsersAndMembersToForm +task,zen,buildBatchCreateForm +task,zen,buildRecordForm +task,zen,buildTaskForEdit +task,zen,buildTasksForBatchAssignTo +task,zen,buildTasksForBatchCreate +task,zen,buildTaskForCreate +task,zen,buildTasksForBatchEdit +task,zen,buildTaskForStart +task,zen,buildTaskForCancel +task,zen,buildTestTasksForCreate +task,zen,buildEffortForStart +task,zen,buildTaskForFinish +task,zen,buildEffortForFinish +task,zen,buildTaskForClose +task,zen,buildChartData +task,zen,commonAction +task,zen,checkLegallyDate +task,zen,checkCreateTask +task,zen,checkBatchCreateTask +task,zen,checkBatchEditTask +task,zen,checkCreateTestTasks +task,zen,formatExportTask +task,zen,getCustomFields +task,zen,getExportFields +task,zen,generalCreateResponse +task,zen,isLimitedInExecution +task,zen,prepareManageTeam +task,zen,processExportData +task,zen,processExportGroup +task,zen,processTaskByStatus +task,zen,responseAfterEdit +task,zen,responseAfterBatchEdit +task,zen,responseAfterAssignTo +task,zen,responseModal +task,zen,responseAfterCreate +task,zen,responseAfterbatchCreate +task,zen,responseAfterChangeStatus +task,zen,responseAfterRecord +task,zen,setTaskByObjectID +task,zen,checkGitRepo +task,zen,getAssignedToOptions +task,zen,getParentEstStartedAndDeadline +task,zen,processFilterTitle +task,zen,getReportTaskList +testcase,zen,checkProducts +testcase,zen,setBrowseCookie +testcase,zen,getBrowseBranch +testcase,zen,setBrowseSession +testcase,zen,setBrowseMenu +testcase,zen,setMenu +testcase,zen,buildBrowseSearchForm +testcase,zen,assignForImportFromLib +testcase,zen,assignCreateVars +testcase,zen,assignCreateSceneVars +testcase,zen,assignEditSceneVars +testcase,zen,assignModulesForCreate +testcase,zen,processCasesForBrowse +testcase,zen,assignCasesForBrowse +testcase,zen,assignModuleTreeForBrowse +testcase,zen,assignProductAndBranchForBrowse +testcase,zen,assignForBrowse +testcase,zen,prepareEditExtras +testcase,zen,preProcessForEdit +testcase,zen,setMenuForLibCaseEdit +testcase,zen,setMenuForCaseEdit +testcase,zen,assignForEditLibCase +testcase,zen,assignForEditCase +testcase,zen,assignBranchForEdit +testcase,zen,assignModuleOptionMenuForEdit +testcase,zen,assignForEdit +testcase,zen,assignForBatchEdit +testcase,zen,assignLibForBatchEdit +testcase,zen,assignTitleForBatchEdit +testcase,zen,assignModuleAndSceneForBatchEdit +testcase,zen,assignShowImportVars +testcase,zen,addEditAction +testcase,zen,assignCaseForView +testcase,zen,assignForBatchCreate +testcase,zen,buildCaseForCreate +testcase,zen,buildCasesForBathcCreate +testcase,zen,buildCasesForBathcEdit +testcase,zen,buildCasesForShowImport +testcase,zen,buildCasesByXmind +testcase,zen,buildDataForImportFromLib +testcase,zen,buildDataForImportToLib +testcase,zen,buildUpdateCaseForShowImport +testcase,zen,checkCreateFormData +testcase,zen,checkTestcasesForBatchCreate +testcase,zen,checkCasesForBatchEdit +testcase,zen,checkCasesForShowImport +testcase,zen,buildMindConfig +testcase,zen,initTestcase +testcase,zen,initLibCase +testcase,zen,importCases +testcase,zen,processScene +testcase,zen,processChildScene +testcase,zen,processStepsForMindMap +testcase,zen,processImportColumnKey +testcase,zen,getGroupCases +testcase,zen,afterCreate +testcase,zen,responseAfterCreate +testcase,zen,responseAfterBatchCreate +testcase,zen,responseAfterShowImport +testcase,zen,prepareReviewData +testcase,zen,buildLinkCasesSearchForm +testcase,zen,buildLinkBugsSearchForm +testcase,zen,getExportFields +testcase,zen,getMindExport +testcase,zen,getModuleListForXmindExport +testcase,zen,getImportedData +testcase,zen,getImportField +testcase,zen,getImportSteps +testcase,zen,processCasesForExport +testcase,zen,processCaseForExport +testcase,zen,processStepForExport +testcase,zen,processStageForExport +testcase,zen,processLinkCaseForExport +testcase,zen,processFileForExport +testcase,zen,processStepsAndExpectsForBatchEdit +testcase,zen,getFieldsForExportTemplate +testcase,zen,getRowsForExportTemplate +testcase,zen,getStatusForCreate +testcase,zen,getStatusForReview +testcase,zen,getStatusForUpdate +testcase,zen,createFreeMindXmlDoc +testcase,zen,getXmindExportData +testcase,zen,parseUploadFile +testcase,zen,fetchByXML +testcase,zen,fetchByJSON +testreport,zen,commonAction +testreport,zen,getReportsForBrowse +testreport,zen,assignTaskParisForCreate +testreport,zen,assignTesttaskReportData +testreport,zen,assignProjectReportDataForCreate +testreport,zen,assignProjectReportDataForEdit +testreport,zen,assignReportData +testreport,zen,buildReportDataForView +testreport,zen,prepareTestreportForCreate +testreport,zen,prepareTestreportForEdit +testreport,zen,buildReportBugData +testreport,zen,buildBugInfo +testreport,zen,getStageAndHandleGroups +testreport,zen,getGeneratedAndLegacyBugData +testreport,zen,getFoundBugGroups +testreport,zen,setChartDatas +testsuite,zen,checkTestsuiteAccess +testtask,zen,setMenu +testtask,zen,getBrowseBranch +testtask,zen,setSearchParamsForCases +testtask,zen,setSearchParamsForLinkCase +testtask,zen,buildTaskForEdit +testtask,zen,buildTaskForStart +testtask,zen,buildTaskForClose +testtask,zen,buildTaskForActivate +testtask,zen,buildTaskForBlock +testtask,zen,buildTaskForImportUnitResult +testtask,zen,checkTaskForEdit +testtask,zen,assignForCases +testtask,zen,assignForCreate +testtask,zen,assignForEdit +testtask,zen,assignForRunCase +testtask,zen,getProducts +testtask,zen,prepareSummaryForBrowse +testtask,zen,prepareCasesForBatchRun +testtask,zen,processRowspanForUnitCases +testtask,zen,processRowspanForGroupCase +testtask,zen,checkAndExecuteAutomatedTest +testtask,zen,responseAfterRunCase +testtask,zen,setDropMenu +todo,zen,buildCreateView +todo,zen,buildBatchCreateView +todo,zen,buildEditView +todo,zen,buildAssignToView +todo,zen,beforeCreate +todo,zen,addCycleYearConfig +todo,zen,prepareCreateData +todo,zen,afterCreate +todo,zen,beforeBatchCreate +todo,zen,beforeEdit +todo,zen,afterEdit +todo,zen,batchEditFromMyTodo +todo,zen,getBatchEditInitTodos +todo,zen,buildBatchEditView +todo,zen,beforeBatchEdit +todo,zen,afterBatchEdit +todo,zen,handleCycleConfig +todo,zen,setCycle +todo,zen,printStartConfirm +todo,zen,getProjectPairsByModel +todo,zen,buildAssignToTodoView +todo,zen,beforeAssignTo +todo,zen,doAssignTo +todo,zen,getUserById +todo,zen,setSessionUri +todo,zen,exportTodoInfo +todo,zen,exportAssociated +todo,zen,assembleExportData +transfer,zen,saveSession +transfer,zen,processTaskTemplateFields +transfer,zen,initTemplateFields +transfer,zen,formatFields +transfer,zen,buildNextList +transfer,zen,printRow +transfer,zen,printCell +transfer,zen,processEstimate +transfer,zen,process4Testcase +tree,zen,setRoot +tree,zen,getBranches +tree,zen,updateBrowseLang +tree,zen,updateWorkflowLang +tree,zen,updateRawModule +tree,zen,printOptionMenuMHtml +tree,zen,printOptionMenuArray +tree,zen,printOptionMenuHtml +user,zen,checkDirPermission +user,zen,checkTmp +user,zen,getUserForJSON +user,zen,login +user,zen,parseLoginModuleAndMethod +user,zen,prepareRolesAndGroups +user,zen,prepareCustomFields +user,zen,reloadLang +user,zen,responseForLogon +user,zen,responseForLocked +user,zen,responseForLoginFail +user,zen,setReferer +webhook,zen,getResponse +webhook,zen,getBoundUseridPairs +zahost,zen,getServiceStatus +zanode,zen,handleNode +zanode,zen,prepareCreateExtras +zanode,zen,prepareCreateSnapshotExtras +zanode,zen,getTaskStatus +zanode,zen,getServiceStatus +zanode,zen,installService diff --git a/.claude/zendata.yaml b/.claude/data/zendata.yaml similarity index 100% rename from .claude/zendata.yaml rename to .claude/data/zendata.yaml diff --git a/zentao-ui-test-guide.md b/.claude/rules/zentao-ui-test-guide.md similarity index 100% rename from zentao-ui-test-guide.md rename to .claude/rules/zentao-ui-test-guide.md diff --git a/zentao-unit-test-guide.md b/.claude/rules/zentao-unit-test-guide.md similarity index 83% rename from zentao-unit-test-guide.md rename to .claude/rules/zentao-unit-test-guide.md index 27f817e6a9..87ee3662a8 100644 --- a/zentao-unit-test-guide.md +++ b/.claude/rules/zentao-unit-test-guide.md @@ -13,6 +13,8 @@ ### 📝 统一占位符说明 **AI大模型必须严格按照以下占位符规范,保持命名一致性:** - `{moduleName}` - 模块名(小写,如:user、task、project) +- `{layerName}` - 业务分层(小写,如:model、tao、zen、control、ui) +- `{className}` - 类名(驼峰命名,如:userModel、taskTao、projectZen) - `{methodName}` - 方法名(驼峰命名,如:getById、createUser) - `{tableName}` - 数据表名(小写,如:user、task、project) - `{fieldName}` - 字段名(小写,如:id、name、status) @@ -30,43 +32,18 @@ --- **🚨🚨🚨 AI大模型必读警告 🚨🚨🚨** -**第一步:必须先切换到 feature/unittest/ai 分支!** -**第二步:每个测试用例必须包含至少5个测试步骤(r()...e()语句)!** -**第三步:必须使用 test/runtime/ztf 运行测试验证!** -**第四步:必须按照指定格式提交代码!** +**第一步:每个测试用例必须包含至少5个测试步骤(r()...e()语句)!** +**第二步:必须按照指定格式提交代码!必须使用 test/runtime/ztf 运行测试验证!** +**第三步:必须先使用 php 命令验证脚本没有错误再使用 test/runtime/ztf 验证测试是否通过** **⛔ 绝对禁止的行为:** -- 在开发分支上直接编写测试代码 - 测试步骤少于5个 -- 使用php命令直接运行测试 - 不遵循提交信息格式 - 代码包含行尾空格(会导致提交失败) +- 使用 `test/spider.php` 运行测试(必须使用 `test/runtime/ztf`) --- -## ⚠️ 重要:分支开发流程(必须执行) - -**任何单元测试脚本的开发都必须严格按照以下分支流程进行:** - -### 第一步:切换到测试分支(必须) -1. **测试分支名**:`feature/unittest/ai` -2. **检查当前分支**:确认当前处于测试分支 -3. **切换到测试分支**:如果当前没有处于测试分支,立即切换到测试分支进行开发 - -### 分支操作命令示例: -```bash -# 检查当前分支 -git branch - -# 切换到测试分支 -git switch feature/unittest/ai - -# 确认已切换到测试分支 -git branch -``` - -**🚨 警告:如果不切换到测试分支,将违反ZenTao开发规范,必须立即停止操作并切换到正确的分支!** - ## 🔍 核心概念说明 ### 🔑 关键概念:测试用例 vs 测试步骤 @@ -86,7 +63,7 @@ git branch **示例说明:** ```php // 这是一个测试用例:getUserById.php -r($userTest->getByIdTest(1)) && p('account') && e('admin'); // 测试步骤1:正常用户查询 +r($userTest->getByIdTest(1)) && p('account') && e('admin'); // 测试步骤1:正常用户查询 r($userTest->getByIdTest(999)) && p() && e(false); // 测试步骤2:不存在用户查询 r($userTest->getByIdTest(0)) && p() && e(false); // 测试步骤3:无效ID查询 r($userTest->getByIdTest(-1)) && p() && e(false); // 测试步骤4:负数ID查询 @@ -127,7 +104,7 @@ module/{moduleName}/test/ /** -title=测试 {moduleName}Model::{methodName}(); +title=测试 {className}::{methodName}(); cid=0 - 测试步骤1描述 @期望结果1 @@ -146,7 +123,7 @@ cid=0 /** -title=测试 {moduleName}Model::{methodName}(); +title=测试 {className}::{methodName}(); cid=0 - 测试步骤1:正常输入情况 >> 期望正常结果 @@ -399,42 +376,13 @@ fields: ## 单元测试开发完整流程(必须按顺序执行) -### 🔴 步骤1:切换到测试分支(AI大模型必须首先执行) - -**⚠️ AI大模型执行指令:在生成任何代码之前,必须先执行以下分支命令** - -#### 1.1 检查当前分支 -```bash -# 执行此命令查看当前分支 -git branch -git status -``` - -#### 1.2 切换到指定测试分支 -```bash -# 必须切换到这个分支,分支名固定不变 -git switch feature/unittest/ai -``` - -#### 1.3 验证切换成功 -```bash -# 确认当前分支标记为 * feature/unittest/ai -git branch -``` - -**🚨 AI执行检查点:** -- [ ] 已执行 `git branch` 命令 -- [ ] 已执行 `git switch feature/unittest/ai` 命令 -- [ ] 已确认当前在 feature/unittest/ai 分支 -- [ ] 如果分支不存在,需要先创建:`git checkout -b feature/unittest/ai` - -### 步骤2:分析待测方法 -1. 确定方法所属模块和层次(Model/TAO/ZEN) +### 步骤1:分析待测方法 +1. 确定方法所属模块和业务分层(model/tao/zen/control/ui) 2. 分析方法参数类型和返回值 3. 理解业务逻辑和数据依赖关系 4. 识别可能的异常情况 -### 步骤3:设计测试用例和测试步骤 +### 步骤2:设计测试用例和测试步骤 1. **设计测试用例**:每个测试脚本对应一个测试用例,用于测试单个方法 2. **设计测试步骤**:在测试用例中设计多个测试步骤来验证不同场景 - 正常流程测试步骤 @@ -444,13 +392,13 @@ git branch 4. 确定每个步骤的断言点和期望结果 5. **🔴 强制要求:每个测试用例必须包含至少5个测试步骤** -### 步骤4:创建YAML数据文件(如需要) +### 步骤3:创建YAML数据文件(如需要) 1. 分析方法依赖的数据表 2. 设计符合业务逻辑的测试数据 3. 使用适当的数据生成规则 4. 考虑数据之间的关联关系 -### 步骤5:编写测试脚本 +### 步骤4:编写测试脚本 1. 创建测试执行脚本,包含完整的测试用例描述 2. 测试脚本使用小写的方法名称作为文件名,后缀统一为.php 3. **🔴 强制要求:每个测试用例必须包含至少5个测试步骤(r()...e()语句)** @@ -458,20 +406,21 @@ git branch 5. 配置数据准备和环境设置 6. 为每个测试步骤编写准确的断言验证 -### 步骤6:验证测试脚本(AI大模型必须执行验证) +### 步骤5:验证测试脚本(AI大模型必须执行验证) -**🔴 强制要求:必须使用 ztf 运行器,禁止使用 php 命令直接运行** +**🔴 强制要求:必须先使用 php 命令运行脚本没有错误再使用 ztf 运行器验证** -#### 6.1 执行测试命令 +#### 5.1 执行测试命令 ```bash -# 切换到测试运行目录 -cd test/runtime -# 运行测试脚本(替换实际的模块名和方法名) -./ztf run ../../module/{moduleName}/test/model/{methodName}.php +# 使用 php 命令运行测试脚本,检查是否有错误 +php module/{moduleName}/test/{layerName}/{methodName}.php + +# 使用 ztf 运行测试脚本 +test/runtime/ztf module/{moduleName}/test/{layerName}/{methodName}.php ``` -#### 6.2 验证测试结果 +#### 5.2 验证测试结果 **✅ 测试通过标准:** - 通过数(PASS):1 - 失败数(FAIL):0 @@ -483,43 +432,36 @@ cd test/runtime 3. 验证断言是否匹配实际结果 4. 修改测试脚本后重新运行 -#### 6.3 AI执行检查点 -- [ ] 已切换到 test/runtime 目录 -- [ ] 已使用 ztf 命令运行测试 +#### 5.3 AI执行检查点 +- [ ] 已使用 php 命令运行测试脚本,确认无错误 +- [ ] 已使用 test/runtime/ztf 命令运行测试 - [ ] 测试结果显示 PASS=1, FAIL=0, SKIP=0 - [ ] 如有失败,已根据错误信息修正代码 -### 🔴 步骤7:提交和推送代码(强制要求) +### 🔴 步骤6:提交代码(强制要求) **测试验证通过后,必须按以下步骤提交代码:** 1. **添加测试文件到git(仅添加测试相关文件)**: ```bash git add module/{moduleName}/test/lib/{moduleName}.unittest.class.php - git add module/{moduleName}/test/model/{methodName}.php - git add module/{moduleName}/test/model/yaml/{tableName}_{methodName}.yaml - # 注意:不要添加规范文档文件到测试分支!规范文档应保留在开发分支上 + git add module/{moduleName}/test/{layerName}/{methodName}.php + git add module/{moduleName}/test/{layerName}/yaml/{tableName}_{methodName}.yaml ``` 2. **提交代码**: ```bash - git commit -m "+ [misc] Add unit tests for {moduleName}::{methodName}() method + git commit -m "+ [misc] Add unit tests for {className}::{methodName}() method 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude " ``` -3. **推送到远程仓库**: - - ```bash - git push - ``` - **⚠️ AI大模型提交信息模板(必须严格遵循):** ```bash -git commit -m "+ [misc] Add unit tests for {moduleName}::{methodName}() method +git commit -m "+ [misc] Add unit tests for {className}::{methodName}() method 🤖 Generated with [Claude Code](https://claude.ai/code) @@ -529,7 +471,7 @@ Co-Authored-By: Claude " **📋 提交信息格式说明:** - **符号**:`+` (新增测试) / `*` (修改测试) / `-` (删除测试) - **分类**:`[misc]` (测试相关固定使用misc) -- **描述**:`Add unit tests for {moduleName}::{methodName}() method` +- **描述**:`Add unit tests for {className}::{methodName}() method` - **标识**:必须包含Claude Code和Co-Authored-By标记 ## 常见测试模式 @@ -688,7 +630,7 @@ r($userTest->createTest($invalidUser)) && p('errors,account') && e('用户名不 - 理解被测方法的业务逻辑 - 分析被测方法涉及的数据库表 - 理解数据库表的结构 -- 表结构定义参考db/zentao.sql +- 表结构定义参考 `db/zentao.sql` ## 注意事项 @@ -716,10 +658,6 @@ r($userTest->createTest($invalidUser)) && p('errors,account') && e('用户名不 ### 🔴 AI大模型强制检查清单(每项必须100%完成) -**📋 分支操作检查** -- [ ] 已执行 `git switch feature/unittest/ai` 切换分支 -- [ ] 已确认当前在 `feature/unittest/ai` 分支(git branch 显示*号) - **📋 代码生成检查** - [ ] 测试文件名使用小写方法名:`{methodName}.php` - [ ] 单元测试类名格式:`{moduleName}Test` @@ -729,14 +667,14 @@ r($userTest->createTest($invalidUser)) && p('errors,account') && e('用户名不 - [ ] **🚨 所有代码行尾无空格**:检查每行末尾是否清洁 **📋 测试验证检查** -- [ ] 已使用 `cd test/runtime && ./ztf run` 命令运行测试 +- [ ] 已使用 `php` 命令验证测试脚本无语法错误 +- [ ] 已使用 `test/runtime/ztf` 命令运行测试 - [ ] 测试结果:PASS=1, FAIL=0, SKIP=0 - [ ] 所有断言都与实际输出匹配 **📋 代码提交检查** - [ ] 已添加测试相关文件:`git add module/{moduleName}/test/...` - [ ] 提交信息符合格式:`+ [misc] Add unit tests for...` -- [ ] 已推送到远程:`git push` ### 📝 代码质量检查项 - [ ] **测试步骤完整**:测试用例包含正常流程、边界值、异常情况等测试步骤 @@ -745,14 +683,9 @@ r($userTest->createTest($invalidUser)) && p('errors,account') && e('用户名不 - [ ] **注释清晰**:测试步骤描述明确,期望结果准确 ### ⚠️ 常见错误避免 -- [ ] **避免直接在开发分支开发**:必须在测试分支上进行开发 -- [ ] **避免使用php直接运行测试**:必须使用ztf运行器验证 -- [ ] **避免不提交代码**:测试通过后必须提交并推送代码 -- [ ] **避免将规范文档提交到测试分支**:规范文档应该保留在开发分支供后续参照使用 +- [ ] **避免不提交代码**:测试通过后必须提交代码 - [ ] **🚨 避免行尾空格**:所有生成的代码必须移除行尾空格,否则提交会被拒绝 --- **🎯 最终目标:通过遵循本指导文档,生成高质量、可维护的ZenTao单元测试脚本,确保代码质量和系统稳定性。** - -**🚨 重要提醒:任何跳过分支管理步骤的行为都违反了ZenTao开发规范,必须严格按照流程执行!** diff --git a/zentao-view-to-ui-guide.md b/.claude/rules/zentao-view-to-ui-guide.md similarity index 100% rename from zentao-view-to-ui-guide.md rename to .claude/rules/zentao-view-to-ui-guide.md diff --git a/.claude/scripts/unit_test_generator.sh b/.claude/scripts/unit_test_generator.sh new file mode 100755 index 0000000000..6b1ef77dbc --- /dev/null +++ b/.claude/scripts/unit_test_generator.sh @@ -0,0 +1,264 @@ +#!/bin/bash + +# 自动生成单元测试脚本 +# 作者: Auto-generated script +# 日期: $(date +%Y-%m-%d) + +echo_usage() { + echo "Usage: $0 [-c] [-s START_LINE] " + echo "This script generates unit test scripts based on the provided CSV file." + echo " -c Continue processing on error (default is to break)." + echo " -s START_LINE Start processing from line START_LINE. Default is 2 (the first line is header)." + exit 1 +} + +# 检查参数数量 +if [ "$#" -eq 0 ]; then + echo_usage +fi + +# 检查是否提供了 CSV 文件名 +if [ -z "$1" ]; then + echo_usage +fi + +# 错误处理策略 +ON_ERROR_STRATEGY="break" # 默认为 break + +# 默认从第2行开始(跳过标题行) +START_LINE=2 + +# 解析命令行选项 +while getopts ":cs:" opt; do # 注意 's:' 表示 s 选项需要一个参数 + case ${opt} in + c ) + ON_ERROR_STRATEGY="continue" + ;; + s ) + # 验证 START_LINE 是否为正整数 + if ! [[ "$OPTARG" =~ ^[0-9]+$ ]] || [ "$OPTARG" -lt 1 ]; then + echo "Invalid start line: '$OPTARG'. Must be a positive integer." + exit 1 + fi + START_LINE="$OPTARG" + ;; + \? ) + echo "Invalid Option: -$OPTARG" 1>&2 + exit 1 + ;; + : ) + echo "Invalid Option: -$OPTARG requires an argument" 1>&2 + exit 1 + ;; + esac +done + +# 移除已处理的选项和参数 +shift $((OPTIND -1)) + +# 设置变量 +BASE_PATH=$(readlink -f "$(dirname "${BASH_SOURCE[0]}")/../..") +GUIDE_FILE="$BASE_PATH/.claude/rules/zentao-unit-test-guide.md" +CSV_FILE="$BASE_PATH/.claude/data/$1" +LOG_FILE="$BASE_PATH/tmp/log/unit_test_generation_$(date +%Y%m%d_%H%M%S).log" + +CURRENT_LINE=0 +TOTAL_PROCESSED=0 +TOTAL_SKIPPED=0 +TOTAL_GENERATED=0 + +# 检查必要文件和工具 +check_prerequisites() { + echo "$(date '+%Y-%m-%d %H:%M:%S') [INFO] 检查前置条件..." | tee -a "$LOG_FILE" + + if [ ! -f "$CSV_FILE" ]; then + echo "$(date '+%Y-%m-%d %H:%M:%S') [ERROR] CSV文件不存在: $CSV_FILE" | tee -a "$LOG_FILE" + exit 1 + fi + + if ! command -v claude &> /dev/null; then + echo "$(date '+%Y-%m-%d %H:%M:%S') [ERROR] claude命令未找到,请确保已安装Claude CLI" | tee -a "$LOG_FILE" + exit 1 + fi + + if [ ! -d "$BASE_PATH" ]; then + echo "$(date '+%Y-%m-%d %H:%M:%S') [ERROR] 基础路径不存在: $BASE_PATH" | tee -a "$LOG_FILE" + exit 1 + fi + + echo "$(date '+%Y-%m-%d %H:%M:%S') [INFO] 前置条件检查完成" | tee -a "$LOG_FILE" +} + +# 调用Claude生成测试脚本 +claude_generate_test() { + local claude_command="$1" + local test_file_path="$2" + local retry_count="${3:-0}" # 添加重试计数参数,默认为0 + + # 设置最大重试次数 + local max_retries=12 + + # 检查是否超过最大重试次数 + if [ "$retry_count" -ge "$max_retries" ]; then + echo "$(date '+%Y-%m-%d %H:%M:%S') [ERROR] 达到最大重试次数($max_retries),放弃处理第 $CURRENT_LINE 行" | tee -a "$LOG_FILE" + return 1 + fi + + echo "$(date '+%Y-%m-%d %H:%M:%S') [INFO] 执行Claude命令: $claude_command" | tee -a "$LOG_FILE" + + # 执行Claude命令并捕获输出 + local claude_output + if claude_output=$($claude_command < /dev/null 2>&1); then + echo "$(date '+%Y-%m-%d %H:%M:%S') [SUCCESS] Claude命令执行成功" | tee -a "$LOG_FILE" + + # 记录测试文件已生成到日志 + echo "$(date '+%Y-%m-%d %H:%M:%S') [INFO] 测试文件已生成: $test_file_path" | tee -a "$LOG_FILE" + + # 记录详细的Claude输出到日志 + echo "$(date '+%Y-%m-%d %H:%M:%S') [DEBUG] Claude输出内容:" | tee -a "$LOG_FILE" + echo "--- 开始输出 ---" | tee -a "$LOG_FILE" + echo "$claude_output" | tee -a "$LOG_FILE" + echo "--- 结束输出 ---" | tee -a "$LOG_FILE" + + ((TOTAL_GENERATED++)) + else + echo "$(date '+%Y-%m-%d %H:%M:%S') [ERROR] Claude命令执行失败" | tee -a "$LOG_FILE" + echo "$(date '+%Y-%m-%d %H:%M:%S') [ERROR] 错误信息: $claude_output" | tee -a "$LOG_FILE" + echo "$(date '+%Y-%m-%d %H:%M:%S') [INFO] 等待5分钟后重试..." | tee -a "$LOG_FILE" + + # 等待5分钟 + sleep 300 + + # 递归重试 + claude_generate_test "$claude_command" "$test_file_path" "$((retry_count + 1))" + + # 返回递归调用的结果 + return $? + fi + + return 0 +} + +# 处理单个方法的单元测试生成 +process_method() { + local module="$1" + local class="$2" + local method="$3" + + echo "$(date '+%Y-%m-%d %H:%M:%S') [INFO] 处理第 $CURRENT_LINE 行: 模块=$module, 类=$class, 方法=$method" | tee -a "$LOG_FILE" + + # 构建测试文件路径(方法名转为小写) + local method_lower=$(echo "$method" | tr '[:upper:]' '[:lower:]') + local test_file_path="$BASE_PATH/module/$module/test/$class/$method_lower.php" + + # 检查测试文件是否存在 + if [ -f "$test_file_path" ]; then + echo "$(date '+%Y-%m-%d %H:%M:%S') [INFO] 测试文件已存在,跳过: $test_file_path" | tee -a "$LOG_FILE" + ((TOTAL_SKIPPED++)) + return 0 + fi + + echo "$(date '+%Y-%m-%d %H:%M:%S') [INFO] 测试文件不存在,开始生成: $test_file_path" | tee -a "$LOG_FILE" + + # 创建测试目录(如果不存在) + local test_dir="$BASE_PATH/module/$module/test/$class" + if [ ! -d "$test_dir" ]; then + echo "$(date '+%Y-%m-%d %H:%M:%S') [INFO] 创建测试目录: $test_dir" | tee -a "$LOG_FILE" + mkdir -p "$test_dir" + fi + + # 构建Claude命令 + local claude_prompt="根据$GUIDE_FILE文档的内容为$module模块的$class.php文件中的$method方法生成单元测试脚本。" + local claude_command="claude -p \"$claude_prompt\" --dangerously-skip-permissions" + + # 调用Claude生成测试脚本 + claude_generate_test "$claude_command" "$test_file_path" + + # 返回Claude生成测试脚本的结果 + return $? +} + +# 主处理函数 +main() { + echo "$(date '+%Y-%m-%d %H:%M:%S') [INFO] ========== 开始执行单元测试生成脚本 ==========" | tee -a "$LOG_FILE" + + # 检查前置条件 + check_prerequisites + + # 读取CSV文件(跳过第一行标题) + local line_count=$(wc -l < "$CSV_FILE") + echo "$(date '+%Y-%m-%d %H:%M:%S') [INFO] CSV文件总行数: $line_count (包含标题行)" | tee -a "$LOG_FILE" + echo "$(date '+%Y-%m-%d %H:%M:%S') [INFO] 从第 $START_LINE 行开始处理 (跳过前面的数据行和标题行)." | tee -a "$LOG_FILE" + + # 使用while循环读取CSV文件 + while IFS=',' read -r module class method || [ -n "$module" ]; do + ((CURRENT_LINE++)) + + # 跳过标题行 + if [ $CURRENT_LINE -eq 1 ]; then + echo "$(date '+%Y-%m-%d %H:%M:%S') [INFO] 跳过标题行" | tee -a "$LOG_FILE" + continue + fi + + # 跳过指定行数之前的数据行和标题行 + if [ $CURRENT_LINE -lt $START_LINE ]; then + echo "$(date '+%Y-%m-%d %H:%M:%S') [INFO] 跳过第 $CURRENT_LINE 行 (在起始行 $START_LINE 之前)." | tee -a "$LOG_FILE" + continue + fi + + # 清理字段中的回车符和空白字符 + module=$(echo "$module" | tr -d '\r\n' | xargs) + class=$(echo "$class" | tr -d '\r\n' | xargs) + method=$(echo "$method" | tr -d '\r\n' | xargs) + + # 跳过空行 + if [ -z "$module" ] || [ -z "$class" ] || [ -z "$method" ]; then + echo "$(date '+%Y-%m-%d %H:%M:%S') [WARN] 第 $CURRENT_LINE 行数据不完整,跳过: 模块=$module, 类=$class, 方法=$method" | tee -a "$LOG_FILE" + continue + fi + + # 处理当前方法 + if process_method "$module" "$class" "$method"; then + echo "$(date '+%Y-%m-%d %H:%M:%S') [SUCCESS] 第 $CURRENT_LINE 行处理完成" | tee -a "$LOG_FILE" + else + echo "$(date '+%Y-%m-%d %H:%M:%S') [ERROR] 第 $CURRENT_LINE 行处理失败" | tee -a "$LOG_FILE" + + # 根据错误处理策略决定是否继续 + if [ "$ON_ERROR_STRATEGY" == "break" ]; then + break + else + continue + fi + fi + + ((TOTAL_PROCESSED++)) + + # 进度提示 + if [ $((TOTAL_PROCESSED % 10)) -eq 0 ]; then + echo "$(date '+%Y-%m-%d %H:%M:%S') [PROGRESS] 已处理 $TOTAL_PROCESSED 个方法" | tee -a "$LOG_FILE" + fi + + done < "$CSV_FILE" + + # 输出统计信息 + echo "$(date '+%Y-%m-%d %H:%M:%S') [INFO] ========== 执行完成 ==========" | tee -a "$LOG_FILE" + echo "$(date '+%Y-%m-%d %H:%M:%S') [STATS] 总处理数量: $TOTAL_PROCESSED" | tee -a "$LOG_FILE" + echo "$(date '+%Y-%m-%d %H:%M:%S') [STATS] 跳过数量: $TOTAL_SKIPPED" | tee -a "$LOG_FILE" + echo "$(date '+%Y-%m-%d %H:%M:%S') [STATS] 生成数量: $TOTAL_GENERATED" | tee -a "$LOG_FILE" + echo "$(date '+%Y-%m-%d %H:%M:%S') [INFO] 日志文件: $LOG_FILE" | tee -a "$LOG_FILE" +} + +# 信号处理函数 +cleanup() { + echo "$(date '+%Y-%m-%d %H:%M:%S') [INFO] 接收到中断信号,正在清理..." | tee -a "$LOG_FILE" + echo "$(date '+%Y-%m-%d %H:%M:%S') [STATS] 中断前已处理: $TOTAL_PROCESSED 个方法" | tee -a "$LOG_FILE" + exit 130 +} + +# 注册信号处理 +trap cleanup INT TERM + +# 执行主函数 +main + +echo "$(date '+%Y-%m-%d %H:%M:%S') [INFO] 脚本执行完成!" | tee -a "$LOG_FILE" diff --git a/.claude/scripts/unit_test_monitor.sh b/.claude/scripts/unit_test_monitor.sh new file mode 100755 index 0000000000..64b555cc9d --- /dev/null +++ b/.claude/scripts/unit_test_monitor.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +CURRENT_DIR="$(dirname "$(readlink -f "$0")")" +SCRIPT_NAME="unit_test_generator.sh" +SCRIPT_PATH="$CURRENT_DIR/$SCRIPT_NAME" +LOG_FILE="/tmp/unit_test_monitor.log" + +# 检测进程是否存在 +if ! pgrep -f "$SCRIPT_NAME" > /dev/null; then + # 重启脚本并记录日志 + nohup bash "$SCRIPT_PATH" 2>&1 & + echo "$(date '+%Y-%m-%d %H:%M:%S') - 进程未运行,已重启" >> "$LOG_FILE" +else + echo "$(date '+%Y-%m-%d %H:%M:%S') - 进程正常运行" >> "$LOG_FILE" +fi diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..b712ac0413 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# .gitattributes +.claude/** -diff diff --git a/.gitfox/unittestcheck.yaml b/.gitfox/unittestcheck.yaml index 03f1b4cb0a..b2d2209d09 100644 --- a/.gitfox/unittestcheck.yaml +++ b/.gitfox/unittestcheck.yaml @@ -86,8 +86,12 @@ spec: ${GITFOX_WORKSPACE_BASE} - ls -l $ZENTAO_RELEASE_PATH - ls -l $ZENTAO_BUILD_PATH - - cp -rf $ZENTAO_BUILD_PATH/zentaopms/* . + - mkdir ${GITFOX_WORKSPACE_BASE}/testcode + - cp -rf $ZENTAO_BUILD_PATH/zentaopms/* ${GITFOX_WORKSPACE_BASE}/testcode && cp -r ${GITFOX_WORKSPACE_BASE}/zentaopms/test ${GITFOX_WORKSPACE_BASE}/testcode/ + - cd ${GITFOX_WORKSPACE_BASE}/testcode - rm -rf tmp + - echo "edition = 'ipd';" + - echo "edition = 'ipd';" > config/ext/edition.php - name: 镜像构建 type: run spec: @@ -104,7 +108,7 @@ spec: --build-arg VERSION=${ZENTAO_VERSION} --build-arg MIRROR=true -t hub.qc.oop.cc/zentao-ztf:${GITFOX_BUILD_NUMBER}-${GITFOX_COMMIT} - -f misc/ci/Dockerfile.test . + -f misc/ci/Dockerfile.test ${GITFOX_WORKSPACE_BASE}/testcode - name: unit test type: run spec: diff --git a/Makefile b/Makefile index 1a10f03c1b..588e93b310 100644 --- a/Makefile +++ b/Makefile @@ -69,8 +69,7 @@ common: # delete the unused files. find zentaopms -name .gitkeep |xargs rm -fr find zentaopms -name tests |xargs rm -fr - echo $(DELETE_TEST) - if [ "$(DELETE_TEST)" = "true" ]; then find zentaopms -name test |xargs rm -fr; fi + if [ "$(DELETE_TEST)" != "false" ]; then find zentaopms -name test |xargs rm -fr; fi # notify.zip. mkdir zentaopms/www/data/notify/ zentaoxx: @@ -226,7 +225,7 @@ package: #rm -r zentaopms/module/misc/ext rm -rf zentaopms/misc rm -rf zentaopms/extension/xuanxuan - if [ "$(DELETE_TEST)" = "true" ]; then find zentaopms/module -type d -name 'test' -maxdepth 2 -exec rm -rf {} +; fi + if [ "$(DELETE_TEST)" != "false" ]; then find zentaopms/module -type d -name 'test' -maxdepth 2 -exec rm -rf {} +; fi pms: make common make zentaoxx diff --git a/QWEN.md b/QWEN.md new file mode 100644 index 0000000000..a798dae30e --- /dev/null +++ b/QWEN.md @@ -0,0 +1,183 @@ +# 禅道PMS项目上下文 + +## 交互 +始终用中文回复。 + +## 项目概述 + +禅道PMS(项目管理系统)是由禅道软件(青岛)有限公司开发的开源项目管理软件。它是中国第一个开源项目管理软件,旨在覆盖从产品和项目管理到质量管理、文档管理、组织管理和办公管理的主要项目管理流程。 + +### 主要特性 + +- 基于禅道PHP框架构建 +- 支持多种项目管理方法论:Scrum、瀑布和看板 +- 全面的功能包括产品管理、项目管理、质量管理、文档管理 +- 多语言支持(中文、英文、德语、法语等) +- 丰富的模块包括数据可视化、度量、DevOps、文档资产管理、自动化测试 +- 版本21.7.5(根据VERSION文件) + +### 架构 + +禅道采用模块化MVC架构: +- **框架**:位于`/framework`的自定义PHP框架 +- **模块**:位于`/module`的功能模块(如产品、项目、执行、缺陷、任务等) +- **数据库**:基于MySQL,模式在`/db/zentao.sql`中定义 +- **Web界面**:位于`/www`的基于PHP的Web应用程序 +- **配置**:位于`/config`的集中配置 + +## 项目结构 + +``` +zentaopms/ +├── api/ # API相关文件 +├── bin/ # 可执行二进制文件/脚本 +├── config/ # 配置文件 +├── db/ # 数据库模式文件 +├── doc/ # 文档 +├── extension/ # 扩展模块 +├── framework/ # 核心框架文件 +├── lib/ # 库文件 +├── misc/ # 杂项文件 +├── module/ # 应用模块 +├── sdk/ # 软件开发工具包 +├── tmp/ # 临时文件 +├── www/ # Web根目录 +└── README.md # 项目文档 +``` + +## 构建和运行 + +### 先决条件 + +- PHP 8.1或更高版本 +- MySQL数据库 +- Apache或Nginx Web服务器 + +### 构建过程 + +项目使用Makefile进行构建: + +1. **清理构建环境**:`make clean` +2. **构建应用程序**:`make`或`make all` +3. **创建包**:`make package` +4. **创建分发版**:`make pms` + +构建过程: +- 将必要文件复制到`zentaopms`目录 +- 处理和压缩JavaScript/CSS资源 +- 设置适当权限 +- 创建分发包(ZIP、tar.xz) + +### 安装 + +1. 将分发包解压到Web服务器目录 +2. 在`config/my.php`中配置数据库设置(从`config/config.php`复制) +3. 访问Web界面并按照安装向导操作 +4. 如果未安装,系统将自动重定向到`install.php` + +### 开发环境运行 + +1. 将源代码放置在Web服务器的文档根目录中 +2. 配置Web服务器以服务PHP文件 +3. 确保以下目录可写: + - `tmp/` + - `www/data/` + - `config/` + - `extension/` + +### 生产环境运行 + +1. 使用`make pms`构建分发包 +2. 解压到生产服务器 +3. 设置目录的适当权限 +4. 在`config/my.php`中配置数据库连接 +5. 通过Web浏览器访问以完成安装 + +## 配置 + +### 主配置 + +主配置在`config/config.php`中,重要设置包括: + +- 数据库连接设置 +- 请求路由配置 +- 语言和主题设置 +- 安全设置 +- 文件上传限制 + +### 自定义配置 + +创建`config/my.php`来覆盖默认设置: +- 从`config/config.php`复制 +- 修改数据库连接设置 +- 根据需要调整其他配置 + +### 数据库配置 + +数据库表在`config/zentaopms.php`中定义为常量: +- 表前缀:默认为`zt_` +- 超过100个表用于不同功能 +- 模式在`db/zentao.sql`中定义 + +## 开发规范 + +### 代码结构 + +- 遵循MVC模式,包含模型、视图和控制器 +- 模块组织在`/module/{module}/`目录中 +- 每个模块通常包含: + - `model.php`:业务逻辑 + - `control.php`:控制器动作 + - `view/`:模板文件 + - `lang/`:语言文件 + - `js/`:模块特定的JavaScript + - `css/`:模块特定的CSS + +### 路由 + +- 默认路由:`index.php?m={module}&f={method}` +- PATH_INFO路由:`index.php/{module}-{method}` +- 可在`config/routes.php`中自定义API路由 + +### 数据库访问 + +- 使用自定义DAO(数据访问对象)模式 +- 定义在`lib/base/dao/`中 +- 示例:`$this->dao->select('*')->from(TABLE_USER)->where('id')->eq($id)->fetch()` + +### 测试 + +- 测试位于模块目录下的`test/`中 + +## 主要模块 + +禅道具有广泛的模块结构: +- **产品管理**:product、story、productplan、release +- **项目管理**:project、execution、task、build +- **质量管理**:bug、testcase、testtask、testsuite +- **文档管理**:doc、doclib +- **组织管理**:company、dept、user、group +- **DevOps**:repo、job、compile、mr +- **报表**:report、pivot、chart +- **管理**:admin、custom、extension + +## API和集成 + +- 通过`api.php`提供RESTful API +- Webhooks支持集成 +- 支持GitLab、Gogs、Gitea、Jenkins、SonarQube +- Xuanxuan集成用于消息传递 + +## 安全 + +- 输入验证和过滤 +- XSS防护 +- CSRF防护 +- 通过DAO防止SQL注入 +- 文件上传限制 + +## 国际化 + +- 多语言支持,语言文件在`/module/{module}/lang/`中 +- 支持的语言:简体中文、繁体中文、英文、德语、法语、越南语、日语、西班牙语、葡萄牙语 +- 语言选择可在用户偏好中配置 diff --git a/api/v1/entries/bug.php b/api/v1/entries/bug.php index 1e7d0020d4..d36634bc22 100644 --- a/api/v1/entries/bug.php +++ b/api/v1/entries/bug.php @@ -95,7 +95,7 @@ class bugEntry extends entry $oldBug = $this->loadModel('bug')->getByID($bugID); /* Set $_POST variables. */ - $fields = 'uid,title,project,execution,openedBuild,assignedTo,pri,severity,type,story,resolvedBy,resolvedBuild,closedBy,resolution,product,plan,task,module,steps,mailto,keywords,deadline'; + $fields = 'uid,title,project,execution,openedBuild,assignedTo,pri,severity,type,story,resolvedBy,resolvedBuild,resolvedDate,closedBy,resolution,product,plan,task,module,steps,mailto,keywords,deadline'; $this->batchSetPost($fields, $oldBug); $this->setPost('notifyEmail', implode(',', $this->request('notifyEmail', array()))); diff --git a/api/v1/entries/bugs.php b/api/v1/entries/bugs.php index 79e9286ddb..3b2039363a 100644 --- a/api/v1/entries/bugs.php +++ b/api/v1/entries/bugs.php @@ -66,7 +66,7 @@ class bugsEntry extends entry $control = $this->loadController('bug', 'create'); - $fields = 'title,project,execution,openedBuild,assignedTo,pri,module,severity,type,story,task,mailto,keywords,steps,uid,deadline'; + $fields = 'title,project,execution,openedBuild,browser,os,assignedTo,pri,module,severity,type,story,task,mailto,keywords,steps,uid,deadline'; $this->batchSetPost($fields); $caseID = $this->request('case', 0); diff --git a/api/v1/entries/executions.php b/api/v1/entries/executions.php index 6e2b173e24..eb0d54dd32 100644 --- a/api/v1/entries/executions.php +++ b/api/v1/entries/executions.php @@ -88,15 +88,16 @@ class executionsEntry extends entry $this->batchSetPost($fields); $projectID = $this->param('project', $projectID); - $this->setPost('project', $projectID); - $this->setPost('acl', $this->request('acl', 'private')); - $this->setPost('PO', $this->request('PO', '')); - $this->setPost('PM', $this->request('PM', '')); - $this->setPost('QD', $this->request('QD', '')); - $this->setPost('RD', $this->request('RD', '')); - $this->setPost('whitelist', $this->request('whitelist', array())); - $this->setPost('products', $this->request('products', array())); - $this->setPost('plans', $this->request('plans', array())); + $this->setPost('project', $projectID); + $this->setPost('acl', $this->request('acl', 'private')); + $this->setPost('PO', $this->request('PO', '')); + $this->setPost('PM', $this->request('PM', '')); + $this->setPost('QD', $this->request('QD', '')); + $this->setPost('RD', $this->request('RD', '')); + $this->setPost('whitelist', $this->request('whitelist', array())); + $this->setPost('products', $this->request('products', array())); + $this->setPost('plans', $this->request('plans', array())); + $this->setPost('teamMembers', $this->request('teamMembers', array())); $requireFields = 'name,begin,end'; if($useCode) $requireFields .= ',code'; diff --git a/config/zentaopms.php b/config/zentaopms.php index 5a04896936..76df6ccd77 100644 --- a/config/zentaopms.php +++ b/config/zentaopms.php @@ -653,6 +653,8 @@ if(!defined('TABLE_SYSTEM')) define('TABLE_SYSTEM', '`' . $config->db->p define('JIRA_TMPRELATION', '`jiratmprelation`'); define('CONFLUENCE_TMPRELATION', '`confluencetmprelation`'); +if(!defined('FIRST_RELEASE_DATE')) define('FIRST_RELEASE_DATE', '2010-05-03'); + $config->objectTables['dept'] = TABLE_DEPT; $config->objectTables['product'] = TABLE_PRODUCT; $config->objectTables['productplan'] = TABLE_PRODUCTPLAN; diff --git a/db/standard/zentao21.7.5.sql b/db/standard/zentao21.7.5.sql index 11922bf3a3..073d9d3c27 100644 --- a/db/standard/zentao21.7.5.sql +++ b/db/standard/zentao21.7.5.sql @@ -676,9 +676,9 @@ CREATE TABLE `zt_bug` ( KEY `assignedTo` (`assignedTo`), KEY `deleted` (`deleted`), KEY `project` (`project`), - KEY `feedback` (`feedback`), KEY `product_status_deleted` (`product`,`status`,`deleted`), - KEY `idx_repo` (`repo`) + KEY `idx_repo` (`repo`), + KEY `feedback` (`feedback`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; CREATE TABLE `zt_build` ( `id` mediumint unsigned NOT NULL AUTO_INCREMENT, @@ -745,7 +745,7 @@ CREATE TABLE `zt_case` ( `subStatus` varchar(30) NOT NULL DEFAULT '', `color` char(7) NOT NULL DEFAULT '', `frequency` enum('1','2','3') NOT NULL DEFAULT '1', - `order` tinyint unsigned NOT NULL DEFAULT '0', + `order` mediumint unsigned NOT NULL DEFAULT '0', `openedBy` char(30) NOT NULL DEFAULT '', `openedDate` datetime DEFAULT NULL, `reviewedBy` varchar(255) NOT NULL DEFAULT '', @@ -1803,8 +1803,8 @@ CREATE TABLE `zt_kanbancell` ( `type` char(30) NOT NULL DEFAULT '', `cards` mediumtext, PRIMARY KEY (`id`), - KEY `lane` (`lane`), - UNIQUE KEY `card_group` (`kanban`,`type`,`lane`,`column`) + UNIQUE KEY `card_group` (`kanban`,`type`,`lane`,`column`), + KEY `lane` (`lane`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; CREATE TABLE `zt_kanbancolumn` ( `id` int NOT NULL AUTO_INCREMENT, @@ -3416,9 +3416,9 @@ CREATE TABLE `zt_story` ( KEY `parent` (`parent`), KEY `product` (`product`), KEY `root` (`root`), - KEY `feedback` (`feedback`), KEY `status` (`status`), - KEY `assignedTo` (`assignedTo`) + KEY `assignedTo` (`assignedTo`), + KEY `feedback` (`feedback`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; CREATE TABLE `zt_storyestimate` ( `story` mediumint NOT NULL DEFAULT '0', @@ -3555,8 +3555,8 @@ CREATE TABLE `zt_task` ( KEY `parent` (`parent`), KEY `path` (`path`), KEY `assignedTo` (`assignedTo`), - KEY `feedback` (`feedback`), - KEY `order` (`order`) + KEY `order` (`order`), + KEY `feedback` (`feedback`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; CREATE TABLE `zt_taskestimate` ( `id` mediumint unsigned NOT NULL AUTO_INCREMENT, @@ -3752,8 +3752,8 @@ CREATE TABLE `zt_ticket` ( `deleted` enum('0','1') NOT NULL DEFAULT '0', `subStatus` varchar(30) NOT NULL DEFAULT '', PRIMARY KEY (`id`), - KEY `feedback` (`feedback`), - KEY `product` (`product`) + KEY `product` (`product`), + KEY `feedback` (`feedback`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; CREATE TABLE `zt_ticketrelation` ( `id` mediumint unsigned NOT NULL AUTO_INCREMENT, @@ -3800,10 +3800,10 @@ CREATE TABLE `zt_todo` ( `vision` varchar(10) NOT NULL DEFAULT 'rnd', PRIMARY KEY (`id`), KEY `account` (`account`), - KEY `feedback` (`feedback`), KEY `assignedTo` (`assignedTo`), KEY `finishedBy` (`finishedBy`), - KEY `date` (`date`) + KEY `date` (`date`), + KEY `feedback` (`feedback`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; CREATE TABLE `zt_traincategory` ( `id` mediumint unsigned NOT NULL AUTO_INCREMENT, diff --git a/db/update21.7.4.sql b/db/update21.7.4.sql index 66af6107d5..c9c261b26b 100644 --- a/db/update21.7.4.sql +++ b/db/update21.7.4.sql @@ -10,3 +10,8 @@ CREATE INDEX `feedback` ON `zt_story`(`feedback`); CREATE INDEX `feedback` ON `zt_task`(`feedback`); CREATE INDEX `feedback` ON `zt_ticket`(`feedback`); CREATE INDEX `feedback` ON `zt_todo`(`feedback`); + +CREATE OR REPLACE VIEW `ztv_executionsummary` AS SELECT `zt_task`.`execution` AS `execution`,SUM(IF((`zt_task`.`isParent` = '0'),`zt_task`.`estimate`,0)) AS `estimate`,SUM(IF((`zt_task`.`isParent` = '0'),`zt_task`.`consumed`,0)) AS `consumed`,SUM(IF(((`zt_task`.`status` <> 'cancel') AND (`zt_task`.`status` <> 'closed') AND (`zt_task`.`isParent` = '0')),`zt_task`.`left`,0)) AS `left`,COUNT(0) AS `number`,SUM(IF(((`zt_task`.`status` <> 'done') AND (`zt_task`.`status` <> 'closed')),1,0)) AS `undone`,SUM(IF(`zt_task`.`isParent` = '0',`zt_task`.`consumed`,0) + IF(((`zt_task`.`status` <> 'cancel') AND (`zt_task`.`status` <> 'closed') AND (`zt_task`.`isParent` = '0')),`zt_task`.`left`,0)) AS `totalReal` FROM `zt_task` WHERE (`zt_task`.`deleted` = '0') GROUP BY `zt_task`.`execution`; +CREATE OR REPLACE VIEW `ztv_projectsummary` AS SELECT `zt_task`.`project` AS `project`,SUM(IF((`zt_task`.`isParent` = '0'),`zt_task`.`estimate`,0)) AS `estimate`,SUM(IF((`zt_task`.`isParent` = '0'),`zt_task`.`consumed`,0)) AS `consumed`,SUM(IF(((`zt_task`.`status` <> 'cancel') AND (`zt_task`.`status` <> 'closed') AND (`zt_task`.`isParent` = '0')),`zt_task`.`left`,0)) AS `left`,COUNT(0) AS `number`,SUM(IF(((`zt_task`.`status` <> 'done') AND (`zt_task`.`status` <> 'closed')),1,0)) AS `undone`,SUM(IF(`zt_task`.`isParent` = '0',`zt_task`.`consumed`,0) + IF(((`zt_task`.`status` <> 'cancel') AND (`zt_task`.`status` <> 'closed') AND (`zt_task`.`isParent` = '0')),`zt_task`.`left`,0)) AS `totalReal` FROM `zt_task` WHERE (`zt_task`.`deleted` = '0') GROUP BY `zt_task`.`project`; + +REPLACE INTO `zt_grouppriv` (`group`, `module`, `method`) SELECT `group`, `module`, 'edit' FROM `zt_grouppriv` WHERE `module` = 'doc' AND `method` = 'create'; diff --git a/db/zentao.sql b/db/zentao.sql index 845b8160d2..40161e1ca9 100755 --- a/db/zentao.sql +++ b/db/zentao.sql @@ -2753,9 +2753,9 @@ CREATE TABLE IF NOT EXISTS `zt_report` ( CREATE UNIQUE INDEX `code` ON `zt_report`(`code`); -- DROP VIEW IF EXISTS `ztv_executionsummary`; -CREATE OR REPLACE VIEW `ztv_executionsummary` AS SELECT `zt_task`.`execution` AS `execution`,SUM(IF((`zt_task`.`isParent` > '0'),`zt_task`.`estimate`,0)) AS `estimate`,SUM(IF((`zt_task`.`isParent` > '0'),`zt_task`.`consumed`,0)) AS `consumed`,SUM(IF(((`zt_task`.`status` <> 'cancel') AND (`zt_task`.`status` <> 'closed') AND (`zt_task`.`isParent` > '0')),`zt_task`.`left`,0)) AS `left`,COUNT(0) AS `number`,SUM(IF(((`zt_task`.`status` <> 'done') AND (`zt_task`.`status` <> 'closed')),1,0)) AS `undone`,SUM(IF(`zt_task`.`isParent` > '0',`zt_task`.`consumed`,0) + IF(((`zt_task`.`status` <> 'cancel') AND (`zt_task`.`status` <> 'closed') AND (`zt_task`.`isParent` > '0')),`zt_task`.`left`,0)) AS `totalReal` FROM `zt_task` WHERE (`zt_task`.`deleted` = '0') GROUP BY `zt_task`.`execution`; +CREATE OR REPLACE VIEW `ztv_executionsummary` AS SELECT `zt_task`.`execution` AS `execution`,SUM(IF((`zt_task`.`isParent` = '0'),`zt_task`.`estimate`,0)) AS `estimate`,SUM(IF((`zt_task`.`isParent` = '0'),`zt_task`.`consumed`,0)) AS `consumed`,SUM(IF(((`zt_task`.`status` <> 'cancel') AND (`zt_task`.`status` <> 'closed') AND (`zt_task`.`isParent` = '0')),`zt_task`.`left`,0)) AS `left`,COUNT(0) AS `number`,SUM(IF(((`zt_task`.`status` <> 'done') AND (`zt_task`.`status` <> 'closed')),1,0)) AS `undone`,SUM(IF(`zt_task`.`isParent` = '0',`zt_task`.`consumed`,0) + IF(((`zt_task`.`status` <> 'cancel') AND (`zt_task`.`status` <> 'closed') AND (`zt_task`.`isParent` = '0')),`zt_task`.`left`,0)) AS `totalReal` FROM `zt_task` WHERE (`zt_task`.`deleted` = '0') GROUP BY `zt_task`.`execution`; -- DROP VIEW IF EXISTS `ztv_projectsummary`; -CREATE OR REPLACE VIEW `ztv_projectsummary` AS SELECT `zt_task`.`project` AS `project`,SUM(IF((`zt_task`.`isParent` > '0'),`zt_task`.`estimate`,0)) AS `estimate`,SUM(IF((`zt_task`.`isParent` > '0'),`zt_task`.`consumed`,0)) AS `consumed`,SUM(IF(((`zt_task`.`status` <> 'cancel') AND (`zt_task`.`status` <> 'closed') AND (`zt_task`.`isParent` > '0')),`zt_task`.`left`,0)) AS `left`,COUNT(0) AS `number`,SUM(IF(((`zt_task`.`status` <> 'done') AND (`zt_task`.`status` <> 'closed')),1,0)) AS `undone`,SUM(IF(`zt_task`.`isParent` > '0',`zt_task`.`consumed`,0) + IF(((`zt_task`.`status` <> 'cancel') AND (`zt_task`.`status` <> 'closed') AND (`zt_task`.`isParent` > '0')),`zt_task`.`left`,0)) AS `totalReal` FROM `zt_task` WHERE (`zt_task`.`deleted` = '0') GROUP BY `zt_task`.`project`; +CREATE OR REPLACE VIEW `ztv_projectsummary` AS SELECT `zt_task`.`project` AS `project`,SUM(IF((`zt_task`.`isParent` = '0'),`zt_task`.`estimate`,0)) AS `estimate`,SUM(IF((`zt_task`.`isParent` = '0'),`zt_task`.`consumed`,0)) AS `consumed`,SUM(IF(((`zt_task`.`status` <> 'cancel') AND (`zt_task`.`status` <> 'closed') AND (`zt_task`.`isParent` = '0')),`zt_task`.`left`,0)) AS `left`,COUNT(0) AS `number`,SUM(IF(((`zt_task`.`status` <> 'done') AND (`zt_task`.`status` <> 'closed')),1,0)) AS `undone`,SUM(IF(`zt_task`.`isParent` = '0',`zt_task`.`consumed`,0) + IF(((`zt_task`.`status` <> 'cancel') AND (`zt_task`.`status` <> 'closed') AND (`zt_task`.`isParent` = '0')),`zt_task`.`left`,0)) AS `totalReal` FROM `zt_task` WHERE (`zt_task`.`deleted` = '0') GROUP BY `zt_task`.`project`; -- DROP VIEW IF EXISTS `ztv_projectstories`; CREATE OR REPLACE VIEW `ztv_projectstories` AS SELECT `t1`.`project` AS `execution`,COUNT(1) AS `stories`,SUM(IF((`t2`.`status` = 'closed'),0,1)) AS `undone` FROM ((`zt_projectstory` `t1` LEFT JOIN `zt_story` `t2` ON((`t1`.`story` = `t2`.`id`))) LEFT JOIN `zt_project` `t3` ON((`t1`.`project` = `t3`.`id`))) WHERE ((`t2`.`deleted` = '0') AND (`t3`.`type` IN ('sprint','stage'))) GROUP BY `t1`.`project`; -- DROP VIEW IF EXISTS `ztv_projectteams`; diff --git a/doc/CHANGELOG b/doc/CHANGELOG index 5a8d651e3e..29b0cffd7d 100644 --- a/doc/CHANGELOG +++ b/doc/CHANGELOG @@ -1,19 +1,49 @@ -2025-08-22 21.7.5 +2025-09-11 21.7.5 完成的需求 开源版: +77897 创建发布/应用/构建页面增加帮助说明 +77640 重构搜索表单相关功能以提高性能 77398 源码包安装流程中增加埋点 -75100 文档编辑器增加对齐功能 +75100 文档编辑器增加文本对齐功能 企业版: 76672 重构文档历史版本对比功能 +73517 工作流配置的流程中在详情点击返回可以返回上一页面 修复的Bug 开源版: +22932 Bug重要程度阶段分布图标中鼠标悬浮后信息显示不全 46933 【20版本】点击搜索按钮后搜索表单会消失 54900 测试下批量建用例超过50个,点击保存提示用例类型不能为空 55125 任务列表下进入需求返回页面不是任务列表 (Feedback#7052) 55259 测试用例列表页点击相关研发需求后,详情页点击返回时没有返回到用例列表 55577 模块名称中不能输入空格 (Feedback#7177) +58165 文档详情页中图片复制按钮无效 +60076 提bug时,切换所属产品,页面会刷新,数据不保存 +61043 草稿文档切换为新编辑器保存草稿页面显示代码 +61176 安装第三步提示“还没有生成配置文件” (Feedback#8912) +61312 编辑文档无法粘贴图片 (Feedback#8877) +61316 旧编辑器文档不显示插入的图片 +61737 [内禅]库卡片统计的文档数量不正确 +61739 [内禅]库卡片的文档数量统计信息没有常显 +61763 [内禅]文档历史版本中图片裂开 +61766 [内禅]升级后文档对齐方式丢失 +61777 markdown的列表项中和简单表格中的图片升级后不显示 +61779 [内禅]文档升级后文字位置不正确 +61790 [内禅]文档升级后表格中显示滚动条 +61791 升级后文档对空白行的处理不一致 +61792 [内禅]文档显示图片加载失败 +61795 [内禅]升级后的文档中不是列表项的图片不显示在详情页和编辑页面 +61798 升级后缩进(空格)的样式丢失 +61805 【内禅】一块引用升级后被拆分成两块 +61807 【内禅】文字和图片的位置升级后改变了 +61813 [内禅]内禅升级后的内禅文档历史记录和历史版本中的@可以点击 +61815 [内禅]文档升级后表格中的换行丢失 +61816 【内禅】文档升级后表格的字体发生变化加粗丢失 +61826 【内禅】列表升级后有多余的间距 +62391 提Bug页面内容全部刷新 64109 批量编辑产品页面负责人字段无法回显也无法选择 (Feedback#9853) 64121 首页-待处理-点击待评审需求提示app not found。 (Feedback#9665) +64133 当gitlab服务器包含端口时链接代码库失败 (Feedback#9883) +64222 离职人员历史的文档无法打开 64389 删除项目后并没有删除该项目下相关的目标评审 (Feedback#9988) 64400 合并产品分支报错 (Feedback#9987) 64473 用例库导出用例报错 (Feedback#10004) @@ -21,44 +51,126 @@ 64516 项目概况中的项目描述过多时显示不全 (Feedback#10045) 64528 视野权限取消勾选devops后管理应用按钮也会消失 (Feedback#9906) 64529 多人并行任务指派给 在地盘待处理 不显示 (Feedback#9902) +64536 解决Bug选择重复Bug编辑时重复Bug的字段是空的 +64539 任务列表父子任务显示不正确 +64540 文档插入多层级的禅道数据时只能插入第一层级的任务 64549 用户没有需求提交评审权限,但是仍展示了按钮,点击弹出异常框 (Feedback#9803) 64581 编辑需求、用例、bug日志,工时显示错误 64599 文档编辑权限异常 (Feedback#10044) 64623 激活Bug上传的图片在历史记录中显示是裂开的 64637 编辑bug的模块,丢失指派给 (Feedback#10064) 64639 Scrum教程到“点击指派给”卡住不能往下继续了 (Feedback#10085) +64685 组织动态搜索排序选项丢失 64693 没有提交评审权限,需求列表显示了提交评审按钮 64717 项目使用重新定义权限分组时不能从项目执行列表访问项目下执行 +64720 项目文档添加研发需求列表,弹窗中报错 64751 激活bug时上传截图保存后截图展示异常 (Feedback#10098) +64758 组织-团队-日程切换其他标签后显示页面不同 (Feedback#10105) +64759 文档库设置了排序后文档库列表不能按照设置的顺序显示文档顺序 +64765 项目与产品解除关联后编辑项目下的产品有报错 +64770 因为`oder`数据库字段长度限制导致导入用例报错 (Feedback#10118) 64776 Bug列表批量指派功能,无法通过拼音或者首字母搜索人员 (Feedback#10056) +64780 用例导入html格式的文件报错 64787 运营管理界面分配权限报错 64792 批量添加用户报错 +64795 在Xmind 编辑页面,点击保存后出现的确认弹窗点击取消后仍然保存 +64808 restful新建bug接口,无法传浏览器和操作系统参数 (Feedback#10084) +64809 关联到发布,验收,点发布,这种情况下需求的阶段不变 (Feedback#10135) 64815 用例覆盖率统计口径与用例需求关联范围不一致的问题 (Feedback#10137) +64821 批量编辑项目置空名称保存后再刷新页面弹出保存成功提示 64822 项目下搜索表单空白 +64857 用户没有编辑文档权限,发布文档后是草稿状态 +64868 多分支产品分支和白名单页面显示了1.5级分支下拉 +64871 运营界面待处理区块报错 +64872 运营界面待处理区块目标未显示所属项目 +64875 开始、激活、继续任务预计剩余为负数报错 +64880 项目迭代列表页搜索后点击列表表头排序不生效 +64893 激活bug时,备注添加图片,保存后不显示 (Feedback#10165) +64903 项目干系人无法查看此项目下的迭代/执行 (Feedback#10163) 64904 批量创建时过滤了尖括号之间的内容 (Feedback#10066) 64920 任务搜索相关研发需求的条件下拉框没有显示相关研发需求 64923 贡献任务列表搜索框没加载显示出来 64925 项目--迭代/阶段列表页执行搜索后,总是列出所有任务 64927 项目--迭代/阶段列表执行搜索后重置搜索条件,没有列出所有任务 +64938 新手教程任务管理页面有报错 +64939 复制已完成的多人任务时团队未复制且没有历史记录 +64941 编辑场景名称置空保存,必填提示不正确 +64967 执行--任务,【最初预计】和【预计剩余】小数点后显示很多位 +64968 数据库中工时保留两位小数 +64990 已经关闭的bug,在列表中还能错误的指派给某个人 (Feedback#10186) +65004 集成应用创建发布时包含应用的+按钮没有常显 +65007 批量创建需求,无法选择对应的模块 (Feedback#10024) +65021 部分发布数据在发布列表中不显示 +65022 集成应用的发布包含的构建缺失 +65023 用例执行时上传的附件无法正确保存、显示 (Feedback#10217) +65024 批量编辑页面已关闭的bug指派给字段应置灰 +65030 demo账户登录时跳转修改密码页 +65032 内禅历史记录中会显示额外的代码 +65033 套件/测试报告的无创建权限仍然显示 (Feedback#10225) +65038 所属项目显示为ID +65039 任务检索表单空白 +65048 多人串行任务团队第一个用户完成后下一个成员无法记录工时 企业版: 39077 用户分配工作流“流程详情”权限后流程页面未显示“预览” 55416 待处理下批量编辑反馈三级导航菜单未高亮 58762 工作流数据关联工作流数据名称错误 58863 组织动态页面搜索页面和前面的控件距离太近 61129 反馈列表页左侧区块中产品名称加粗显示了 +62476 导出用户xls文件第10个用户没有背景色 +62491 发布工作流有报错 +62537 linux一键包中项目阶段下导出xls模板后弹窗未关闭 +62654 产品下导入xls格式数据,弹窗没有关闭 +62669 项目阶段导入任务时上传一个空的excel保存时会报错 64317 导入研发需求确认页面评审人建议增加[同上]按钮 64468 批量编辑反馈,设置显示多个自定义字段时,字段重叠 (Feedback#10010) 64470 项目需求导入导出权限配置错误 (Feedback#10005) 64481 用例批量编辑与单个编辑表单数据不一致 (Feedback#10038) +64538 自定义透视表查看原始数据报错 64675 配置了office后,文档详情页不显示预览按钮 +64696 产品下导入产品需求报错 64714 预览导入的office文档在禅道中打开没有新开标签 +64716 导出文档文档中甘特图和附件没有链接 +64762 需求导出xls页面报错 64763 导出项目进度没有显示百分比 64764 导出项目的已投入列建议显示单位人天 +64801 用例库里导入excel时页面有报错 +64810 研发需求重复导入报错 64824 反馈状态更新为已处理后没有发送消息通知 (Feedback#10142) +64859 运营界面,反馈列表的状态字段不显示 (Feedback#10154) +64888 发布的工作流配置动作后在项目里不生效 (Feedback#1822) 64889 项目和迭代下的任务指派给分布饼图不一致 64909 任务进行搜索后查看报表有报错 +64913 英文下迭代列表基本统计报表空白有报错 +64928 企业版和旗舰版后台通知设置页面显示了“由需求池需求处理” +64934 导入excel表格报错 +64985 升级biz12.3报错 (Feedback#10198) +65001 导出用户xls格式没有隐藏 +65012 bug导出模板里面包含的模块,导入不展示这个模块 (Feedback#10209) +65031 开源版升级到企业版后访问禅道页面报错 +65036 导入bug确认页面指派给下拉列出了closed +65054 项目下迭代报表任务统计等页面有报错 +65063 执行需求报表页面报错 +65069 研发需求导入时评审人必填提示文案不对 +65077 导入需求确认页面评审人默认同上了 +65081 导出用户后导出弹窗未关闭 +65097 项目下阶段列表导入任务时有报错 +65100 地盘日程软需详情页点击用例按钮后弹窗页置灰了 +65149 项目型项目创建的反馈,转研发需求后,项目需求列表看不到 (Feedback#10251) +65177 快捷访问下的文档点击关联对象按钮无反应 +65196 工时明细表按完成者和关闭者分组时报错 +65206 无产品项目的日志导出后产品列显示了影子产品 +65207 无产品项目计划的日志,导出后项目列显示空 +65213 项目投入表查询不到任务消耗 +65225 导出xls用户数据后再导入未成功导入数据 +65252 导出xls用户数据时确认导入页有报错 +65268 休息日加班,考勤显示为休息 (Feedback#10281) +65310 项目迭代报表下的资源分析页面有报错 +65321 工单转研发需求不显示自定义字段 (Feedback#10276) +65329 PHP70加密代码,任务统计报表的基本统计中有些报错 +65361 导入任务无法导入多人任务 旗舰版: 24150 添加自定义项不适用某个语言时,该语言下字段显示为空了 +61007 组织动态搜索之后翻页异常 (Feedback#8703) 64338 项目评审问题列表中选择评审项时会返回已删除评审项 (Feedback#9942) 64384 审批人必填提示信息不正确 64480 项目甘特图下无法拖拽任务更新任务排序 (Feedback#9998) @@ -69,18 +181,69 @@ 64761 工单编辑界面编辑器还是老版本编辑器 (Feedback#10107) 64782 升级后过程列表和活动列表每页按照左侧区块顺序显示 64784 新建产品无法选择产品线 (Feedback#10101) +64796 瀑布项目设计评审页面无评审人员选项,导致提交失败 (Feedback#10129) 64797 项目模板无法新增子阶段 (Feedback#10126) +64832 批量创建设计,关联对象不自动绑定 (Feedback#10152) +64847 瀑布项目评审时填写的工时被自动取整 (Feedback#10149) 64850 上传有大小写字母的文件类型,下载文件有双后缀 (Feedback#10094) +64851 项目型项目工单日志搜索异常 (Feedback#10148) +64858 立项中上传其他附件时无法上传多个 (Feedback#10140) +64865 集成应用发布,列表包括应用和发布显示错乱且缺少集成icon (Feedback#10159) +64866 集成应用的发布,发布描述显示不正常 (Feedback#10158) 64873 项目模板下点击阶段的二级导航,页面报错 +64874 文档插入甘特图有报错 64879 瀑布项目阶段列表点击甘特图按钮报错 +64917 瀑布项目甘特图按指派给分组没有显示未指派的任务 64919 瀑布项目甘特图搜索条件不起作用 +64924 甘特图搜索表单未列出所属模块 +64936 从已有项目创建模板页面报错 +64962 excel导入任务,导入的任务层级关系不正确 (Feedback#10146) +64981 【合并】工作流字段设置为隐藏后错误的要求其必填 +64983 工作流富文本字段不能正常使用 (Feedback#9495) +64986 反馈列表所属模块字段错误的显示成了模块id (Feedback#10201) +64997 项目型瀑布项目模板,创建项目完善阶段页面空白,无法正常读取模板阶段 (Feedback#10212) +65018 文档中添加甘特图提示需优化 +65041 基线评审列表页报错 +65049 反馈全文检索问题 (Feedback#10181) +65052 php8.1安装报错 +65099 QA不符合项列表搜索不成功 +65101 维护项目/执行交付物,上传文件保存后报错 +65113 自定义大屏,部门筛选器没有数据 (Feedback#10122) +65115 点击已关闭执行的设置后,会跳转到其他的执行概况表单 (Feedback#10110) +65117 补全后台-二次开发-数据字典数据表字段为空的描述 (Feedback#9974) +65123 项目-需求列表倒入需求库需求点击详情提示无权限 (Feedback#10240) +65134 需求库导入需求提示信息没有显示 +65161 项目模板中拆分子阶段,无法保存 (Feedback#10259) +65164 项目维护交付物页面提交文件保存报错 +65166 工作流扩展的审批流程没有给审批人进行通知 (Feedback#9597) +65212 无权限时在报告中点任务链接没有提示信息 +65224 提交交付物后,页面有报错 +65231 审计时检查清单建议解决时间为空保存报错 +65235 升级后交后台付物列表报错 +65239 项目下提交的附件交付物升级后文档显示在迭代主库下 +65242 升级后项目交付物列表页其他交付物的交付物类型显示为空 +65245 升级后交付物的提交人显示system +65246 升级后执行下交付物丢失 +65317 评审时上传的图片,在评审报告中显示为裂图 +65327 审批流为或签时,有一人评审不通过则评审失败 +65339 编辑评审页面修改附件名称后保存时有报错 +65381 任务取消异常 (Feedback#10206) IPD版: +62782 IPD项目阶段添加子级后,子级行末尾显示了“否” 64285 研发界面点击消息通知链接打开反馈详情,没有展示工作流自定义的字段 64422 甘特图上的阶段和评审掉悬停时显示圆圈 64495 PHP7.4 项目-文档下,移动文档库的顺序无效 (Feedback#9865) 64533 执行甘特图,预计工时与消耗工时重复计算了父子任务工时 (Feedback#10031) +64585 复制IPD项目校验子阶段的开始时间应大于父阶段的结束时间 64713 任务附件名称异常 (Feedback#9638) 64916 OR界面进入地盘时有任务搜索表单的相关报错 +64978 【性能】填写日志过多导致的性能问题 +64979 调研任务完成页面点添加备注页面卡住,需要重新刷新 (Feedback#9840) +64980 反馈数据导出标题列不展示内容 (Feedback#10131) +65203 OR界面用户需求/业务需求保存搜索条件时勾选显示在菜单栏但保存后未显示在菜单栏 +65266 立项详情页创建IPD项目时项目类型未置灰 +65290 甘特图中提交评审后,提示无法发起评审 +65295 立项详情页创建IPD项目保存时提示项目类型不能为空 2025-07-29 21.7.4 完成的需求 diff --git a/extension/lite/story/ext/model/lite.php b/extension/lite/story/ext/model/lite.php index 87115f0552..e0c3cf7421 100644 --- a/extension/lite/story/ext/model/lite.php +++ b/extension/lite/story/ext/model/lite.php @@ -6,5 +6,5 @@ public function getExecutionStoryPairs(int $executionID = 0, int $productID = 0, $execution = $this->loadModel('execution')->getById($executionID); if(!empty($execution->project)) $executionID = $execution->project; } - return parent::getExecutionStoryPairs($executionID, $productID, $branch, $moduleIdList, $type, $status, $storyType); + return parent::getExecutionStoryPairs($executionID, $productID, $branch, $moduleIdList, $type, $status, $storyType, $hasParent); } diff --git a/framework/api/entry.class.php b/framework/api/entry.class.php index 2a23de07d1..a5e8797627 100644 --- a/framework/api/entry.class.php +++ b/framework/api/entry.class.php @@ -560,7 +560,7 @@ class baseEntry } else { - $vs = implode(',', $object->$key); + $vs = explode(',', $object->$key); foreach($vs as $v) { if($v === '') continue; diff --git a/lib/scm/scm.class.php b/lib/scm/scm.class.php index 02fd3a8f30..88fac1b5cc 100644 --- a/lib/scm/scm.class.php +++ b/lib/scm/scm.class.php @@ -59,11 +59,13 @@ class scm * @param string $orderBy * @param int $limit * @param int $pageID + * @param string $label + * @param int $showArchived * @return array */ - public function branch(string $showDetail = '', string $orderBy = '', int $limit = 0, int $pageID = 1, string $label = '') + public function branch(string $showDetail = '', string $orderBy = '', int $limit = 0, int $pageID = 1, string $label = '', int $showArchived = 0) { - return $this->engine->branch($showDetail, $orderBy, $limit, $pageID, $label); + return $this->engine->branch($showDetail, $orderBy, $limit, $pageID, $label, $showArchived); } /** diff --git a/lib/sqlfilter/sqlfilter.class.php b/lib/sqlfilter/sqlfilter.class.php new file mode 100644 index 0000000000..7c0443e7dd --- /dev/null +++ b/lib/sqlfilter/sqlfilter.class.php @@ -0,0 +1,348 @@ +removeControlCharacters($input); + + // 步骤3:移除SQL注入攻击模式 + $filtered = $this->removeSQLInjectionPatterns($filtered); + + // 步骤4:处理危险的SQL字符组合 + $filtered = $this->removeDangerousSQLChars($filtered); + + // 步骤5:去除首尾的空白字符 + $filtered = trim($filtered); + + return $filtered; + } + + /** + * 方案2:Unicode属性过滤 + SQL危险字符过滤 + * + * 适用场景: + * - 需要更宽松的字符支持 + * - 用户可能输入各种标点符号 + * - 对性能要求不是特别高 + * + * @param string $input 用户输入 + * @return string 过滤后的字符串 + */ + public function filterUnicodeForSQL($input) + { + if(!is_string($input) || empty(trim($input))) return ''; + + // 步骤1:使用Unicode属性类保留语言字符和基本标点 + // \p{L} = 所有语言的字母 + // \p{N} = 所有数字 + // \p{M} = 标记字符(如重音符号) + // \s = 空白字符 + // \.\,\!\?\-\_\(\) = 常用标点符号 + $filtered = preg_replace('/[^\p{L}\p{N}\p{M}\s\.\,\!\?\-\_\(\)]/u', ' ', $input); + + // 步骤2:移除SQL注入模式 + $filtered = $this->removeSQLInjectionPatterns($filtered); + + // 步骤3:标准化空格 + $filtered = preg_replace('/\s+/', ' ', $filtered); + + // 步骤4:去除首尾的空白字符 + $filtered = trim($filtered); + + return $filtered; + } + + /** + * 方案3:严格的SQL安全过滤 + * + * 适用场景: + * - 高安全要求的环境 + * - 可以接受某些特殊字符被过滤 + * - 关键数据操作 + * + * @param string $input 用户输入 + * @return string 过滤后的字符串 + */ + public function filterStrictSQL($input) + { + if(!is_string($input) || empty(trim($input))) return ''; + + // 步骤1:只保留字母、数字、最基本的标点 + $filtered = preg_replace('/[^\p{L}\p{N}\s\.\,\!\?\-\_]/u', '', $input); + + // 步骤2:移除SQL注入模式 + $filtered = $this->removeSQLInjectionPatterns($filtered); + + // 步骤3:去除首尾的空白字符 + $filtered = trim($filtered); + + return $filtered; + } + + /** + * 移除控制字符(但保留正常的空白字符) + * + * 控制字符可能被用于绕过安全检查或造成解析错误 + * + * @param string $input 输入字符串 + * @return string 处理后的字符串 + */ + private function removeControlCharacters($input) + { + // 移除C0和C1控制字符 + // 但保留:制表符(\t)、换行符(\n)、回车符(\r) + // \x00-\x08: NULL到BACKSPACE + // \x0B: 垂直制表符 + // \x0C: 换页符 + // \x0E-\x1F: 其他C0控制字符 + // \x7F-\x9F: DEL和C1控制字符 + return preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F]/u', '', $input); + } + + /** + * 移除明显的SQL注入攻击模式 + * + * 这是防护的核心部分,识别并移除常见的SQL注入技术 + * + * @param string $input 输入字符串 + * @return string 处理后的字符串 + */ + private function removeSQLInjectionPatterns($input) + { + $dangerousPatterns = [ + // === SQL注释攻击 === + '/--[\s\S]*$/i', // 单行注释:-- comment + '/\/\*[\s\S]*?\*\//i', // 块注释:/* comment */ + '/#.*$/m', // MySQL特有的#注释 + + // === 联合查询注入 === + '/\b(union\s+select)\b/i', // UNION SELECT + '/\b(union\s+all\s+select)\b/i', // UNION ALL SELECT + + // === 数据操作注入 === + '/\b(drop\s+table)\b/i', // DROP TABLE + '/\b(drop\s+database)\b/i', // DROP DATABASE + '/\b(delete\s+from)\b/i', // DELETE FROM + '/\b(insert\s+into)\b/i', // INSERT INTO + '/\b(update\s+.*\s+set)\b/i', // UPDATE ... SET + '/\b(alter\s+table)\b/i', // ALTER TABLE + '/\b(create\s+table)\b/i', // CREATE TABLE + '/\b(truncate\s+table)\b/i', // TRUNCATE TABLE + + // === 存储过程和函数执行 === + '/\b(exec\s*\()\b/i', // EXEC() + '/\b(execute\s*\()\b/i', // EXECUTE() + '/\b(sp_executesql)\b/i', // SQL Server存储过程 + '/\b(xp_cmdshell)\b/i', // SQL Server命令执行 + + // === 文件操作注入 === + '/\b(load_file)\b/i', // MySQL LOAD_FILE() + '/\b(into\s+outfile)\b/i', // INTO OUTFILE + '/\b(into\s+dumpfile)\b/i', // INTO DUMPFILE + + // === 编码绕过尝试 === + '/\\\\x[0-9a-f]{2}/i', // 十六进制编码 \x41 + '/\\\\[0-7]{1,3}/i', // 八进制编码 \101 + '/%[0-9a-f]{2}/i', // URL编码 %41 + + // === 其他危险模式 === + '/\b(information_schema)\b/i', // 信息模式数据库 + '/\b(mysql\.user)\b/i', // MySQL用户表 + '/\b(pg_sleep)\b/i', // PostgreSQL延时函数 + '/\b(waitfor\s+delay)\b/i', // SQL Server延时 + ]; + + // 逐个应用模式,将匹配内容替换为空格 + foreach($dangerousPatterns as $pattern) $input = preg_replace($pattern, ' ', $input); + + return $input; + } + + /** + * 移除危险的SQL字符组合 + * + * 处理单个字符可能无害,但组合起来就危险的情况 + * + * @param string $input 输入字符串 + * @return string 处理后的字符串 + */ + private function removeDangerousSQLChars($input) + { + $replacements = [ + // === 引号相关 === + "/'+/i" => "", // 多个单引号:''' + '/"+/i' => "", // 多个双引号:""" + "/'+\s*or\s*'+/i" => " ", // 引号包围的OR:'or' + "/'+\s*and\s*'+/i" => " ", // 引号包围的AND:'and' + + // === SQL语法字符 === + '/;+/' => " ", // 分号(语句分隔符) + '/\|\|/' => " ", // SQL字符串连接符 || + '/`+/' => "", // 反引号(MySQL标识符) + + // === 注释字符组合 === + '/--+/' => " ", // 多个连字符 + '/\/\*|\*\//' => " ", // 注释开始/结束符 + + // === 危险操作符 === + '/\s*=\s*[\'"]?\s*[\'"]?\s*/i' => " ", // 可能的等号注入 + '/\s+(or|and)\s+[\'"]?\d+[\'"]?\s*=\s*[\'"]?\d+[\'"]?/i' => " ", // 1=1类型注入 + ]; + + foreach($replacements as $pattern => $replacement) $input = preg_replace($pattern, $replacement, $input); + + return $input; + } + + /** + * 验证过滤后的字符串是否仍包含危险特征 + * + * 作为最后的安全检查 + * + * @param string $input 已过滤的字符串 + * @return bool true表示安全,false表示仍有风险 + */ + public function validateSafety($input) + { + // 危险特征检查 + $dangerousPatterns = [ + '/[\'"`;]/i', // 引号和分号 + '/\b(select|union|drop|delete|insert|update|alter|create|exec)\b/i', // SQL关键词 + '/--|\*\/|\/\*/', // 注释符 + '/\|\|/', // 字符串连接 + '/\bor\s+\d+\s*=\s*\d+/i', // 1=1类型条件 + ]; + + foreach($dangerousPatterns as $pattern) + { + if(preg_match($pattern, $input)) return false; // 发现危险特征 + } + + return true; // 通过安全检查 + } + + /** + * 根据安全级别选择合适的过滤方法 + * + * @param string $input 用户输入 + * @param string $securityLevel 安全级别:'high', 'medium', 'low' + * @return string 过滤后的字符串 + */ + public function getRecommendedFilter($input, $securityLevel = 'medium') + { + switch($securityLevel) + { + case 'high': + // 高安全级别:最严格的过滤 + return $this->filterStrictSQL($input); + + case 'low': + // 低安全级别:更宽松,保留更多字符 + return $this->filterUnicodeForSQL($input); + + case 'medium': + default: + // 中等安全级别:平衡安全性和可用性 + return $this->filterForSQL($input); + } + } + + /** + * 批量过滤多个输入 + * + * @param array $inputs 输入数组 + * @param string $securityLevel 安全级别 + * @return array 过滤后的数组 + */ + public function filterMultiple($inputs, $securityLevel = 'medium') + { + $filtered = []; + foreach($inputs as $key => $input) $filtered[$key] = $this->getRecommendedFilter($input, $securityLevel); + return $filtered; + } + + /** + * 生成过滤报告(调试用) + * + * @param string $original 原始输入 + * @param string $filtered 过滤后结果 + * @return array 详细的过滤报告 + */ + public function generateFilterReport($original, $filtered) + { + return [ + 'original' => $original, + 'filtered' => $filtered, + 'length_change' => strlen($original) - strlen($filtered), + 'removed_chars' => $this->getRemovedChars($original, $filtered), + 'safety_check' => $this->validateSafety($filtered), + 'potential_threats' => $this->identifyThreats($original) + ]; + } + + /** + * 识别输入中的潜在威胁(调试和日志记录用) + * + * @param string $input 输入字符串 + * @return array 发现的威胁列表 + */ + private function identifyThreats($input) + { + $threats = []; + + $threatPatterns = [ + 'sql_injection' => '/\b(union|select|drop|delete|insert|update)\b/i', + 'comment_attack' => '/--|\*\/|\/\*/', + 'quote_manipulation' => '/[\'"]{2,}/', + 'statement_separator' => '/;/', + 'encoding_bypass' => '/\\\\x[0-9a-f]{2}|%[0-9a-f]{2}/i' + ]; + + foreach($threatPatterns as $threat => $pattern) + { + if(preg_match_all($pattern, $input, $matches)) $threats[$threat] = $matches[0]; + } + + return $threats; + } + + /** + * 计算被移除的字符 + * + * @param string $original 原始字符串 + * @param string $filtered 过滤后字符串 + * @return string 被移除的字符 + */ + private function getRemovedChars($original, $filtered) + { + $originalChars = mb_str_split($original, 1, 'UTF-8'); + $filteredChars = mb_str_split($filtered, 1, 'UTF-8'); + + // 简化的差异检测 + $diff = array_diff($originalChars, $filteredChars); + return implode('', array_unique($diff)); + } +} diff --git a/lib/zin/wg/docapp/js/v1.js b/lib/zin/wg/docapp/js/v1.js index b98e7b0b98..781892d69b 100644 --- a/lib/zin/wg/docapp/js/v1.js +++ b/lib/zin/wg/docapp/js/v1.js @@ -11,9 +11,8 @@ let savingDocData = {}; let docBasicModal = {}; let currentDocApp = null; -window.setZentaoSlashMenu = function(menus, title, vision, position) +window.setZentaoSlashMenu = function(menus, title, position) { - if(vision == 'or' || vision == 'lite') return; if(!menus?.length) return; const slashMenus = menus.map(menu => @@ -94,13 +93,17 @@ function getZentaoListProps(type, blockID, props) if(props && props.isTemplate) blockID = '__TML_ZENTAOLIST__' + blockID; const zentaoListLang = getLang('zentaoList'); - const exportUrl = $.createLink('doc', 'ajaxExportZentaoList', `blockID=${blockID}`); + const exportUrl = `${location.origin}${$.createLink('doc', 'ajaxExportZentaoList', `blockID=${blockID}`)}`; + const title = [(zentaoListLang ? zentaoListLang[type] : type), getLang('list')].join(config.clientLang.includes('zh') ? '' : ' '); return $.extend( { - title: [(zentaoListLang ? zentaoListLang[type] : type), getLang('list')].join(config.clientLang.includes('zh') ? '' : ' '), - exportUrl: `${location.origin}${exportUrl}`, + title: title, fetcher: $.createLink('doc', 'zentaoList', `type=${type}&blockID=${blockID}`), clearBeforeLoad: false + }, type === 'gantt' ? { + export: [{type: 'link', props: {text: title, href: exportUrl}}] + } : { + exportUrl: exportUrl, }, props); } @@ -1099,7 +1102,7 @@ const actionsMap = const canCreateSpace = canModify && hasPriv('createSpace'); const canCreateOffice = canModify && hasPriv('createOffice'); const canUploadDoc = canModify && hasPriv('uploadFile'); - const canExportDoc = hasPriv('exportDoc'); + const canExportDoc = hasPriv('exportDoc') && docApp.spaceType !== 'quick'; /* 文档列表没有文档时的按钮。Actions for empty doc list. */ if(info.ui === 'doc-list-empty') @@ -2239,11 +2242,32 @@ window.getDocViewSidebarTabs = function(doc, info) ].filter(Boolean); } - if(info.isNewDoc) return [{key: 'outline', icon: 'list-box', title: getLang('docOutline')}]; - return [ - {key: 'outline', icon: 'list-box', title: getLang('docOutline')}, - {key: 'history', icon: 'history', title: getLang('history')}, - ] + let tabList = []; + if(info.isNewDoc) + { + tabList.push({key: 'outline', icon: 'list-box', title: getLang('docOutline')}); + + } + else + { + tabList.push( + {key: 'outline', icon: 'list-box', title: getLang('docOutline')}, + {key: 'history', icon: 'history', title: getLang('history')} + ); + } + + if(info.mode == 'view' && doc.status != 'draft' && !doc.api) + { + tabList.push( + { + key : 'relateObject', + icon : 'link', + title : getLang('relateObject'), + render: function(doc){return {fetcher: $.createLink('doc', 'ajaxGetRelatedObjects', `docID=${doc.id}`)}} + }); + } + + return tabList; } function getSpaceFetcher(spaceType, spaceID = 0) diff --git a/lib/zin/wg/docapp/v1.php b/lib/zin/wg/docapp/v1.php index a5a6a5fb3b..68dc93be50 100644 --- a/lib/zin/wg/docapp/v1.php +++ b/lib/zin/wg/docapp/v1.php @@ -320,11 +320,14 @@ class docApp extends wg $historyPanelProps = array('fileListProps' => $fileListProps); $canPreviewOffice = $canDownload && isset($config->file->libreOfficeTurnon) and $config->file->libreOfficeTurnon == 1; - // 不可用场景:文档模板、API 文档、开源版 + /* 对比不可用场景:文档模板、API 文档、开源版 */ $diffEnabled = ($config->edition != 'open') && !($rawModule == 'doc' && $rawMethod == 'view') && $rawModule != 'api'; + /* 禅道数据菜单不可用界面:运营(lite)、需求与市场(or) */ + if ($config->vision == 'lite' || $config->vision == 'or') $hasZentaoSlashMenu = false; + $zentaoListMenu = $hasZentaoSlashMenu ? $this->getZentaoListMenu() : array(); $moreMenus = $zentaoListMenu @@ -382,7 +385,7 @@ class docApp extends wg set::moreMenuAction(jsRaw('window.moreMenuAction')), set::canPreviewOffice($canPreviewOffice), set::fileInfoUrl($fileInfoUrl), - $hasZentaoSlashMenu ? jsCall('setZentaoSlashMenu', $zentaoListMenu, $lang->doc->zentaoData, $config->vision, $config->doc->zentaoListMenuPosition) : null + $hasZentaoSlashMenu ? jsCall('setZentaoSlashMenu', $zentaoListMenu, $lang->doc->zentaoData, $config->doc->zentaoListMenuPosition) : null ); } } diff --git a/lib/zin/wg/filelist/v1.php b/lib/zin/wg/filelist/v1.php index 0e5a9a0a6c..d0822fe153 100644 --- a/lib/zin/wg/filelist/v1.php +++ b/lib/zin/wg/filelist/v1.php @@ -44,7 +44,7 @@ class fileList extends wg foreach($files as $file) { - if($file->extra != $extra) continue; + if($extra && $file->extra != $extra) continue; $fileItemView = html($app->loadTarget('file')->printFile($file, $method, $showDelete, $showEdit, $object)); $fileListView->add($fileItemView); diff --git a/lib/zin/wg/formpanel/v1.php b/lib/zin/wg/formpanel/v1.php index 8e3e0161ec..b700886f38 100644 --- a/lib/zin/wg/formpanel/v1.php +++ b/lib/zin/wg/formpanel/v1.php @@ -134,6 +134,20 @@ class formPanel extends panel } } + if($moduleName == 'ticket') + { + if($methodName == 'createstory') + { + $moduleName = 'story'; + $methodName = 'create'; + } + elseif($methodName == 'createbug') + { + $moduleName = 'bug'; + $methodName = 'create'; + } + } + return array($moduleName, $methodName); } diff --git a/lib/zin/wg/gantt/js/v1.js b/lib/zin/wg/gantt/js/v1.js index 98f6a0dc29..06d8f847e1 100644 --- a/lib/zin/wg/gantt/js/v1.js +++ b/lib/zin/wg/gantt/js/v1.js @@ -340,6 +340,10 @@ function waitGantt(callback) clearInterval(timer); callback(); } + else + { + zui.Gantt.loadModule(); + } }, 300); } @@ -619,7 +623,7 @@ function initGantt() if(editBtn.hasClass('icon-confirm')) { - let pointAttr = reviewPoints; + let pointAttr = JSON.parse($('#gantt_here').attr('data-reviewpoints')); let category = id.split("-")[1]; if(pointAttr[category]['disabled']) @@ -795,6 +799,7 @@ function initGantt() window.onPageUnmount = function() { $(window).off('.gannt'); + $('.gantt_tooltip').remove(); document.removeEventListener('fullscreenchange', exitHandler); document.removeEventListener('webkitfullscreenchange', delayHandleFullscreen, false); document.removeEventListener('mozfullscreenchange', delayHandleFullscreen, false); diff --git a/lib/zin/wg/gantt/v1.php b/lib/zin/wg/gantt/v1.php index 9af7679aba..16099ff687 100644 --- a/lib/zin/wg/gantt/v1.php +++ b/lib/zin/wg/gantt/v1.php @@ -29,10 +29,7 @@ class gantt extends wg { global $app; $currentLang = $app->getClientLang(); - $langJSFile = $app->getWwwRoot() . 'js/dhtmlxgantt/lang/' . $currentLang . '.js'; - $js = file_get_contents(__DIR__ . DS . 'js' . DS . 'v1.js'); - if($currentLang != 'en' && file_exists($langJSFile)) $js .= "\nwaitGantt(function(){\n" . file_get_contents($langJSFile) . "\n});\n"; return $js; } @@ -55,8 +52,6 @@ class gantt extends wg protected function build() { global $app; - $cssFile = $app->getWebRoot() . 'js/dhtmlxgantt/min.css'; - $jsFile = $app->getWebRoot() . 'js/dhtmlxgantt/min.js'; list($id, $zooming, $colsWidth, $showChart) = $this->prop(array('id', 'zooming', 'colsWidth', 'showChart')); if(empty($id)) $id = 'ganttView'; @@ -73,15 +68,12 @@ class gantt extends wg return div ( - h::import($cssFile), - h::import($jsFile), jsVar('ganttID', $id), jsVar('projectID', $project ? $project->id : 0), jsVar('module', $app->rawModule), jsVar('method', $app->rawMethod), jsVar('jsRoot', $app->getWebRoot()), jsVar('fileName', $fileName), - jsVar('reviewPoints', $reviewPoints), jsVar('ganttType', $ganttType), jsVar('showFields', $showFields), jsVar('showChart', $showChart), @@ -101,7 +93,7 @@ class gantt extends wg setID('ganttContainer'), on::click('.toggle-all-icon')->call('toggleAllTasks'), div(setID($id), setClass('gantt is-collapsed')), - div(setID('myCover'), div(setID('gantt_here'))) + div(setID('myCover'), div(setID('gantt_here'), setData('reviewpoints', json_encode($reviewPoints)))) ); } } diff --git a/lib/zin/wg/header/v1.php b/lib/zin/wg/header/v1.php index caf78edf1e..bd3092cd7d 100644 --- a/lib/zin/wg/header/v1.php +++ b/lib/zin/wg/header/v1.php @@ -365,7 +365,7 @@ class header extends wg { $params = "model=kanban"; } - else if(!defined('TUTORIAL')) + elseif(!commonModel::isTutorialMode()) { $params = "programID=0&from=global"; $createMethod = 'createGuide'; diff --git a/lib/zin/wg/navbar/v1.php b/lib/zin/wg/navbar/v1.php index f82b27ed5b..ce5145d4d8 100644 --- a/lib/zin/wg/navbar/v1.php +++ b/lib/zin/wg/navbar/v1.php @@ -29,7 +29,7 @@ class navbar extends wg protected function getExecutionMoreItem($executionID) { - if(defined('TUTORIAL')) return; + if(commonModel::isTutorialMode()) return; global $lang, $app; @@ -106,7 +106,8 @@ class navbar extends wg protected function getAppBtnItem() { - if(defined('TUTORIAL')) return; + if(commonModel::isTutorialMode()) return; + global $app, $config, $lang; $condition = ''; diff --git a/module/action/config.php b/module/action/config.php index 60ad91f7aa..f7d072f6a7 100755 --- a/module/action/config.php +++ b/module/action/config.php @@ -89,7 +89,7 @@ $config->action->majorList['doc'] = array('releaseddoc'); $config->action->needGetProjectType = 'build,task,bug,case,testcase,caselib,testtask,testsuite,testreport,doc,issue,release,risk,design,opportunity,trainplan,gapanalysis,researchplan,researchreport,'; $config->action->needGetRelateField = ',branch,story,epic,requirement,productplan,release,task,build,bug,testcase,case,testtask,testreport,design,doc,doclib,issue,risk,opportunity,trainplan,gapanalysis,team,whitelist,researchplan,researchreport,meeting,kanbanlane,kanbancolumn,module,review,'; -$config->action->noLinkModules = ',doclib,module,webhook,gitlab,instance,gitea,gogs,sonarqube,pipeline,jenkins,kanban,kanbanspace,kanbancolumn,kanbanlane,kanbanregion,kanbancard,execution,project,traincategory,apistruct,program,product,user,entry,repo,pivot,scene,boardspace,auditplan,auditresult,productline,chapter,doc,'; +$config->action->noLinkModules = ',doclib,module,webhook,gitlab,instance,gitea,gogs,sonarqube,pipeline,jenkins,kanban,kanbanspace,kanbancolumn,kanbanlane,kanbanregion,kanbancard,execution,project,traincategory,apistruct,program,product,user,entry,repo,pivot,scene,boardspace,auditplan,auditresult,productline,chapter,doc,caselib,'; $config->action->ignoreObjectType4Dynamic = 'kanbanregion,kanbanlane,kanbancolumn'; $config->action->ignoreActions4Dynamic = 'disconnectxuanxuan,reconnectxuanxuan,loginxuanxuan,logoutxuanxuan,editmr,removemr,syncdoingbyticket,syncdoingbystory,syncdoingbyuserstory,syncdoingbyepic,syncdoingbytask,syncdoingbybug,syncdoingbytodo,syncdoingbydemand'; diff --git a/module/action/model.php b/module/action/model.php index 44c1b498b7..ae53f93eac 100755 --- a/module/action/model.php +++ b/module/action/model.php @@ -358,6 +358,14 @@ class actionModel extends model if(isset($fieldList[$history->old])) $history->oldValue = $fieldList[$history->old]; if(isset($fieldList[$history->new])) $history->newValue = $fieldList[$history->new]; } + + /* 如果是升级, 检查oldValue和newValue字段是否存在。以防止从老版本升级的时候,而这两个字段不存在,导致升级失败。 */ + if(!empty($this->app->upgrading) && (isset($history->oldValue) || isset($history->newValue))) + { + $existHistory = $this->dao->select('*')->from(TABLE_HISTORY)->limit(1)->fetch(); + if(!isset($existHistory->oldValue)) unset($history->oldValue, $history->newValue); + } + return $history; } @@ -1860,29 +1868,29 @@ class actionModel extends model /* 只保留允许的标签。 */ /* Keep only allowed tags. */ - $action->comment = trim(strip_tags($newComment->lastComment, $this->config->allowedTags)); + $action->comment = trim(strip_tags($newComment->lastComment, $this->config->allowedTags)); /* 处理评论内的图片。*/ /* Handle images in comment. */ - $action = $this->loadModel('file')->processImgURL($action, 'comment', $newComment->uid); + $action = $this->loadModel('file')->processImgURL($action, 'comment', $newComment->uid); - $this->dao->update(TABLE_ACTION) - ->set('date')->eq(helper::now()) - ->set('comment')->eq($newComment->lastComment) - ->where('id')->eq($actionID) - ->exec(); + $this->dao->update(TABLE_ACTION) + ->set('date')->eq(helper::now()) + ->set('comment')->eq($newComment->lastComment) + ->where('id')->eq($actionID) + ->exec(); - $this->file->updateObjectID($newComment->uid, $action->objectID, $action->objectType); - $this->file->processFileDiffsForObject('comment', $action, $newComment); - if(!empty($newComment->files)) - { - $action->files = $newComment->files; - $this->dao->update(TABLE_ACTION)->set('files')->eq($newComment->files)->where('id')->eq($actionID)->exec(); - } - $changes = common::createChanges($action, $newComment); - if($changes) $this->logHistory($actionID, $changes); + $this->file->updateObjectID($newComment->uid, $action->objectID, $action->objectType); + $this->file->processFileDiffsForObject('comment', $action, $newComment); + if(!empty($newComment->files)) + { + $action->files = $newComment->files; + $this->dao->update(TABLE_ACTION)->set('files')->eq($newComment->files)->where('id')->eq($actionID)->exec(); + } + $changes = common::createChanges($action, $newComment); + if($changes) $this->logHistory($actionID, $changes); - return true; + return true; } /** diff --git a/module/action/test/model/updatecomment.php b/module/action/test/model/updatecomment.php index 65e1a53f9f..9435599bcb 100755 --- a/module/action/test/model/updatecomment.php +++ b/module/action/test/model/updatecomment.php @@ -17,8 +17,8 @@ cid=1 - 测试更新action 1的备注, 备注被成功更新为备注1属性comment @备注1 - 测试更新action 2的备注, 备注被成功更新为备注2属性comment @备注2 -- 测试文件是否更新成功, 文件的objectType和objectID被更新为comment和2 - - 属性objectType @comment +- 查看更新后的文件 + - 属性objectType @story - 属性objectID @2 - 属性name @文件标题1 @@ -33,4 +33,4 @@ $file = new fileTest(); r($action->updateCommentTest($actionIDList[0], $commentList[0], $uidList[0])) && p('comment') && e('备注1'); // 测试更新action 1的备注, 备注被成功更新为备注1 r($action->updateCommentTest($actionIDList[1], $commentList[1], $uidList[1])) && p('comment') && e('备注2'); // 测试更新action 2的备注, 备注被成功更新为备注2 -r($file->getByIdTest(1)) && p('objectType;objectID;name') && e('comment;2;文件标题1'); //测试文件是否更新成功, 文件的objectType和objectID被更新为comment和2 +r($file->getByIdTest(1)) && p('objectType;objectID;name') && e('story;2;文件标题1'); // 查看更新后的文件 \ No newline at end of file diff --git a/module/action/view/trash.html.php b/module/action/view/trash.html.php deleted file mode 100755 index 5f319b012d..0000000000 --- a/module/action/view/trash.html.php +++ /dev/null @@ -1,206 +0,0 @@ - - * @package action - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -
-
- -
-

noData;?>

-
- -
- - recTotal}&recPerPage={$pager->recPerPage}"; ?> - - - - - - - - - - - - - - - - - - - - - - objectType == 'case' ? 'testcase' : $action->objectType;?> - - - - objectType == 'scene'): ?> - - - - - - - - - - - - - - - - - - - -
action->objectType);?>idAB);?>action->objectName;?>lang->project->project;?>lang->story->product;?>lang->task->execution;?>action->actor);?>action->date);?>actions;?>
action->objectTypes, $action->objectType, '');?>objectID;?> - objectName;?> - - objectType == 'user' ? "account={$action->objectName}" : "id={$action->objectID}"; - $methodName = 'view'; - if($module == 'caselib') - { - $methodName = 'view'; - $module = 'caselib'; - } - if($module == 'basicmeas') - { - $module = 'measurement'; - $methodName = 'setSQL'; - $params = "id={$action->objectID}"; - } - if($module == 'deploystep') - { - $module = 'deploy'; - $methodName = 'viewStep'; - } - if($action->objectType == 'api') - { - $params = "libID=0&moduelID=0&apiID={$action->objectID}"; - $methodName = 'index'; - } - if(strpos('traincourse,traincontents', $module) !== false) - { - $methodName = $module == 'traincourse' ? 'viewcourse' : 'viewchapter'; - $module = 'traincourse'; - } - if(isset($config->action->customFlows[$action->objectType])) - { - $flow = $config->action->customFlows[$action->objectType]; - $module = $flow->module; - } - if(strpos($this->config->action->noLinkModules, ",{$module},") !== false) - { - echo $action->objectName; - } - else - { - $tab = ''; - $canView = common::hasPriv($module, $methodName); - if($action->objectType == 'meeting') $tab = $action->project ? "data-app='project'" : "data-app='my'"; - if($module == 'requirement') $module = 'story'; - echo $canView ? html::a($this->createLink($module, $methodName, $params), $action->objectName, '_self', "title='{$action->objectName}' $tab") : "$action->objectName"; - } - ?> - - project]->name;?> - project]->deleted):?> - lang->project->deleted;?> - - - objectID]->productTitle;?> - objectID]->productDeleted):?> - lang->story->deleted;?> - - - execution]->name;?> - execution]->deleted):?> - lang->execution->deleted;?> - - actor);?>date;?> - id&browseType=$currentObjectType", $lang->action->undelete, 'hiddenwin'); - if($type == 'all') common::printLink('action', 'hideOne', "actionid=$action->id&browseType=$currentObjectType", $lang->action->hideOne, 'hiddenwin'); - ?> -
- -
- -
- diff --git a/module/admin/model.php b/module/admin/model.php index f4facb0f8d..a88a8de2ec 100755 --- a/module/admin/model.php +++ b/module/admin/model.php @@ -455,7 +455,7 @@ class adminModel extends model public function genDateUsed(): object { $firstUseDate = $this->dao->select('min(`date`) as `date`')->from(TABLE_ACTION) - ->where('`date`')->gt('1970-01-01') + ->where('`date`')->ge(FIRST_RELEASE_DATE) ->andWhere('actor')->eq($this->app->user->account) ->fetch('date'); diff --git a/module/admin/view/checkweak.html.php b/module/admin/view/checkweak.html.php deleted file mode 100755 index 152ab7ab6e..0000000000 --- a/module/admin/view/checkweak.html.php +++ /dev/null @@ -1,55 +0,0 @@ - - * @package admin - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
- -
-
- - - - - - - - - - - - - - - - - - - - - - - -
idAB;?>user->realname;?>user->account;?>user->phone;?>user->mobile;?>admin->safe->reason;?>actions;?>
id?>realname?>account?>phone?>mobile?>admin->safe->reasonList[$user->weakReason];?>id", '', 'list');?>
-
-
-
- diff --git a/module/admin/view/index.html.php b/module/admin/view/index.html.php deleted file mode 100755 index 8673a4c3f1..0000000000 --- a/module/admin/view/index.html.php +++ /dev/null @@ -1,172 +0,0 @@ - - * @package admin - * @version $Id: view.html.php 2568 2012-02-09 06:56:35Z shiyangyangwork@yahoo.cn $ - * @link https://www.zentao.net - */ -?> - -hasData);?> - -
-
-
-
admin->setting?>
-
- admin->menuList as $menuKey => $menu):?> - vision == 'lite' and !in_array($menuKey, $config->admin->liteMenuList)) continue;?> -
admin->noPriv}";?> data-id=""> - -
- -
-
- - plugins):?> -
-
- admin->pluginRecommendation;?> - admin->extensionURL, "{$lang->more} ", '_blank', 'class="more text-muted flex align-center"');?> -
-
> - plugins as $plugin):?> - abstract));?> -
- -

name;?>

-

-
- -
-
- - - -
-
-
admin->officialAccount?>
-
-
-
-
- admin->followUs?> - hasData):?> - - -
-
admin->followUsContent?>
-
-
- hasData and common::hasPriv('admin', 'register')):?> - - -
- classes):?> -
-
- admin->publicClass;?> - admin->classURL, "{$lang->more} ", '_blank', 'class="more text-muted flex align-center"');?> -
-
- classes as $class):?> - -
-
-
-
name;?>
-
- -
-
- - -
-
- - hasData and !$langNotCN):?> -
-
-
admin->zentaoInfo?>
-
- admin->zentaoUsed;?> - year):?> - year;?>year;?> - - month):?> - month;?>admin->mon;?> - - day;?>admin->day;?> -
-
-
-
-
admin->updateDynamics?>
- admin->downloadURL, "{$lang->more} ", '_blank', 'class="more text-muted flex align-center"');?> -
- dynamics as $dynamic):?> -
-
title ?>>link, $dynamic->title, '_blank');?>
-
addedDate, 0, 10);?>
-
- -
-
-
-
admin->updatePatch?>
- admin->patchURL, "{$lang->more} ", '_blank', 'class="more text-muted flex align-center"');?> -
- patches as $patch):?> -
-
-
name?>
- -
-
desc?>
-
- -
- edition, array('max', 'ipd'))):?> -
-
-
admin->upgradeRecommend?>
-
- edition != 'biz'):?> -
- -
admin->bizTag?>
-
admin->productDetail?>
-
- admin->productFeature['biz'] as $feature):?> -
- -
- -
- -
admin->maxTag?>
-
admin->productDetail?>
-
- admin->productFeature['max'] as $feature):?> -
- -
-
- -
- -
- diff --git a/module/admin/view/log.html.php b/module/admin/view/log.html.php deleted file mode 100755 index 1026463289..0000000000 --- a/module/admin/view/log.html.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @package admin - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -
-
-

webhook->setting;?>

-
-
-
- - - - - - - - - -
admin->days;?>admin->log->saveDays, "class='form-control'");?>
- - admin->info->log;?> -
-
-
-
- diff --git a/module/admin/view/resetpwdsetting.html.php b/module/admin/view/resetpwdsetting.html.php deleted file mode 100755 index 0707fd4097..0000000000 --- a/module/admin/view/resetpwdsetting.html.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @package admin - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -
- -
-
-

admin->resetPWDSetting;?>

-
-
-
- - - - - - - - - -
admin->resetPWDByMail;?> - resetPWDByMail) ? $config->resetPWDByMail : 0;?> - admin->safe->resetPWDList as $key => $value):?> - - -
-
-
-
-
- diff --git a/module/admin/view/safe.html.php b/module/admin/view/safe.html.php deleted file mode 100755 index 398f4c575e..0000000000 --- a/module/admin/view/safe.html.php +++ /dev/null @@ -1,110 +0,0 @@ - - * @package admin - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -admin);?> - - - -
- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
admin->safe->password?>admin->safe->modeList, isset($config->safe->mode) ? $config->safe->mode : 0, "onclick=showModeRule(this.value)")?>safe->changeWeak) ? $lang->admin->safe->noticeWeakMode : $lang->admin->safe->noticeMode;?>
admin->safe->weak?>safe->weak, "class='form-control' style='height:100px'")?>
admin->safe->changeWeak?>admin->safe->modifyPasswordList, isset($config->safe->changeWeak) ? $config->safe->changeWeak : 0, "onchange='changeWeakChange(this.value)'")?>
admin->safe->modifyPasswordFirstLogin?>admin->safe->modifyPasswordList, isset($config->safe->modifyPasswordFirstLogin) ? $config->safe->modifyPasswordFirstLogin : 0)?>
admin->safe->loginCaptcha?>admin->safe->loginCaptchaList, isset($config->safe->loginCaptcha) ? $config->safe->loginCaptcha : 0)?>admin->safe->noticeGd;?>
- - -
-
-
-
-
- - diff --git a/module/admin/view/setmodule.html.php b/module/admin/view/setmodule.html.php deleted file mode 100755 index 8c9608b72c..0000000000 --- a/module/admin/view/setmodule.html.php +++ /dev/null @@ -1,83 +0,0 @@ - - * @package admin - * @version $Id: setmodule.html.php 2568 2012-02-09 06:56:35Z shiyangyangwork@yahoo.cn $ - * @link https://www.zentao.net - */ -?> - -
-
-
-

admin->setModuleIndex;?>

-
-
- - - - - - - - - featureGroup as $group => $features):?> - - - - - - - - - - - - - - - - - - - - - -
admin->setModule->module;?>admin->setModule->optional;?>
-
- - -
-
- - - - -
- $lang->admin->setModule->{$feature}), $value, "data-code='{$code}'", 'inline');?> - -
- -
-
- - -
-
-
-
-
- diff --git a/module/admin/view/sso.html.php b/module/admin/view/sso.html.php deleted file mode 100755 index 24ceda5de4..0000000000 --- a/module/admin/view/sso.html.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @package admin - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
-
-
-
-

admin->sso;?>

-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
sso->turnon; ?>sso->turnonList, $turnon);?>
sso->redirect; ?>sso->turnonList, $redirect);?>
sso->addr; ?>sso->addrNotice}'");?>
sso->code; ?>
sso->key; ?>
- - -
-
-
sso->help?>
-
-
- diff --git a/module/admin/view/tableengine.html.php b/module/admin/view/tableengine.html.php deleted file mode 100755 index 7617a369d1..0000000000 --- a/module/admin/view/tableengine.html.php +++ /dev/null @@ -1,105 +0,0 @@ - - * @package admin - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
-
- $engine) - { - if($engine != 'InnoDB') $MyISAMCount ++; - $engineListHtml .= "
  • " . sprintf($lang->admin->engineInfo, $tableName, $engine) . "
  • \n"; - } - ?> -

    - 0):?> - admin->engineSummary['hasMyISAM'], $MyISAMCount);?> - admin->changeEngine, '', "class='btn btn-sm changeEngine btn-primary' onclick='changeAllEngines()'");?> - - admin->engineSummary['allInnoDB']);?> - -

    -
    -
    -
    -
    -
    -admin->changingTable);?> -admin->engineSummary['hasMyISAM']);?> - - diff --git a/module/api/view/create.html.php b/module/api/view/create.html.php deleted file mode 100644 index cd5d1bc971..0000000000 --- a/module/api/view/create.html.php +++ /dev/null @@ -1,228 +0,0 @@ - - * @package doc - * @version $Id: create.html.php 975 2010-07-29 03:30:25Z jajacn@126.com $ - * @link https://www.zentao.net - */ -?> - - - -struct->field); -js::set('langDesc', $lang->struct->desc); -js::set('structAdd', $lang->struct->add); -js::set('structDelete', $lang->delete); -js::set('addSubField', $lang->struct->addSubField); -js::set('struct_field', $lang->struct->field); -js::set('struct_desc', $lang->struct->desc); -js::set('struct_action', $lang->struct->action); -js::set('struct_required', $lang->struct->required); -js::set('struct_paramsType', $lang->struct->paramsType); -?> - - -
    -
    -
    -

    api->create;?>

    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    api->lib;?> - -
    api->module;?> - -
    api->formTitle;?>
    api->path;?> -
    -
    - api->protocalOptions, 'HTTP', "class='form-control chosen'");?> -
    -
    - api->methodOptions, 'GET', "class='form-control chosen'");?> -
    -
    - -
    -
    -
    api->requestType;?> - api->requestTypeOptions, 'application/json', "class='form-control chosen'");?> -
    api->status;?>api->statusOptions, apiModel::STATUS_DONE);?>
    api->owner;?> -
    - -
    -
    api->header;?> - - - - - - - - - - - - - - - - -
    struct->field;?>struct->required;?>struct->desc;?>struct->action;?>
    - - -
    - - -
    -
    - - - - -
    -
    api->query;?> - - - - - - - - - - - - - - - - -
    struct->field;?>struct->required;?>struct->desc;?>struct->action;?>
    - - -
    - - -
    -
    - - - - -
    -
    api->params;?> - - -
    api->paramsExample;?> -
    - -
    -
    api->response;?> - - -
    api->responseExample;?> -
    - -
    -
    api->desc;?> -
    -
    - - goback, "data-app='{$app->tab}' class='btn btn-back btn-wide'");?> -
    -
    -
    -
    - diff --git a/module/api/view/createlib.html.php b/module/api/view/createlib.html.php deleted file mode 100644 index 91a7656f3c..0000000000 --- a/module/api/view/createlib.html.php +++ /dev/null @@ -1,83 +0,0 @@ - - * @package doc - * @version $Id: createlib.html.php 975 2010-07-29 03:30:25Z jajacn@126.com $ - * @link https://www.zentao.net - */ -?> - - - -
    -
    -
    -
    -
    -

    api->createLib;?>

    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    api->libType;?> - api->libTypeList, $type, "onchange='toggleLibType(this.value)'")?> -
    api->product;?> - -
    api->project;?> - -
    api->name?>
    api->baseUrl?>api->baseUrlDesc . "'");?>
    api->control;?> - api->aclList, 'open', "onchange='toggleAcl(this.value, \"lib\")'", 'block');?> -
    -
    -
    -
    -
    -
    -productCommon);?> -projectCommon);?> - - diff --git a/module/api/view/createrelease.html.php b/module/api/view/createrelease.html.php deleted file mode 100644 index 2acd6ae37f..0000000000 --- a/module/api/view/createrelease.html.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @package doc - * @version $Id: createlib.html.php 975 2010-07-29 03:30:25Z jajacn@126.com $ - * @link https://www.zentao.net - */ -?> - - - -
    -
    -
    -
    -
    -

    api->createRelease;?>

    -
    -
    - - - - - - - - - - - - -
    api->version?>
    api->desc;?> - -
    -
    -
    -
    -
    -
    - diff --git a/module/api/view/createstruct.html.php b/module/api/view/createstruct.html.php deleted file mode 100644 index e2ff41d7c3..0000000000 --- a/module/api/view/createstruct.html.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @package doc - * @link https://www.zentao.net - */ -?> - - - - -api->paramsScopeOptions);?> -struct->add); -js::set('addSubField', $lang->struct->addSubField); -js::set('structDelete', $lang->delete); -js::set('langField', $lang->struct->field); -js::set('langDesc', $lang->struct->desc); -js::set('struct_field', $lang->struct->field); -js::set('struct_desc', $lang->struct->desc); -js::set('struct_action', $lang->struct->action); -js::set('struct_required', $lang->struct->required); -js::set('struct_paramsType', $lang->struct->paramsType); -js::set('struct', ''); -?> -
    -
    -
    -
    -

    api->createStruct;?>

    -
    -
    - - - - - - - - - - - - - - - - - - - -
    api->structName;?>
    - - -
    api->desc;?>
    - - goback, "data-app='{$app->tab}'");?> - goback, '', "class='btn btn-back btn-wide'");?> -
    -
    -
    -
    -
    - diff --git a/module/api/view/edit.html.php b/module/api/view/edit.html.php deleted file mode 100644 index 309af4cfe7..0000000000 --- a/module/api/view/edit.html.php +++ /dev/null @@ -1,231 +0,0 @@ - - * @package doc - * @version $Id: create.html.php 975 2010-07-29 03:30:25Z jajacn@126.com $ - * @link https://www.zentao.net - */ -?> - - - -lib);?> -struct->field); -js::set('langDesc', $lang->struct->desc); -js::set('structAdd', $lang->struct->add); -js::set('structDelete', $lang->delete); -js::set('addSubField', $lang->struct->addSubField); -js::set('struct_field', $lang->struct->field); -js::set('struct_desc', $lang->struct->desc); -js::set('struct_action', $lang->struct->action); -js::set('struct_required', $lang->struct->required); -js::set('struct_paramsType', $lang->struct->paramsType); -js::set('api', $api); -?> - -
    -
    -
    - -

    - id;?> - createLink('api', 'index', "apiID=$api->id"), $api->title, '', "title='$api->title'");?> - arrow . ' ' . $lang->api->edit;?> -

    -
    save, '', 'id="top-submit" class="btn btn-primary"');?>
    - -

    api->create;?>

    - -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    api->module;?> - -
    api->formTitle;?>title, "class='form-control' required");?>
    api->path;?>path, "class='form-control'");?>
    api->protocol;?>api->protocalOptions, $api->protocol ? $api->protocol : 'HTTP');?>
    api->method;?>api->methodOptions, $api->method ? $api->method : 'GET', "class='form-control chosen'");?>
    api->requestType;?>api->requestTypeOptions, $api->requestType ? $api->requestType : 'application/json', "class='form-control chosen'");?>
    api->status;?>api->statusOptions, $api->status ? $api->status : apiModel::STATUS_DOING);?>
    - api->owner;?> - -
    - owner ? $api->owner : $user, "class='form-control chosen'");?> -
    -
    api->header;?> - - - - - - - - - - - - - - - - -
    struct->field;?>struct->required;?>struct->desc;?>struct->action;?>
    - - -
    - - -
    -
    - - - - -
    -
    api->query;?> - - - - - - - - - - - - - - - - -
    struct->field;?>struct->required;?>struct->desc;?>struct->action;?>
    - - -
    - - -
    -
    - - - - -
    -
    api->params;?> - - -
    - api->paramsExample;?> - -
    - paramsExample, "style='width:100%;height:200px'");?> -
    -
    api->response;?> - - -
    - api->responseExample;?> - -
    - responseExample, "style='width:100%;height:200px'");?> -
    -
    api->desc;?> -
    desc, "style='width:100%;height:200px'");?>
    -
    - - editedDate);?> - goback, "data-app='{$app->tab}'");?> - goback, '', "class='btn btn-back btn-wide'");?> -
    -
    -
    -
    - diff --git a/module/api/view/editlib.html.php b/module/api/view/editlib.html.php deleted file mode 100644 index 8f670c2bea..0000000000 --- a/module/api/view/editlib.html.php +++ /dev/null @@ -1,70 +0,0 @@ - - * @package api - * @version $Id: editlib.html.php 975 2010-07-29 03:30:25Z jajacn@126.com $ - * @link https://www.zentao.net - */ -?> - - - -
    -
    -
    -
    -
    -

    api->editLib;?>

    -
    -
    - - - - - - - - - - - - - - - - - - - - '> - - - - - - -
    api->{$type};?>name?>
    api->name?>name, "class='form-control'");?>
    api->baseUrl?>baseUrl, "class='form-control'");?>
    api->control;?> - api->aclList, $lib->acl, "onchange='toggleAcl(this.value, \"lib\")'", 'block')?> -
    api->whiteList;?> -
    - api->group?> - groups, "class='form-control chosen' multiple");?> -
    -
    - api->user?> - users, "class='form-control chosen' multiple");?> - fetch('my', 'buildContactLists', "dropdownName=users&attr=data-drop_direction='up'");?> -
    -
    -
    -
    -
    -
    -
    -productCommon);?> -projectCommon);?> - diff --git a/module/api/view/editstruct.html.php b/module/api/view/editstruct.html.php deleted file mode 100644 index 02d80a3838..0000000000 --- a/module/api/view/editstruct.html.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @package doc - * @link https://www.zentao.net - */ -?> - - - - -api->paramsScopeOptions);?> -struct->add); -js::set('addSubField', $lang->struct->addSubField); -js::set('structDelete', $lang->delete); -js::set('langField', $lang->struct->field); -js::set('langDesc', $lang->struct->desc); -js::set('struct_field', $lang->struct->field); -js::set('struct_desc', $lang->struct->desc); -js::set('struct_action', $lang->struct->action); -js::set('struct_required', $lang->struct->required); -js::set('struct_paramsType', $lang->struct->paramsType); -js::set('struct', $struct); -?> -
    -
    -
    -
    -

    - name;?> - arrow . ' ' . $lang->api->editStruct;?> -

    -
    -
    - - - - - - - - - - - - - - - - - - - -
    api->structName;?>name, "class='form-control' required");?>
    - - -
    api->desc;?>desc, "class='form-control'");?>
    - - goback, "data-app='{$app->tab}'");?> - goback, '', "class='btn btn-back btn-wide'");?> -
    -
    -
    -
    -
    - diff --git a/module/api/view/index.html.php b/module/api/view/index.html.php deleted file mode 100644 index 1fde8b8a43..0000000000 --- a/module/api/view/index.html.php +++ /dev/null @@ -1,91 +0,0 @@ - - * @package doc - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -api->confirmDelete);?> - - -
    - -
    -

    - doc->noLib;?> - ' . $lang->api->createLib, '', 'class="btn btn-info iframe" data-width="800px"'); - ?> -

    -
    - - - -
    -
    - -
    - -
    - - - - diff --git a/module/api/view/releases.html.php b/module/api/view/releases.html.php deleted file mode 100644 index 5ca50f58c5..0000000000 --- a/module/api/view/releases.html.php +++ /dev/null @@ -1,76 +0,0 @@ - - * @package doc - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
    -
    - - -
    -

    noData;?>

    -
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - -
    idAB);?>api->version);?>api->desc;?>api->structAddedBy);?>api->structAddedDate);?>actions;?>
    id);?>version;?>>version;?>desc;?>>desc;?>addedBy, '');?>addedDate;?> - createLink('api', 'deleteRelease', "libID=$libID&id=$release->id"), '', 'hiddenwin', "title='{$lang->api->deleteRelease}' class='btn'");?> -
    -
    - -
    -
    - - diff --git a/module/api/view/struct.html.php b/module/api/view/struct.html.php deleted file mode 100644 index 365bd1f05e..0000000000 --- a/module/api/view/struct.html.php +++ /dev/null @@ -1,75 +0,0 @@ - - * @package doc - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
    -
    -
    - - -
    -

    - api->noStruct;?> -

    -
    - -
    - - - - recTotal}&recPerPage={$pager->recPerPage}";?> - - - - - - - - - - - - - - - - - - - - -
    idAB);?>api->structType);?>api->structName;?>api->structAddedBy);?>api->structAddedDate);?>actions;?>
    id);?>type;?>name;?>addedName;?>addedDate, 'Y-m-d');?> - createLink('api', 'editStruct', "libID=$libID&structID=$struct->id"), '', '', "title='{$lang->api->editStruct}' class='btn'"); - if(common::hasPriv('api', 'deleteStruct')) echo html::a($this->createLink('api', 'deleteStruct', "libID=$libID&structID=$struct->id"), '', 'hiddenwin', "title='{$lang->api->deleteStruct}' class='btn'"); - ?> -
    - -
    - -
    -
    - diff --git a/module/api/view/view.html.php b/module/api/view/view.html.php deleted file mode 100644 index 0a5dddd355..0000000000 --- a/module/api/view/view.html.php +++ /dev/null @@ -1,46 +0,0 @@ - - * @package doc - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -api->confirmDelete);?> - - - - -
    - - -
    -
    - -
    -
    - diff --git a/module/backup/view/index.html.php b/module/backup/view/index.html.php deleted file mode 100644 index 83f3968043..0000000000 --- a/module/backup/view/index.html.php +++ /dev/null @@ -1,140 +0,0 @@ - - * @package backup - * @version $Id: view.html.php 2568 2012-02-09 06:56:35Z shiyangyangwork@yahoo.cn $ - * @link https://www.zentao.net - */ -?> - - -
    -
    -
    - - -
    -
    -
    -

    - backup->history?> -

    -
    - " . $lang->backup->setting, '', "data-width='500' class='iframe btn btn-primary'");?> - " . $lang->backup->backup, "data-link='{$backupLink}'", 'btn btn-primary backup load-indicator'); - } - ?> -
    -
    - - - - - - - - - - - - - - - files);?> - - - files as $file => $summary):?> - - - - - - - - - - - - - - - - - - -
    backup->time?>backup->files?>backup->allCount?>backup->count?>backup->size?>backup->status?>actions?>
    1) echo "rowspan='$rowspan'"?>>time);?> class='text-left' style='padding-left:5px;'> - backup->processFileSize($size); - ?> - - - - - backup->statusList[$status];?> - - 1) echo "rowspan='$rowspan'"?>> - name}"), $lang->backup->rmPHPHeader, 'hiddenwin', "class='rmPHPHeader'"); - echo "
    "; - } - if(common::hasPriv('backup', 'restore')) echo html::a(inlink('restore', "file={$backupFile->name}&confirm=yes"), $lang->backup->restore, 'hiddenwin', "class='restore'"); - if(common::hasPriv('backup', 'delete')) echo html::a(inlink('delete', "file=$backupFile->name"), $lang->delete, 'hiddenwin'); - ?> -
    -

    - - backup->restoreTip;?> - backup->holdDays, $config->backup->holdDays)?> - -

    -
    -
    - - -backup->common);?> -backup->backup);?> -backup->getSpaceLoading);?> -backup->rmPHPHeader);?> -backup->confirmRestore);?> -backup->restore);?> -backup->error->timeout);?> -backup->insufficientDisk);?> - - diff --git a/module/backup/view/setting.html.php b/module/backup/view/setting.html.php deleted file mode 100644 index 587aaf8b67..0000000000 --- a/module/backup/view/setting.html.php +++ /dev/null @@ -1,55 +0,0 @@ - - * @package backup - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
    -
    -

    backup->setting;?>

    -
    - -
    - -
    - - - - - - - - - - - - - -
    -
    - backup->settingList, isset($config->backup->setting) ? $config->backup->setting : '');?> -
    -
    -
    - backup->settingDir;?> - backup->settingDir) ? $config->backup->settingDir : $this->app->getTmpRoot() . 'backup/', "class='form-control'");?> -
    -
    -
    - backup->change;?> - backup->holdDays, "class='form-control'");?> - day;?> -
    -
    -
    - -
    - - diff --git a/module/block/view/bugblock.html.php b/module/block/view/bugblock.html.php deleted file mode 100644 index 161be7af77..0000000000 --- a/module/block/view/bugblock.html.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @package block - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
    block->emptyTip;?>
    - - -
    - '> - - - - - - - - - - - - - bug->severityList as $severityKey => $severityValue) - { - if(!empty($severityKey) && (string)$severityKey != (string)$severityValue) - { - $hasCustomSeverity = true; - break; - } - } - ?> - - - get->entry}'" : ''; - ?> - - - - - - - - - processStatus('bug', $bug);?> - - - - -
    idAB?>bug->title;?>bug->abbr->severity?>priAB?>bug->deadline;?>bug->abbr->status;?>
    id);?>createLink('bug', 'view', "bugID=$bug->id"), $bug->title, '', "style='color: $bug->color'")?> - - ' title='bug->severityList, $bug->severity);?>' data-severity='severity;?>'>bug->severityList, $bug->severity, $bug->severity);?> - - - - bug->priList, $bug->pri)?>deadline) ? '' : $bug->deadline;?> - -
    -
    - diff --git a/module/block/view/buildblock.html.php b/module/block/view/buildblock.html.php deleted file mode 100644 index 4ba78f767b..0000000000 --- a/module/block/view/buildblock.html.php +++ /dev/null @@ -1,50 +0,0 @@ - - * @package block - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
    block->emptyTip;?>
    - -
    - - - - - - - - - - - - - - - get->entry}'" : ''; - $buildViewLink = $this->createLink('build', 'view', "buildID={$build->id}"); - $productViewLink = $this->createLink('product', 'browse', "productID={$build->product}"); - $projectViewLink = $this->createLink('projectbuild', 'browse', "projectID={$build->project}"); - ?> - > - - - - - - - - - - -
    idAB?>build->name;?>build->product;?>build->project;?>build->date;?>
    id);?>name);?>shadow ? $projectViewLink : $productViewLink, $build->productName);?>projectName);?>date?>
    -
    - diff --git a/module/block/view/caseblock.html.php b/module/block/view/caseblock.html.php deleted file mode 100644 index c182abbf30..0000000000 --- a/module/block/view/caseblock.html.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @package block - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
    block->emptyTip;?>
    - -
    - - '> - - - - - - - - - - - - - - - get->entry}'" : ''; - $viewLink = $this->createLink('testcase', 'view', "caseID={$case->id}"); - ?> - > - - - - - - - processStatus('testcase', $case);?> - - - - - -
    idAB?>priAB?>case->title;?>testtask->lastRunTime;?>testtask->lastRunResult;?>statusAB;?>
    id);?>case->priList, $case->pri, $case->pri)?>title?>lastRunDate)) echo date(DT_MONTHTIME1, strtotime($case->lastRunDate));?>lastRunResult) echo $lang->testcase->resultList[$case->lastRunResult];?> - - - -
    -
    - diff --git a/module/block/view/create.html.php b/module/block/view/create.html.php deleted file mode 100644 index f7b93d32f4..0000000000 --- a/module/block/view/create.html.php +++ /dev/null @@ -1,46 +0,0 @@ - - * @package block - * @version $Id$ - * @link https://www.zentao.net - */ -?> -app->getWebRoot(); -$jsRoot = $webRoot . "js/"; -include '../../common/view/chosen.html.php'; -?> - -
    -
    - -
    - -
    -
    - -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - - -
    -
    -
    - diff --git a/module/block/view/dashboard.html.php b/module/block/view/dashboard.html.php deleted file mode 100644 index 8abcd22944..0000000000 --- a/module/block/view/dashboard.html.php +++ /dev/null @@ -1,148 +0,0 @@ - - * @package block - * @version $Id$ - * @link https://www.zentao.net - */ -if($extView = $this->getExtViewFile(__FILE__)){include $extView; return helper::cd();} -$webRoot = $config->webRoot; -$jsRoot = $webRoot . "js/"; -$themeRoot = $webRoot . "theme/"; -if(isset($pageCSS)) css::internal($pageCSS); -$useGuest = $this->app->user->account == 'guest'; -?> - -
    - -
    -

    - block->noData;?> - createLink("block", "admin", "id=0&module=$module"), " {$lang->block->createBlock}", '', "data-toggle='modal' data-type='ajax' data-width='700' data-title='{$lang->block->createBlock}' class='btn btn-info'")?> - createLink("block", "ajaxReset", "module=$module"), " {$lang->block->reset}", 'hiddenwin', 'class="btn btn-info"')?> -

    -
    - -
    -
    - $block):?> - block->closed) && strpos(",{$config->block->closed},", ",{$block->source}|{$block->block},") !== false) continue;?> -
    params->color;?>' id='blockid?>' data-id='id?>' data-name='title?>' data-order='order?>' data-url='blockLink?>'> - block != 'welcome');?> - -
    -
    title;?>
    - - - -
    - -
    -
    - -
    -
    - $block):?> - block->closed) && strpos(",{$config->block->closed},", ",{$block->source}|{$block->block},") !== false) continue;?> -
    params->color;?>' id='blockid?>' data-id='id?>' data-name='title?>' data-order='order?>' data-url='blockLink?>'> - block != 'welcome');?> - -
    -
    title;?>
    - - - -
    - -
    -
    - -
    -
    -
    - -getExtViewFile(__FILE__)){include $extView; return helper::cd();}?> - diff --git a/module/block/view/doccollectlistblock.html.php b/module/block/view/doccollectlistblock.html.php deleted file mode 100644 index 08790f8563..0000000000 --- a/module/block/view/doccollectlistblock.html.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @package block - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
    - -

    doc->noDoc;?>

    - -
    - - -
    - - createLink('doc', 'view', "docID=$doc->id"), $doc->title, '', "title='{$doc->title}' class='doc-name' data-app='{$this->app->tab}'"); - } - else - { - echo "{$doc->title}"; - } - ?> -
    - - - doc->collectCount, $doc->collects);?> -
    -
    - - -
    - -
    diff --git a/module/block/view/docdynamicblock.html.php b/module/block/view/docdynamicblock.html.php deleted file mode 100644 index a0285848b6..0000000000 --- a/module/block/view/docdynamicblock.html.php +++ /dev/null @@ -1,37 +0,0 @@ - -
    block->emptyTip;?>
    - - -
    -
      - actor); - $class = $action->major ? 'active' : ''; - if(in_array($action->action, array('releaseddoc', 'collected'))) $class .= " {$action->action}"; - echo "
    • "; - if($action->objectLink) printf($lang->block->dynamicInfo, $action->date, $user, $action->actionLabel, $action->objectLabel, $action->objectLink, $action->objectName, $action->objectName); - if(!$action->objectLink) printf($lang->block->noLinkDynamic, $action->date, $action->objectName, $user, $action->actionLabel, $action->objectLabel, ' ' . $action->objectName); - echo "
    • "; - $i++; - } - ?> -
    -
    - diff --git a/module/block/view/docmycollectionblock.html.php b/module/block/view/docmycollectionblock.html.php deleted file mode 100644 index ad659509e1..0000000000 --- a/module/block/view/docmycollectionblock.html.php +++ /dev/null @@ -1,79 +0,0 @@ - - * @package block - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -
    - -

    doc->noDoc;?>

    - -
    - -
    - -
    - -
    - -
    - diff --git a/module/block/view/docrecentupdateblock.html.php b/module/block/view/docrecentupdateblock.html.php deleted file mode 100644 index eb99cb89ea..0000000000 --- a/module/block/view/docrecentupdateblock.html.php +++ /dev/null @@ -1,80 +0,0 @@ - - * @package block - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -
    - -

    doc->noDoc;?>

    - -
    - -
    - -
    - -
    - -
    - diff --git a/module/block/view/docstatisticblock.html.php b/module/block/view/docstatisticblock.html.php deleted file mode 100644 index 5e796c142c..0000000000 --- a/module/block/view/docstatisticblock.html.php +++ /dev/null @@ -1,79 +0,0 @@ - - * @package block - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
    -
    -
    -
    -
    -
    totalDocs;?>
    -
    doc->allDoc;?>
    -
    -
    -
    todayEditedDocs;?>
    -
    doc->todayEdited;?>
    -
    -
    -
    -
    -
    - - - - - -
    -
    myDoc->docViews;?>
    -
    doc->docViews;?>
    -
    -
    -
    myDoc->docCollects;?>
    -
    doc->docCollects;?>
    -
    -
    -
    -
    -
    -
    -
    myEditedDocs;?>
    -
    doc->docEdited;?>
    -
    -
    -
    -
    diff --git a/module/block/view/docviewlistblock.html.php b/module/block/view/docviewlistblock.html.php deleted file mode 100644 index 8db534d339..0000000000 --- a/module/block/view/docviewlistblock.html.php +++ /dev/null @@ -1,55 +0,0 @@ - - * @package block - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
    - -

    doc->noDoc;?>

    - -
    - - -
    - - createLink('doc', 'view', "docID=$doc->id"), $doc->title, '', "title='{$doc->title}' class='doc-name' data-app='{$this->app->tab}'"); - } - else - { - echo "{$doc->title}"; - } - ?> -
    - - - doc->viewCount, $doc->views);?> -
    -
    - - -
    - -
    diff --git a/module/block/view/executionoverviewblock.html.php b/module/block/view/executionoverviewblock.html.php deleted file mode 100644 index 91e0f9bc6f..0000000000 --- a/module/block/view/executionoverviewblock.html.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @package block - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
    -
    -
    -
    execution->allExecutions;?>
    -
    - execution->viewAll;?> -
    -
    -
    -
      - execution->statusList as $statusKey => $statusName):?> -
    • - createLink('execution', 'all', "type=$statusKey"), $overview[$statusKey]);?> - -
    • - -
    -
    -
    diff --git a/module/block/view/executionstatisticblock.html.php b/module/block/view/executionstatisticblock.html.php deleted file mode 100644 index a1fcc6899e..0000000000 --- a/module/block/view/executionstatisticblock.html.php +++ /dev/null @@ -1,210 +0,0 @@ - - -
    -
    - -
    -

    block->noData;?>

    -
    - -
    - -
    -
    - -
    -
    -
    -
    - -
    - task->statusList['done'];?> - progress;?>percent;?> -
    -
    -
    -
    -
    execution->totalEstimate;?>
    -
    totalEstimate;?> task->hour;?>
    -
    -
    - -
    execution->totalConsumed;?>
    -
    totalConsumed;?> task->hour;?>
    -
    -
    - -
    execution->totalLeft;?>
    -
    totalLeft;?> task->hour;?>
    -
    -
    -
    -
    -
    -
    task->yesterdayFinished;?> yesterdayFinished;?>
    -
    -
    -
    -
    -
    -
    - - - - - - - - - -
    task->allTasks;?> :totalTasks) ? 0 : html::a($this->createLink('execution', 'task', "executionID={$execution->id}&status=all"), $execution->totalTasks);?>
    task->noFinished;?> :undoneTasks) ? 0 : html::a($this->createLink('execution', 'task', "executionID={$execution->id}&status=undone"), $execution->undoneTasks);?>
    -
    -
    -
    - lifetime != 'ops' and !in_array($execution->attribute, array('request', 'review'))):?> -
    -
    story->released;?> releasedStories;?>
    -
    -
    -
    -
    -
    - - - - - - - - - -
    story->total;?> :totalStories) ? 0 : html::a($this->createLink('execution', 'story', "executionID={$execution->id}&storyType=story&orderBy=order_desc&type=all"), $execution->totalStories);?>
    story->unclosed;?> :unclosedStories) ? 0 : html::a($this->createLink('execution', 'story', "executionID={$execution->id}&storyType=story&orderBy=order_desc&type=unclosed"), $execution->unclosedStories);?>
    -
    -
    -
    - attribute != 'design'):?> -
    -
    bug->yesterdayResolved;?> yesterdayResolved;?>
    -
    -
    -
    -
    -
    -
    - - - - - - - - - -
    bug->allBugs;?> :totalBugs) ? 0 : html::a($this->createLink('execution', 'bug', "executionID={$execution->id}&productID=0&branch=0&orderBy=status,id_desc&build=0&type=all"), $execution->totalBugs);?>
    bug->unResolved;?> :activeBugs) ? 0 : html::a($this->createLink('execution', 'bug', "executionID={$execution->id}&productID=0&branch=0&orderBy=status,id_desc&build=0&type=unresolved"), $execution->activeBugs);?>
    -
    -
    -
    - - -
    -
    -
    - -
    - -
    -
    diff --git a/module/block/view/flowchart.html.php b/module/block/view/flowchart.html.php deleted file mode 100644 index 2d25032598..0000000000 --- a/module/block/view/flowchart.html.php +++ /dev/null @@ -1,33 +0,0 @@ -
    -block->flowchart as $flowName => $flow):?> - -
    - -
    - -
    - -
    - diff --git a/module/block/view/issueblock.html.php b/module/block/view/issueblock.html.php deleted file mode 100644 index db8c682161..0000000000 --- a/module/block/view/issueblock.html.php +++ /dev/null @@ -1,49 +0,0 @@ - -
    block->emptyTip;?>
    - - -
    - '> - - - - - - - - - - - - - - - get->entry}'" : ''; - ?> - - - - - - - - - processStatus('issue', $issue);?> - - - - -
    idAB?>issue->title?>priAB?>issue->severity;?>issue->deadline;?>issue->status;?>
    id);?>createLink('issue', 'view', "issueID=$issue->id", '', '', $issue->project), $issue->title)?>issue->priList, $issue->pri)?>issue->severityList, $issue->severity)?>deadline == '0000-00-00' ? '' : $issue->deadline;?> - -
    -
    - diff --git a/module/block/view/main.html.php b/module/block/view/main.html.php deleted file mode 100644 index e6696d0f9d..0000000000 --- a/module/block/view/main.html.php +++ /dev/null @@ -1,16 +0,0 @@ - - * @package block - * @version $Id$ - * @link http://www.zentao.pms - */ -$viewDir = dirname(__FILE__); -$extFire = $app->getExtensionRoot() . $config->edition . "/block/ext/view/{$code}block.html.php"; -$file2Include = file_exists($extFire) ? $extFire : "{$viewDir}/{$code}block.html.php"; -include $file2Include; -?> diff --git a/module/block/view/planblock.html.php b/module/block/view/planblock.html.php deleted file mode 100644 index 30ed5712a9..0000000000 --- a/module/block/view/planblock.html.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @package block - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
    block->emptyTip;?>
    - -
    - - - - - - - - - - - - - - - get->entry}'" : ''; - $planViewLink = $this->createLink('productplan', 'view', "planID={$plan->id}"); - $productViewLink = $this->createLink('product', 'view', "productID={$plan->product}"); - ?> - > - - - - - - - - - - -
    idAB?>productplan->product;?>productplan->title;?>productplan->begin;?>productplan->end;?>
    id;?>productName);?>title);?>begin?>end?>
    -
    - diff --git a/module/block/view/preference.html.php b/module/block/view/preference.html.php deleted file mode 100644 index ec2dc7c617..0000000000 --- a/module/block/view/preference.html.php +++ /dev/null @@ -1,242 +0,0 @@ - -
    -
    '> - - - - - - systemMode, array('ALM', 'PLM'))):?> - - - - - - - - - - vision != 'or'):?> - - - - - - - - - - - - -
    my->storyConcept;?>
    my->programLink;?>my->programLinkList, $programLink, "class='form-control picker programLink'");?>
    my->productLink;?>my->productLinkList, $productLink, "class='form-control picker productLink'");?>
    my->projectLink;?>my->projectLinkList, $projectLink, "class='form-control picker projectLink'");?>
    my->executionLink;?>my->executionLinkList, $executionLink, "class='form-control picker executionLink'");?>
    - -
    -
    -
    - - diff --git a/module/block/view/productdocblock.html.php b/module/block/view/productdocblock.html.php deleted file mode 100644 index 2a69c671a9..0000000000 --- a/module/block/view/productdocblock.html.php +++ /dev/null @@ -1,208 +0,0 @@ - - - - - - - - -
    -
    -
    -

    block->emptyTip;?>

    -
    -
    - - -
    -
    - -
    - id])):?> -
    - - - - - - - - - - - id] as $doc):?> - - - - - - - - -
    doc->title?>doc->addedBy?>doc->addedDate?>doc->editedDate?>
    - doc->iconList, $doc->type); - $icon = html::image("static/svg/{$docType}.svg", "class='file-icon'"); - if(common::hasPriv('doc', 'view')) - { - echo html::a($this->createLink('doc', 'view', "docID=$doc->id"), $icon . $doc->title, '', "title='{$doc->title}' class='doc-title' data-app='{$this->app->tab}'"); - } - else - { - echo "$icon {$doc->title}"; - } - if($doc->status == 'draft') echo "{$lang->doc->draft}"; - ?> - addedBy);?>addedDate, 0, 10);?>editedDate, 0, 10);?>
    -
    - -
    -

    block->emptyTip;?>

    -
    - -
    - -
    -
    -
    diff --git a/module/block/view/productoverviewblock.html.php b/module/block/view/productoverviewblock.html.php deleted file mode 100644 index d874b80b8f..0000000000 --- a/module/block/view/productoverviewblock.html.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @package block - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
    -
    -
    - -
    - product->all;?> - createLink('product', 'all', "browseType=all"), $total, '', "class='text-primary'");?> -
    -
    -
    -
    -
      -
    • product->statusList['normal'];?>   createLink('product', 'all', "browseType=noclosed"), $normal, '', "class='text-primary'");?>
    • -
    • product->statusList['closed'];?>   createLink('product', 'all', "browseType=closed"), $closed, '', "class='text-primary'");?>
    • -
    -
    -
    diff --git a/module/block/view/productstatisticblock.html.php b/module/block/view/productstatisticblock.html.php deleted file mode 100644 index c971ed989d..0000000000 --- a/module/block/view/productstatisticblock.html.php +++ /dev/null @@ -1,219 +0,0 @@ - - * @package block - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -
    -
    - -
    -

    block->noData;?>

    -
    - -
    - -
    -
    - -
    -
    -
    -
    -
    SRCommon;?>
    - stories):?> -
    stories);?>
    - id}&branch=&type=allstory", $lang->story->viewAll . '', '', 'class="btn btn-primary btn-circle btn-icon-right btn-sm" data-app="product"');?> - -
    0
    - id}", '' . $lang->story->create, '', 'class="btn btn-primary btn-circle btn-icon-left btn-sm" data-app="product"');?> - -
    -
      - statistic->storyStages as $stage):?> -
    • -
      - story->stageList, $stage);?> - stories ? zget($product->stories, $stage, 0) : 0;?> -
      -
    • - -
    -
    - stories):?> -
    -
    - plans ? array_sum($product->plans) : 0;?> - plans ? zget($product->plans, 'unexpired', 0) : 0;?> - - -
    -
    -
    -
    - -
    - id}", " " . $lang->productplan->create, '', "class='btn btn-info' data-app='product'");?> -
    - -
    -
    - - - - - - - - - -
    productplan->all;?> :createLink('productplan', 'browse', "productID={$product->id}&branch=0&browseType=all"), $totalPlan);?>
    productplan->unexpired;?> :createLink('productplan', 'browse', "productID={$product->id}&branch=0&browseType=unexpired"), $unexpiredPlan);?>
    -
    -
    -
    -
    - releases ? array_sum($product->releases) : 0;?> - releases ? zget($product->releases, 'normal', 0) : 0;?> - - -
    - lastRelease):?> - release->yesterday;?> lastRelease;?> - -
    -
    -
    -
    - -
    - id}", " " . $lang->release->create, '', "class='btn btn-info' data-app='product'");?> -
    - -
    -
    - - - - - - - - - -
    product->allRelease;?> :createLink('release', 'browse', "productID={$product->id}&branch=0&type=all"), $totalRelease);?>
    product->maintain;?> :createLink('release', 'browse', "productID={$product->id}&branch=0&type=normal"), $normalRelease);?>
    -
    -
    -
    -
    - -
    -
    - -
    - -
    -
    diff --git a/module/block/view/projectblock.html.php b/module/block/view/projectblock.html.php deleted file mode 100644 index 6f7aed43d5..0000000000 --- a/module/block/view/projectblock.html.php +++ /dev/null @@ -1,48 +0,0 @@ - -
    block->emptyTip;?>
    - - -
    - '> - - - - - - - - - - - - - - - - - - createLink('project', 'index', "programID={$project->id}");?> - - - - - - - - app->getClientLang(), array('zh-cn','zh-tw')) ? round((float)$project->budget / 10000, 2) . $this->lang->project->tenThousand : round((float)$project->budget, 2);?> - - - - - - - - -
    project->name;?>project->PM;?>project->status;?>project->teamCount;?>task->consumed;?>project->budget;?>project->leftStories;?>project->leftTasks;?>project->leftBugs;?>
    name);?>PM, $project->PM)?> - project->statusList, $project->status);?> - teamCount;?>consumed . $lang->execution->workHourUnit;?>budget != 0 ? zget($lang->project->currencySymbol, $project->budgetUnit) . ' ' . $programBudget : $lang->project->future;?>leftStories;?>leftTasks;?>leftBugs;?>
    -
    - diff --git a/module/block/view/projectdocblock.html.php b/module/block/view/projectdocblock.html.php deleted file mode 100644 index 7a16ee7ea5..0000000000 --- a/module/block/view/projectdocblock.html.php +++ /dev/null @@ -1,208 +0,0 @@ - - - - - - - - -
    -
    -
    -

    block->emptyTip;?>

    -
    -
    - - -
    -
    - -
    - id])):?> -
    - - - - - - - - - - - id] as $doc):?> - - - - - - - - -
    doc->title?>doc->addedBy?>doc->addedDate?>doc->editedDate?>
    - doc->iconList, $doc->type); - $icon = html::image("static/svg/{$docType}.svg", "class='file-icon'"); - if(common::hasPriv('doc', 'view')) - { - echo html::a($this->createLink('doc', 'view', "docID=$doc->id"), $icon . $doc->title, '', "title='{$doc->title}' class='doc-title' data-app='{$this->app->tab}'"); - } - else - { - echo "$icon {$doc->title}"; - } - if($doc->status == 'draft') echo "{$lang->doc->draft}"; - ?> - addedBy);?>addedDate, 0, 10);?>editedDate, 0, 10);?>
    -
    - -
    -

    block->emptyTip;?>

    -
    - -
    - -
    -
    -
    diff --git a/module/block/view/projectdynamicblock.html.php b/module/block/view/projectdynamicblock.html.php deleted file mode 100644 index f08c9f4f37..0000000000 --- a/module/block/view/projectdynamicblock.html.php +++ /dev/null @@ -1,36 +0,0 @@ - -
    block->emptyTip;?>
    - - -
    -
      - actor); - if($action->action == 'login' or $action->action == 'logout') $action->objectName = $action->objectLabel = ''; - $class = $action->major ? "class='active'" : ''; - echo "
    • "; - printf($lang->block->dynamicInfo, $action->date, $user, $action->actionLabel, $action->objectLabel, $action->objectLink, $action->objectName, $action->objectName); - echo "
    • "; - $i++; - } - ?> -
    -
    - diff --git a/module/block/view/projectstatisticblock.html.php b/module/block/view/projectstatisticblock.html.php deleted file mode 100755 index acc2b7f7b5..0000000000 --- a/module/block/view/projectstatisticblock.html.php +++ /dev/null @@ -1,268 +0,0 @@ - - -
    -
    - -
    -

    block->emptyTip;?>

    -
    - -
    - -
    -
    - -
    -
    - model, array('scrum', 'kanban', 'agileplus'))):?> -
    -
    -

    block->storyCount;?>

    -
    -
    block->allStories . ":";?>
    -
    allStories;?>
    -
    -
    -
    block->finish . ":";?>
    -
    doneStories;?>
    -
    -
    -
    project->surplus . ":";?>
    -
    leftStories;?>
    -
    -
    -
    -

    block->investment;?>

    -
    -
    block->totalPeople . ":";?>
    -
    teamCount;?>
    -
    -
    -
    block->estimate . ":";?>
    -
    estimate . $lang->execution->workHourUnit;?>
    -
    -
    -
    block->consumedHours . ":";?>
    -
    consumed . $lang->execution->workHourUnit;?>
    -
    -
    -
    -

    block->taskCount;?>

    -
    -
    block->wait . ":";?>
    -
    waitTasks;?>
    -
    -
    -
    block->doing . ":";?>
    -
    doingTasks;?>
    -
    -
    -
    block->done . ":";?>
    -
    rndDoneTasks;?>
    -
    -
    -
    -

    block->bugCount;?>

    -
    -
    block->totalBug . ":";?>
    -
    allBugs;?>
    -
    -
    -
    bug->statusList['resolved'] . ":";?>
    -
    doneBugs;?>
    -
    -
    -
    bug->unResolved . ":";?>
    -
    leftBugs;?>
    -
    -
    -
    - executions) and $project->multiple):?> -
    -

    block->last;?>

    -
    -
    createLink('execution', 'task', "executionID={$project->executions[0]->id}"), $project->executions[0]->name, '', "title='{$project->executions[0]->name}'");?>
    -
    -
    -
    - executions[0]->hours->progress) ? $project->executions[0]->hours->progress . '%' : '0%';?> -
    -
    -
    -
    -
    - - -
    -
    - project->weekly;?> - current;?> -
    -
    -
    -
    - project->progress . ':';?> - progress . '%';?> -
    -
    -
    -
    -
    -
    - project->teamCount . ':';?> - teamCount;?> -
    -
    - project->budget . ':';?> - - app->getClientLang(), array('zh-cn','zh-tw')) ? round((float)$project->budget / 10000, 2) . $this->lang->project->tenThousand : round((float)$project->budget, 2); - echo $project->budget != 0 ? $projectBudget : $this->lang->project->future; - ?> - -
    -
    -
    -
    - app->getClientLang(), array('zh-cn','zh-tw'));?> -
    project->pv . '(' . $lang->project->pvTitle . ')' : $lang->project->pv; ?>
    -
    project->ev . '(' . $lang->project->evTitle . ')' : $lang->project->ev;?>
    -
    project->ac . '(' . $lang->project->acTitle . ')' : $lang->project->ac;?>
    -
    project->sv . '(' . $lang->project->svTitle . ')' : $lang->project->sv;?>
    -
    project->cv . '(' . $lang->project->cvTitle . ')' : $lang->project->cv;?>
    -
    -
    -
    pv;?>
    -
    ev;?>
    -
    ac;?>
    -
    sv;?>
    -
    cv;?>
    -
    -
    - -
    -
    - -
    - -
    -
    diff --git a/module/block/view/qastatisticblock.html.php b/module/block/view/qastatisticblock.html.php deleted file mode 100644 index 079d2b14c2..0000000000 --- a/module/block/view/qastatisticblock.html.php +++ /dev/null @@ -1,185 +0,0 @@ - - -
    -
    -
    - -
    -
    - - -
    -
    -
    - testtask):?> - testtask->name;?> - id}");?>" class="text-primary">block->lblTesttask;?> - -
    -
    -
    -
    -
    - -
    - bug->allBugs;?> - total) ? 0 : html::a($this->createLink('bug', 'browse', "productID={$product->id}&branch=&type=all"), $product->total);?> -
    -
    -
    -   bug->assignToMe;?>   assignedToMe) ? 0 : html::a($this->createLink('bug', 'browse', "productID={$product->id}&branch=&browseType=assigntome"), $product->assignedToMe);?> -
    -
    -
    -
    - yesterdayResolved):?> -
    bug->yesterdayResolved;?> yesterdayResolved;?>
    - -
    -
    -
    -
    -
    - bug->unResolved;?> -
    -
    - unresolved) ? 0 : html::a($this->createLink('bug', 'browse', "productID={$product->id}&branch=&browseType=unresolved"), $product->unresolved);?> -
    -
    -
    -
    - yesterdayConfirmed):?> -
    bug->yesterdayConfirmed;?> yesterdayConfirmed;?>
    - -
    -
    -
    -
    -
    - bug->unconfirmed;?> -
    -
    - unconfirmed) ? 0 : html::a($this->createLink('bug', 'browse', "productID={$product->id}&branch=&browseType=unconfirmed"), $product->unconfirmed);?> -
    -
    -
    -
    - yesterdayClosed):?> -
    bug->yesterdayClosed;?> yesterdayClosed;?>
    - -
    -
    -
    -
    -
    - bug->unclosed;?> -
    -
    - unclosed) ? 0 : html::a($this->createLink('bug', 'browse', "productID={$product->id}&branch=&browseType=unclosed"), $product->unclosed);?> -
    -
    -
    -
    -
    -
    - - -
    -
    -
    diff --git a/module/block/view/recentprojectblock.html.php b/module/block/view/recentprojectblock.html.php deleted file mode 100644 index da19da4548..0000000000 --- a/module/block/view/recentprojectblock.html.php +++ /dev/null @@ -1,135 +0,0 @@ - -
    - -
    block->emptyTip;?>
    - -
    - $project):?> - createLink('project', 'index', "projectID=$project->id");?> -
    -
    -
    - model == 'waterfall' ? 'label-warning' : 'label-info';?> - project->{$project->model};?> - name);?> - -
    -
    -
    - project->membersUnit, $project->teamCount); ?> - project->hoursUnit, $project->estimate); ?> -
    - model === 'waterfall'):?> -
    - executions as $project) - { - if($project->grade == 1) $projectProjects[] = $project; - } - ?> - -
    project->statusList, $project->status);?>
    - -

    project->ongoingStage;?>

    -
    -
    - -
    '> -
    name;?>
    -
    - -
    -
    - -
    - multiple):?> - executions ) ? '' : end($project->executions);?> -
    - -

    type == 'kanban' ? $lang->project->lastKanban : $lang->project->lastIteration;?>

    -
    -
    createLink('execution', 'task', "executionID={$project->id}"), $project->name);?>
    -
    -
    -
    - hours->progress;?>% -
    -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    - diff --git a/module/block/view/releaseblock.html.php b/module/block/view/releaseblock.html.php deleted file mode 100644 index be44e8df25..0000000000 --- a/module/block/view/releaseblock.html.php +++ /dev/null @@ -1,58 +0,0 @@ - - * @package block - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
    block->emptyTip;?>
    - -
    - - - - - - - - - - - - - - - - - - get->entry}'" : ''; - $productViewLink = $this->createLink('product', 'browse', "productID={$release->product}"); - $buildViewLink = $this->createLink('build', 'view', "buildID={$release->build}"); - $releaseViewLink = $this->createLink('release', 'view', "releaseID={$release->id}"); - ?> - > - - - - - - - - - - - - - -
    idAB?>release->product;?>release->name;?>release->build;?>release->date;?>release->status;?>
    id);?>productName);?>name);?>buildName);?>date?> - release->statusList, $release->status);?> -
    -
    - diff --git a/module/block/view/riskblock.html.php b/module/block/view/riskblock.html.php deleted file mode 100644 index 1a9a4e0fb2..0000000000 --- a/module/block/view/riskblock.html.php +++ /dev/null @@ -1,51 +0,0 @@ - -
    block->emptyTip;?>
    - - -
    - '> - - - - - - - - - - - - - - - get->entry}'" : ''; - ?> - - - - - - - - - processStatus('risk', $risk);?> - - - - -
    idAB?>risk->name?>priAB?>risk->category;?>risk->plannedClosedDate;?>risk->status;?>
    id);?>createLink('risk', 'view', "riskID=$risk->id", '', '', $risk->project), $risk->name)?>pri}'>" . zget($lang->risk->priList, $risk->pri) . "";?>risk->categoryList, $risk->category)?>plannedClosedDate == '0000-00-00' ? '' : $risk->plannedClosedDate;?> - -
    -
    - diff --git a/module/block/view/scrumissueblock.html.php b/module/block/view/scrumissueblock.html.php deleted file mode 100644 index 7f4ca97119..0000000000 --- a/module/block/view/scrumissueblock.html.php +++ /dev/null @@ -1,50 +0,0 @@ - -
    block->emptyTip;?>
    - - -
    - '> - - - - - - - - - - - - - - - - - createLink('issue', 'view', "issueID={$issue->id}"); - ?> - - - - - - - - - - - - - - -
    idAB;?>issue->type;?> issue->title;?>issue->severity;?>issue->pri;?>issue->owner;?>issue->assignedTo;?>issue->status;?>
    id);?>issue->typeList, $issue->type);?>title);?>issue->severityList, $issue->severity, $issue->severity)?>issue->priList, $issue->pri, $issue->pri)?>owner, $issue->owner)?>assignedTo, $issue->assignedTo)?> - issue->statusList, $issue->status);?> -
    -
    - diff --git a/module/block/view/scrumlistblock.html.php b/module/block/view/scrumlistblock.html.php deleted file mode 100644 index ca585bd28d..0000000000 --- a/module/block/view/scrumlistblock.html.php +++ /dev/null @@ -1,76 +0,0 @@ - - * @package block - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -
    block->emptyTip;?>
    - -
    - - - - - - - - - - - - - - - - - - - - - - get->entry}'" : "class='text-center'"; - $viewLink = $this->createLink('execution', 'task', 'executionID=' . $execution->id); - ?> - > - - - - - - - - - - - - - - - -
    execution->name;?>execution->end;?>statusAB;?>execution->totalEstimate;?>execution->totalConsumed;?>execution->totalLeft;?>execution->progress;?>execution->burn;?>
    name, '', "title='$execution->name' class='text-primary'");?>end;?> - delay)):?> - execution->delayed;?> - - processStatus('execution', $execution);?> - - - hours->totalEstimate . $lang->execution->workHourUnit;?>hours->totalConsumed . $lang->execution->workHourUnit;?>hours->totalLeft . $lang->execution->workHourUnit;?> -
    -
    hours->progress);?>
    -
    -
    burns);?>'>
    -
    - diff --git a/module/block/view/scrumoverviewblock.html.php b/module/block/view/scrumoverviewblock.html.php deleted file mode 100644 index d74c0b8262..0000000000 --- a/module/block/view/scrumoverviewblock.html.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @package block - * @version $Id$ - * @link https://www.zentao.net - */ -?> -config->vision;?> - -
    " . $lang->project->create, '', "class='btn btn-primary'")?>
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    block->storyCount;?>block->investment;?>block->taskCount;?>block->bugCount;?>
    block->totalStory . ':';?>allStories;?>block->totalPeople . ':';?>teamCount ? html::a($this->createLink('project', 'team', 'projectID=' . $projectID), $totalData[$projectID]->teamCount) : 0;?>block->wait : $lang->block->totalTask) . ':';?>waitTasks : $totalData[$projectID]->allTasks;?>block->totalBug . ':';?>allBugs;?>
    block->done . ':';?>doneStories;?>block->estimate . ':';?>estimate . $lang->execution->workHourUnit;?>block->doing : $lang->block->done) . ':';?>doingTasks: $totalData[$projectID]->liteDoneTasks;?>bug->statusList['resolved'] . ':';?>doneBugs;?>
    block->left . ':';?>leftStories;?>block->consumedHours . ':';?>consumed . $lang->execution->workHourUnit;?>block->done . ':' : $lang->block->undone;?>rndDoneTasks : $totalData[$projectID]->leftTasks;?>bug->unResolved . ':';?>leftBugs;?>
    - - diff --git a/module/block/view/scrumriskblock.html.php b/module/block/view/scrumriskblock.html.php deleted file mode 100644 index 47e4e9af30..0000000000 --- a/module/block/view/scrumriskblock.html.php +++ /dev/null @@ -1,58 +0,0 @@ - -
    block->emptyTip;?>
    - - -
    - '> - - - - - - - - - - - - - - - - - - - createLink('risk', 'view', "riskID={$risk->id}"); - ?> - - - - - - - - - - - - - - - - -
    idAB;?>risk->name;?> risk->strategy;?>risk->status;?>risk->rate;?>risk->pri;?>risk->assignedTo;?>risk->category;?>
    id);?>name);?>risk->strategyList, $risk->strategy, $risk->strategy)?> - risk->statusList, $risk->status);?> - rate?>pri}'>" . zget($lang->risk->priList, $risk->pri) . "";?>assignedTo, $risk->assignedTo)?>risk->categoryList, $risk->category, $risk->category)?>
    -
    - diff --git a/module/block/view/scrumtestblock.html.php b/module/block/view/scrumtestblock.html.php deleted file mode 100644 index 9f93bf3d5c..0000000000 --- a/module/block/view/scrumtestblock.html.php +++ /dev/null @@ -1,55 +0,0 @@ - - * @package block - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
    block->emptyTip;?>
    - -
    - - - - - hasProduct):?> - - - - - - - - - - - - get->entry}'" : ''; - $productViewLink = $this->createLink('product', 'browse', "productID={$testtask->product}"); - $projectViewLink = $this->createLink('project', 'view', "projectID={$testtask->project}"); - $testtaskViewLink = $this->createLink('testtask', 'view', "testtaskID={$testtask->id}"); - $buildViewLink = $this->createLink('build', 'view', "buildID={$testtask->build}"); - ?> - > - - hasProduct):?> - - - - - - - - - - -
    testtask->name;?>testtask->product;?>testtask->project?>testtask->build;?>testtask->status;?>
    name);?>productName);?>projectName);?>buildName);?>testtask->statusList, $testtask->status)?>
    -
    - diff --git a/module/block/view/sprintblock.html.php b/module/block/view/sprintblock.html.php deleted file mode 100644 index 732a78c395..0000000000 --- a/module/block/view/sprintblock.html.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @package block - * @version $Id$ - * @link https://www.zentao.net - */ -?> -total): ?> -
    block->emptyTip;?>
    - - -
    -
    -
    -
    block->allExecutions;?>
    - createLink('project', 'execution')?> -
    total ? html::a($projectLink, $summary->total) : 0;?>
    -
    -
    -
    -
      -
    • - - doing;?> - - block->doingExecution;?> -
    • -
    • - - closed;?> - - block->finishExecution;?> -
    • -
    -
    -
    - diff --git a/module/block/view/storyblock.html.php b/module/block/view/storyblock.html.php deleted file mode 100644 index 2640621edc..0000000000 --- a/module/block/view/storyblock.html.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @package block - * @version $Id$ - * @link https://www.zentao.net - */ -?> -app->loadLang('story');?> - -
    block->emptyTip;?>
    - - -
    - '> - - - - - - - - - - - - - - - get->entry}'" : ''; - $viewLink = $this->createLink('story', 'view', "storyID={$story->id}"); - ?> - > - - - - - processStatus('story', $story);?> - - - - - - - -
    idAB?>story->title;?>priAB?>statusAB;?>story->estimateAB;?>story->stageAB;?>
    id);?>title);?>story->priList, $story->pri, $story->pri)?> - - estimate . $config->hourUnit?> - - story->stageList, $story->stage, $story->stage);?> - -
    -
    - diff --git a/module/block/view/taskblock.html.php b/module/block/view/taskblock.html.php deleted file mode 100644 index e2d51e037e..0000000000 --- a/module/block/view/taskblock.html.php +++ /dev/null @@ -1,65 +0,0 @@ - - * @package block - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
    block->emptyTip;?>
    - - -
    - '> - - - - - - - - - - - - - - - get->entry}'" : ''; - ?> - - - executionType == 'kanban' ? true : ''; - $class = $task->executionType == 'kanban' ? "class='iframe' data-toggle='modal'" : ''; - ?> - - - processStatus('task', $task);?> - - - - - - - - -
    idAB;?> task->name;?>priAB?>statusAB;?>task->deadlineAB;?>task->estimateAB;?>
    id);?>createLink('task', 'view', "taskID=$task->id", '', $onlybody, $task->project), $task->name, null, "$class data-width='80%'")?>task->priList, $task->pri)?> - - deadline, 0, 4) > 0) echo $task->deadline;?>estimate . $lang->execution->workHourUnit;?>
    -
    - diff --git a/module/block/view/testtaskblock.html.php b/module/block/view/testtaskblock.html.php deleted file mode 100644 index 3421907a85..0000000000 --- a/module/block/view/testtaskblock.html.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @package block - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
    block->emptyTip;?>
    - -
    - - - - - - - - - - - - - - - - - - get->entry}'" : ''; - $productViewLink = $this->createLink('product', 'browse', "productID={$testtask->product}"); - $buildViewLink = $this->createLink('build', 'view', "buildID={$testtask->build}"); - $testtaskViewLink = $this->createLink('testtask', 'view', "testtaskID={$testtask->id}"); - - if($testtask->shadow) - { - $testtask->productName = zget($projects, $testtask->project); - $productViewLink = $this->createLink('projectstory', 'story', "projectID={$testtask->project}&productID={$testtask->product}"); - } - ?> - > - - - - - - - - - - - - - -
    idAB?>testtask->product;?>testtask->name;?>testtask->execution . '/' . $lang->testtask->build;?>testtask->begin;?>testtask->end;?>
    id);?>productName);?>name);?>buildName?>'>projectName . '/' . $testtask->buildName);?>begin?>end?>
    -
    - diff --git a/module/block/view/themeswitch.html.php b/module/block/view/themeswitch.html.php deleted file mode 100644 index 8e8be6c1de..0000000000 --- a/module/block/view/themeswitch.html.php +++ /dev/null @@ -1,47 +0,0 @@ - - -
    - -block->themes as $themeKey => $themeName):?> - "?> -
    - webRoot . "theme/default/images/guide/theme_{$themeKey}.png");?> - cookie->theme == $themeKey ? '' : 'hidden';?> - cookie->theme == $themeKey ? 'active' : '';?> -
    -
    - ";?> - - -
    diff --git a/module/block/view/visionswitch.html.php b/module/block/view/visionswitch.html.php deleted file mode 100644 index 3cb0969617..0000000000 --- a/module/block/view/visionswitch.html.php +++ /dev/null @@ -1,53 +0,0 @@ - -config->vision);?> - - - diff --git a/module/block/view/waterfallestimateblock.html.php b/module/block/view/waterfallestimateblock.html.php deleted file mode 100644 index 5135671541..0000000000 --- a/module/block/view/waterfallestimateblock.html.php +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - -
    durationestimation->people;?>workestimation->duration;?>
    durationestimation->members;?>workestimation->consumed;?>
    workestimation->totalLaborCost;?>block->remain;?>
    diff --git a/module/block/view/waterfallganttblock.html.php b/module/block/view/waterfallganttblock.html.php deleted file mode 100644 index a63f49f165..0000000000 --- a/module/block/view/waterfallganttblock.html.php +++ /dev/null @@ -1,216 +0,0 @@ - - -
    -
    - = 2): ?> - - * block->selectProduct;?> - - -
    programplan->noData;?>
    - -
    -
    -
    -
    -
    programplan->today; ?>
    -
    -
    -
    - -
    - - -
    diff --git a/module/block/view/waterfallissueblock.html.php b/module/block/view/waterfallissueblock.html.php deleted file mode 100644 index 7f4ca97119..0000000000 --- a/module/block/view/waterfallissueblock.html.php +++ /dev/null @@ -1,50 +0,0 @@ - -
    block->emptyTip;?>
    - - -
    - '> - - - - - - - - - - - - - - - - - createLink('issue', 'view', "issueID={$issue->id}"); - ?> - - - - - - - - - - - - - - -
    idAB;?>issue->type;?> issue->title;?>issue->severity;?>issue->pri;?>issue->owner;?>issue->assignedTo;?>issue->status;?>
    id);?>issue->typeList, $issue->type);?>title);?>issue->severityList, $issue->severity, $issue->severity)?>issue->priList, $issue->pri, $issue->pri)?>owner, $issue->owner)?>assignedTo, $issue->assignedTo)?> - issue->statusList, $issue->status);?> -
    -
    - diff --git a/module/block/view/waterfallprogressblock.html.php b/module/block/view/waterfallprogressblock.html.php deleted file mode 100644 index de21679535..0000000000 --- a/module/block/view/waterfallprogressblock.html.php +++ /dev/null @@ -1,125 +0,0 @@ -
    - -
    block->emptyTip;?>
    - - -
    -
    -
    - -
    -
    -
    execution->workHour})";?>
    -
    - PV - EV - AC -
    -
    - - - -
    diff --git a/module/block/view/waterfallreportblock.html.php b/module/block/view/waterfallreportblock.html.php deleted file mode 100644 index ba76bea5e7..0000000000 --- a/module/block/view/waterfallreportblock.html.php +++ /dev/null @@ -1,76 +0,0 @@ - - - - -
    -
    -
    -

    project->weekProgress;?>

    - -
    -
    -
    -
    -
    -
    -
    -
    -
    programplan->end . ')';?>
    -
    -
    -
    -
    programplan->realEnd . ')';?>
    -
    -
    -
    -
    programplan->ac . ')';?>
    -
    -
    -
    -
    programplan->sv . ')';?>
    -
    -
    -
    -
    programplan->cv . ')';?>
    -
    -
    -
    -
    -
    -
    diff --git a/module/block/view/waterfallriskblock.html.php b/module/block/view/waterfallriskblock.html.php deleted file mode 100644 index 5dc881b462..0000000000 --- a/module/block/view/waterfallriskblock.html.php +++ /dev/null @@ -1,58 +0,0 @@ - -
    block->emptyTip;?>
    - - -
    - '> - - - - - - - - - - - - - - - - - - - createLink('risk', 'view', "riskID={$risk->id}"); - ?> - - - - - - - - - - - - - - - - -
    idAB;?>risk->name;?> risk->strategy;?>risk->status;?>risk->rate;?>risk->pri;?>risk->assignedTo;?>risk->category;?>
    id);?>name);?>risk->strategyList, $risk->strategy, $risk->strategy)?> - risk->statusList, $risk->status);?> - rate?>pri}'>" . zget($lang->risk->priList, $risk->pri) . "";?>assignedTo, $risk->assignedTo)?>risk->categoryList, $risk->category, $risk->category)?>
    -
    - diff --git a/module/branch/view/batchedit.html.php b/module/branch/view/batchedit.html.php deleted file mode 100644 index 41c7c61974..0000000000 --- a/module/branch/view/batchedit.html.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @package branch - * @version $Id: batchedit.html.php 4903 2021-11-09 13:14:59Z hfz $ - * @link https://www.zentao.net - */ -?> - - -
    -
    -

    branch->common . '-' . $lang->branch->batchEdit;?>

    -
    -
    - - - - - - - - - - - - - - id == BRANCH_MAIN ? 'disabled' : '';?> - - - - - - - - - - - - - -
    branch->id;?>branch->name, $lang->product->branchName[$product->type]);?>branch->desc, $lang->product->branchName[$product->type]);?>branch->status;?>
    id == BRANCH_MAIN ? '' : $branch->id) . html::hidden("IDList[$branch->id]", $branch->id);?>id]", $branch->name, "class='form-control chosen' $disabled");?>id]", $branch->desc, "class='form-control' $disabled");?>id]", $lang->branch->statusList, $branch->status, "class='form-control' chosen $disabled onchange='canSetDefaultBranch(this)'");?>
    - -
    -
    -
    - diff --git a/module/branch/view/create.html.php b/module/branch/view/create.html.php deleted file mode 100644 index 37fc99a6f7..0000000000 --- a/module/branch/view/create.html.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @package branch - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
    -
    -

    branch->create, $lang->product->branchName[$product->type]);?>

    -
    -
    - - - - - - - - - - - - -
    branch->name, $lang->product->branchName[$product->type]);?>
    branch->desc, $lang->product->branchName[$product->type]);?>
    -
    -
    - diff --git a/module/branch/view/edit.html.php b/module/branch/view/edit.html.php deleted file mode 100644 index 005f59ea7a..0000000000 --- a/module/branch/view/edit.html.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @package branch - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
    -
    -

    branch->edit, $lang->product->branchName[$product->type]);?>

    -
    -
    - - - - - - - - - - - - - - - - -
    branch->name, $lang->product->branchName[$product->type]);?>name, "class='form-control'");?>
    branch->status;?>branch->statusList, $branch->status, "class='form-control chosen'");?>
    branch->desc, $lang->product->branchName[$product->type]);?>desc, "class='form-control'");?>
    -
    -
    - diff --git a/module/branch/view/manage.html.php b/module/branch/view/manage.html.php deleted file mode 100644 index feaf79aeca..0000000000 --- a/module/branch/view/manage.html.php +++ /dev/null @@ -1,188 +0,0 @@ - - * @package branch - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - - -branch);?> - - - - - - - - -
    - -
    -

    - branch->noData;?> - createLink('branch', 'create', "productID=$productID", '', true), " " . $lang->branch->create, '', "class='btn btn-info iframe'");?> -

    -
    - -
    - - - - recTotal&recPerPage=$pager->recPerPage&pageID=$pager->pageID"; ?> - - - - - - - - - - - - - - - - - id == BRANCH_MAIN;?> - - - - - - - - - - - - - - - - -
    -
    -
    branch->order;?>branch->name);?>branch->status);?>branch->createdDate);?>branch->closedDate);?>branch->desc;?>actions;?>
    - id => ''));?> - '> - ';?> - - name;?>  - default) - //{ - // echo '' . $lang->branch->default . ''; - //} - //elseif($branch->status == 'active') - //{ - // $setDefaultLink = helper::createLink('branch', 'setDefault', "productID=$productID&branchID=$branch->id", '', true); - // $setDefaultHtml = html::a($setDefaultLink, " {$lang->branch->setDefault}", 'hiddenwin', "class='btn btn-icon-left btn-sm setDefault hidden'"); - - // echo common::hasPriv('branch', 'setDefault') ? $setDefaultHtml : ''; - //} - ?> - branch->statusList, $branch->status);?>createdDate) ? '' : $branch->createdDate;?>closedDate) ? '' : $branch->closedDate;?>desc;?> - id&productID=$productID", $branch, 'list', '', '', 'iframe', true, '', $lang->branch->edit); - if($branch->status == 'active') - { - common::printIcon('branch', 'close', "branchID=$branch->id", $branch, 'list', 'off', 'hiddenwin'); - } - else - { - common::printIcon('branch', 'activate', "branchID=$branch->id", $branch, 'list', 'active', 'hiddenwin'); - } - } - ?> -
    - -
    - -
    - - - diff --git a/module/bug/config.php b/module/bug/config.php index 034f396f3b..b49aedaba9 100755 --- a/module/bug/config.php +++ b/module/bug/config.php @@ -43,7 +43,7 @@ $config->bug->custom->batchEditFields = 'type,severity,pri,assignedTo,deadline $config->bug->exportFields = 'id, product, branch, module, project, execution, plan, story, task, title, keywords, severity, pri, type, os, browser, - steps, status, deadline, activatedCount, confirmed, mailto, + steps, status, deadline, activatedCount, activatedDate, confirmed, mailto, openedBy, openedDate, openedBuild, assignedTo, assignedDate, resolvedBy, resolution, resolvedBuild, resolvedDate, diff --git a/module/bug/js/common.ui.js b/module/bug/js/common.ui.js index abe83de8fe..f1721c0916 100644 --- a/module/bug/js/common.ui.js +++ b/module/bug/js/common.ui.js @@ -35,7 +35,6 @@ function changeProduct(event) loadProductCases(productID); loadProductStories(productID, bug.storyID); loadProductBugs(productID, bug.id); - if(methodName == 'edit' && edition == 'max') loadIdentify(); } } @@ -74,7 +73,6 @@ function changeProject(event) loadExecutionLabel(projectID); loadExecutions(productID, projectID); loadAssignedTo(productID, projectID); - if(methodName == 'edit' && edition == 'max') loadIdentify(); }); } else @@ -84,7 +82,6 @@ function changeProject(event) loadExecutionLabel(projectID); loadExecutions(productID, projectID); loadAssignedTo(productID, projectID); - if(methodName == 'edit' && edition == 'max') loadIdentify(); } } diff --git a/module/bug/js/view.ui.js b/module/bug/js/view.ui.js index ceaa59855e..9ea902f768 100644 --- a/module/bug/js/view.ui.js +++ b/module/bug/js/view.ui.js @@ -10,7 +10,7 @@ $(document).on('click', '#toStory', function() }); }); -$(document).on('click', '#toTaskButton', function() +window.clickToTask = function() { const projectID = $('[name="taskProjects"]').val(); const executionID = $('[name="execution"]').val() ? $('[name="execution"]').val() : 0; @@ -32,7 +32,7 @@ $(document).on('click', '#toTaskButton', function() { zui.Modal.alert(errorNoExecution); } -}); +}; function changeTaskProjects(event) { diff --git a/module/bug/model.php b/module/bug/model.php index 844b59056d..20bedd541e 100644 --- a/module/bug/model.php +++ b/module/bug/model.php @@ -587,7 +587,6 @@ class bugModel extends model public function activate(object $bug, array $kanbanParams = array()): bool { $oldBug = parent::fetchByID($bug->id); - $bug = $this->loadModel('file')->processImgURL($bug, $this->config->bug->editor->activate['id'], $this->post->uid); $this->dao->update(TABLE_BUG)->data($bug, 'comment')->check('openedBuild', 'notempty')->autoCheck()->checkFlow()->where('id')->eq($bug->id)->exec(); if(dao::isError()) return false; @@ -613,7 +612,7 @@ class bugModel extends model if($changes || $files) { $fileAction = !empty($files) ? $this->lang->addFiles . implode(',', $files) . "\n" : ''; - $actionID = $this->loadModel('action')->create('bug', $bug->id, 'Activated', $fileAction . $this->post->comment); + $actionID = $this->loadModel('action')->create('bug', $bug->id, 'Activated', $fileAction . $bug->comment); $this->action->logHistory($actionID, $changes); } if($this->config->edition != 'open' && $oldBug->feedback) $this->loadModel('feedback')->updateStatus('bug', $oldBug->feedback, $bug->status, $oldBug->status, $oldBug->id); @@ -815,7 +814,7 @@ class bugModel extends model $_SESSION['searchParams']['module'] = 'bug'; $searchConfig = $this->config->bug->search; - $searchConfig['params'] = $this->loadModel('search')->setDefaultParams($searchConfig['fields'], $searchConfig['params']); + $searchConfig['params'] = $this->loadModel('search')->setDefaultParams('bug', $searchConfig['fields'], $searchConfig['params']); return $searchConfig; } diff --git a/module/bug/test/model/buildsearchconfig.php b/module/bug/test/model/buildsearchconfig.php new file mode 100644 index 0000000000..c97896b35c --- /dev/null +++ b/module/bug/test/model/buildsearchconfig.php @@ -0,0 +1,30 @@ +#!/usr/bin/env php +buildSearchConfig(); +cid=1 +- 测试字段名称 + - 属性title @Bug标题 + - 属性module @所属模块 + - 属性steps @重现步骤 +- 测试指派给字段 + - 属性operator @= + - 属性control @select +- 测试严重程度字段 @6 + +*/ + + + +$bug=new bugTest(); +$searchConfig = $bug->objectModel->buildSearchConfig(1, 'story'); + +r($searchConfig['fields']) && p('title,module,steps') && e('Bug标题,所属模块,重现步骤'); // 测试字段名称 +r($searchConfig['params']['assignedTo']) && p('operator,control') && e('=,select'); // 测试指派给字段 +r(count($searchConfig['params']['severity']['values'])) && p('') && e('6'); // 测试严重程度字段 \ No newline at end of file diff --git a/module/bug/ui/batchedit.html.php b/module/bug/ui/batchedit.html.php index 02aec5956b..31243799d8 100644 --- a/module/bug/ui/batchedit.html.php +++ b/module/bug/ui/batchedit.html.php @@ -45,6 +45,8 @@ foreach(explode(',', $config->bug->edit->requiredFields) as $field) } } +$assignedToList = array_merge($users, array('closed' => 'Closed')); + formBatchPanel ( set::title($lang->bug->batchEdit), @@ -184,7 +186,7 @@ formBatchPanel set::name('assignedTo'), set::label($lang->bug->assignedTo), set::control('picker'), - set::items($users), + set::items($assignedToList), set::width('200px'), set::required(isset($requiredFields['assignedTo'])), set::ditto(true), diff --git a/module/bug/ui/create.html.php b/module/bug/ui/create.html.php index d6a0ffc716..b7da026a4a 100644 --- a/module/bug/ui/create.html.php +++ b/module/bug/ui/create.html.php @@ -16,8 +16,7 @@ include($this->app->getModuleRoot() . 'ai/ui/inputinject.html.php'); $fields = useFields('bug.create'); if(!empty($executionType) && $executionType == 'kanban') $fields->merge('bug.kanban'); - -$fields->autoLoad('product', array('items' => 'product,module,execution,project,story,task,assignedTo,' . (!empty($lang->bug->flowExtraFields) ? implode(',', $lang->bug->flowExtraFields) : ''), 'updateOrders' => true)) +$fields->autoLoad('product', array('items' => 'product,module,assignedTo,story,execution,task,openedBuild,project,injection,identify,plan,case,' . (!empty($lang->bug->flowExtraFields) ? implode(',', $lang->bug->flowExtraFields) : ''), 'updateOrders' => true)) ->autoLoad('branch', 'module,execution,project,story,task,assignedTo') ->autoLoad('module', 'assignedTo,story') ->autoLoad('project', 'project,execution,story,task,assignedTo,injection,identify,openedBuild') @@ -42,7 +41,6 @@ jsVar('projectExecutionPairs', $projectExecutionPairs); formGridPanel ( - on::change('[name="product"], [name="branch"], [name="project"], [name="execution"]', 'loadBuilds'), set::title($lang->bug->create), set::fields($fields), set::loadUrl($loadUrl) diff --git a/module/bug/ui/view.html.php b/module/bug/ui/view.html.php index 39e21003cf..0fbb339606 100644 --- a/module/bug/ui/view.html.php +++ b/module/bug/ui/view.html.php @@ -158,7 +158,7 @@ modal div ( setClass('toolbar gap-4 w-full justify-center'), - btn($lang->bug->nextStep, setID('toTaskButton'), setClass('primary')), + btn($lang->bug->nextStep, setID('toTaskButton'), setClass('primary'), setData(array('on' => 'click', 'call' => 'clickToTask'))), btn($lang->cancel, setID('cancelButton'), setData(array('dismiss' => 'modal'))) ) ), diff --git a/module/bug/view/activate.html.php b/module/bug/view/activate.html.php deleted file mode 100644 index 0cf5c3a24f..0000000000 --- a/module/bug/view/activate.html.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @package bug - * @version $Id: activate.html.php 4129 2013-01-18 01:58:14Z wwccss $ - * @link https://www.zentao.net - */ -?> - - -
    -
    -
    -

    - id;?> - title . '">' . $bug->title . '') : html::a($this->createLink('bug', 'view', 'bug=' . $bug->id), $bug->title);?> - - - arrow . $lang->bug->activate;?> - -

    -
    -
    - - - - - - - - - - printExtendFields($bug, 'table');?> - - - - - - - - - - - - - - - -
    bug->assignedTo;?>resolvedBy, "class='form-control chosen'");?>
    bug->status;?>
    bug->openedBuild;?>openedBuild, 'size=4 multiple=multiple class="form-control picker-select"');?>
    comment;?>
    bug->files;?>fetch('file', 'buildform');?>
    goback, $this->session->bugList, 'self', '', 'btn btn-wide');?>
    -
    -
    -
    -
    -
    -product); -js::set('released', $lang->build->released); -?> - diff --git a/module/bug/view/assignto.html.php b/module/bug/view/assignto.html.php deleted file mode 100644 index c595f1ed99..0000000000 --- a/module/bug/view/assignto.html.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @package task - * @version $Id: complete.html.php 935 2010-07-06 07:49:24Z jajacn@126.com $ - * @link https://www.zentao.net - */ -?> -bug->placeholder); -js::set('page', 'assignedto'); -?> -
    -
    -
    -

    - id;?> - title . '">' . $bug->title . '') : html::a($this->createLink('bug', 'view', 'bug=' . $bug->id), $bug->title);?> - - - arrow . $lang->bug->assignBug;?> - -

    -
    -
    - - - - - - - - - - printExtendFields($bug, 'table');?> - - - - - - - - - - - -
    bug->assignBug;?>assignedTo, "class='form-control chosen'");?>
    bug->status;?>status);?>
    bug->mailto;?>mailto), 'class="form-control chosen" multiple');?>
    comment;?>
    goback, $this->server->http_referer, 'self', '', 'btn btn-wide');?>
    -
    -
    -
    -
    -
    - diff --git a/module/bug/view/batchactivate.html.php b/module/bug/view/batchactivate.html.php deleted file mode 100644 index 3ed469881e..0000000000 --- a/module/bug/view/batchactivate.html.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @package bug - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -config->edition != 'open') -{ - $action = $this->loadModel('workflowaction')->getByModuleAndAction('bug', 'batchactivate'); - if($action->js) echo ""; - if($action->css) echo ""; -} -?> - -
    -
    -

    bug->common . $lang->hyphen . $lang->bug->batchActivate;?>

    -
    -
    - - - - - - - - - bug->getFlowExtendFields(); - foreach($extendFields as $extendField) - { - $required = strpos(",$extendField->rules,", ',1,') !== false ? 'required' : ''; - echo ""; - } - ?> - - - - - - - - - - - loadModel('flow'); - foreach($extendFields as $extendField) echo "control == 'select' or $extendField->control == 'multi-select') ? " style='overflow:visible'" : '') . ">" . $this->flow->getFieldControl($extendField, $bug, $extendField->field . "[$bug->id]") . ""; - ?> - - - - - - -
    idAB;?>bug->title;?>bug->assignedTo;?>bug->openedBuild;?>bug->legendComment;?>{$extendField->name}
    id . html::hidden("bugIDList[$bug->id]", $bug->id);?>title . html::hidden("statusList[$bug->id]", $bug->status);?>id]", $users, $bug->resolvedBy, "class='form-control chosen'");?>id]", $builds, $bug->openedBuild, 'size=4 multiple=multiple class="form-control chosen"');?>id]", '', "class='form-control'");?>
    -
    -
    - diff --git a/module/bug/view/batchcreate.html.php b/module/bug/view/batchcreate.html.php deleted file mode 100755 index 5bdbb09daf..0000000000 --- a/module/bug/view/batchcreate.html.php +++ /dev/null @@ -1,324 +0,0 @@ - - * @package story - * @version $Id$ - * @link https://www.zentao.net - */ -?> -bug->create->requiredFields); -js::set('productID', $productID); -js::set('released', $lang->build->released); -?> -bug->create->requiredFields) as $field) -{ - if($field) - { - $requiredFields[$field] = ''; - if(strpos(",{$config->bug->list->customBatchCreateFields},", ",{$field},") !== false) $visibleFields[$field] = ''; - } -} -?> - -
    -
    -

    - bug->batchCreate;?> -

    -
    - createLink('file', 'uploadImages', 'module=bug¶ms=' . helper::safe64Encode("productID=$productID&branch=$branch&executionID=$executionID&moduleID=$moduleID")), $lang->uploadImages, '', "data-toggle='modal' data-type='iframe' class='btn btn-primary' data-width='70%'")?> - - createLink('custom', 'ajaxSaveCustomFields', 'module=bug§ion=custom&key=batchCreateFields')?> - - -
    - - -
    -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - bug->getFlowExtendFields(); - foreach($extendFields as $extendField) - { - $required = strpos(",$extendField->rules,", ',1,') !== false ? 'required' : ''; - echo ""; - } - ?> - - - - - $lang->bug->ditto); - $projects += array('ditto' => $lang->bug->ditto); - $executions += array('ditto' => $lang->bug->ditto); - $lang->bug->typeList += array('ditto' => $lang->bug->ditto); - $lang->bug->priList += array('ditto' => $lang->bug->ditto); - ?> - - - $fileName):?> - - - - - - - - - - - - - - - - - - - - - - loadModel('flow'); - foreach($extendFields as $extendField) echo "control == 'select' or $extendField->control == 'multi-select') ? " style='overflow:visible'" : '') . ">" . $this->flow->getFieldControl($extendField, '', $extendField->field . "[$i]") . ""; - ?> - - - - - - - bug->batchCreate; $i++):?> - - - - - - - - - - - - - - - - - - - - - - loadModel('flow'); - foreach($extendFields as $extendField) echo "control == 'select' or $extendField->control == 'multi-select') ? " style='overflow:visible'" : '') . ">" . $this->flow->getFieldControl($extendField, '', $extendField->field . "[$i]") . ""; - ?> - - - - - - - - - -
    idAB;?> branchBox'> product->branch;?>'> bug->module;?> projectBox'>bug->project;?> executionBox'>model) and $project->model == 'kanban') ? $lang->bug->kanban : $lang->bug->execution;?>bug->openedBuild;?>bug->title;?>kanbancard->region;?>kanbancard->lane;?> deadlineBox'>bug->deadline;?> stepsBox'>bug->steps;?> typeBox'>typeAB;?> priBox'>bug->pri;?> severityBox'>bug->severity;?> osBox'>bug->os;?> browserBox'>bug->browser;?> keywordsBox'>bug->keywords;?>{$extendField->name}actions;?>
    branchBox' style='overflow:visible'> projectBox' style='overflow:visible'> executionBox' style='overflow:visible'> -
    -
    - -
    - - - -
    -
    -
    -
    deadlineBox'> stepsBox'> typeBox' style='overflow:visible'> bug->typeList, $type, "class='form-control chosen'");?> priBox' style='overflow:visible'> bug->priList, $pri, "class='form-control'");?> severityBox' style='overflow:visible'>bug->severityList, '3', "class='form-control'");?> osBox' style='overflow:visible'> bug->osList, '', "class='form-control chosen' multiple");?> browserBox' style='overflow:visible'> bug->browserList, '', "class='form-control chosen' multiple");?> keywordsBox'> - - - - -
    branchBox' style='overflow:visible'> projectBox' style='overflow:visible'> executionBox' style='overflow:visible'> -
    -
    - -
    - - - -
    -
    -
    -
    deadlineBox'> stepsBox'> typeBox' style='overflow:visible'> bug->typeList, $type, "class='form-control chosen'");?> priBox' style='overflow:visible'> bug->priList, $pri, "class='form-control'");?> severityBox' style='overflow:visible'>bug->severityList, '3', "class='form-control'");?> osBox' style='overflow:visible'> bug->osList, '', "class='form-control chosen' multiple");?> browserBox' style='overflow:visible'> bug->browserList, '', "class='form-control chosen' multiple");?> keywordsBox'> - - - - -
    - - -
    -
    -
    -
    - - - - - - - - - - - - - - - - - - - - loadModel('flow'); - foreach($extendFields as $extendField) echo "control == 'select' or $extendField->control == 'multi-select') ? " style='overflow:visible'" : '') . ">" . $this->flow->getFieldControl($extendField, '', $extendField->field . "[%s]") . ""; - ?> - - - -
    %s productBox' style='overflow:visible'> projectBox' style='overflow:visible'> executionBox' style='overflow:visible'> -
    -
    - -
    - - - -
    -
    -
    -
    deadlineBox'> stepsBox'> typeBox' style='overflow:visible'> bug->typeList, $type, "class='form-control chosen'");?> priBox' style='overflow:visible'> bug->priList, $pri, "class='form-control'");?> severityBox' style='overflow:visible'>bug->severityList, '3', "class='form-control'");?> osBox' style='overflow:visible'> bug->osList, '', "class='form-control chosen' multiple");?> browserBox' style='overflow:visible'> bug->browserList, '', "class='form-control chosen' multiple");?> keywordsBox'> - - -
    -
    - - - - - - - - - - - - - - - - - - - - - - - loadModel('flow'); - foreach($extendFields as $extendField) echo "control == 'select' or $extendField->control == 'multi-select') ? " style='overflow:visible'" : '') . ">" . $this->flow->getFieldControl($extendField, '', $extendField->field . "[$i]") . ""; - ?> - - - -
    - - - - - - - diff --git a/module/bug/view/batchedit.html.php b/module/bug/view/batchedit.html.php deleted file mode 100644 index 813a599d1b..0000000000 --- a/module/bug/view/batchedit.html.php +++ /dev/null @@ -1,170 +0,0 @@ - - * @package bug - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -lang->bug->notice->productDitto);?> - -bug->edit->requiredFields);?> -
    -
    -

    bug->common . $lang->hyphen . $lang->bug->batchEdit;?>

    -
    - createLink('custom', 'ajaxSaveCustomFields', 'module=bug§ion=custom&key=batchEditFields')?> - -
    -
    - - -
    - - bug->edit->requiredFields) as $field) - { - if($field) - { - $requiredFields[$field] = ''; - if(strpos(",{$config->bug->list->customBatchEditFields},", ",{$field},") !== false) $visibleFields[$field] = ''; - } - } - $columns = count($visibleFields) + 2; - ?> -
    " id='batchEditForm'> -
    - - - - - - - - - - - - - - - - - - - - - bug->getFlowExtendFields(); - foreach($extendFields as $extendField) echo ""; - ?> - - - - $bug):?> - - - - - - - - - - - - tab == 'project' or $app->tab == 'execution') - { - if($bug->execution) - { - $assignedToList = array('' => '', 'ditto' => $this->lang->bug->ditto) + $executionMembers[$bug->execution]; - } - elseif($bug->project) - { - $assignedToList = array('' => '', 'ditto' => $this->lang->bug->ditto) + $projectMembers[$bug->project]; - } - else - { - $assignedToList = $productMembers[$bug->product][$bug->branch]; - if(empty($assignedToList)) - { - $assignedToList = $users; - unset($assignedToList['closed']); - } - } - } - else - { - $assignedToList = $users; - unset($assignedToList['closed']); - } - ?> - - - - - - - - control == 'select' or $extendField->control == 'multi-select') ? " style='overflow:visible'" : '') . ">" . $this->loadModel('flow')->getFieldControl($extendField, $bug, $extendField->field . "[{$bugID}]") . "";?> - - config->moreLinks["assignedTos[$bugID]"])) unset($this->config->moreLinks["assignedTos[$bugID]"]);?> - - - - - - - -
    idAB;?>'>bug->type;?>'>bug->severity;?>'>bug->pri;?>bug->title;?>bug->branch;?>'> bug->module;?>'>bug->plan;?>'>bug->assignedTo;?>'>bug->deadline;?>'>bug->os;?>'>bug->browser;?>'>bug->keywords;?>'>bug->abbr->resolvedBy;?>'>bug->abbr->resolution;?>{$extendField->name}
    >type, 'class=form-control');?>>severity, 'class=form-control');?>>pri, 'class=form-control');?> -
    -
    - title, "class='form-control' style='color:{$bug->color}'");?> -
    - - - color, "data-provide='colorpicker' data-icon='color' data-wrapper='input-control-icon-right' data-update-color='#titles\\[{$bugID}\\]'");?> -
    -
    -
    -
    - product]->type == 'normal') ? "disabled='disabled'" : '';?> - product], $bug->branch, "class='form-control picker-select' data-drop-width='auto' $disabled onchange='setBranchRelated(this.value, $bug->product, $bug->id)'");?> - product][$bug->branch]) ? $modules[$bug->product][$bug->branch] : array(0 => '/'), $bug->module, "class='form-control picker-select' data-drop-width='auto'");?>' style='overflow:visible'>plans, $bug->plan, "class='form-control picker-select' data-drop-width='auto'");?>' style='overflow:visible'>status == 'closed' ? html::input("assignedTos[$bugID]", ucfirst($bug->assignedTo), 'class=form-control disabled') : html::select("assignedTos[$bugID]", $assignedToList, $bug->assignedTo, "class='form-control picker-select' data-drop-width='135px'");?>' style='overflow:visible'>deadline) ? '' : $bug->deadline, "class='form-control form-date'");?>>bug->osList, $bug->os, 'class="form-control chosen" multiple');?>>bug->browserList, $bug->browser, 'class="form-control chosen" multiple');?>>keywords, 'class=form-control');?>' style='overflow:visible'>resolvedBy, "class='form-control picker-select' data-drop-width='auto'");?>> - - - - - -
    resolution, "class='form-control' onchange=setDuplicate(this.value,$bugID)");?>' resolution != 'duplicate') echo "style='display:none'";?>> - product]) && isset($productBugList[$bug->product][$bug->branch]) ? $productBugList[$bug->product][$bug->branch] : array(); - if(isset($productBugs[$bug->id])) unset($productBugs[$bug->id]); - ?> - duplicate, "class='form-control' placeholder='{$lang->bug->placeholder->duplicate}'");?> -
    -
    - - app->tab == 'product' ? html::a($this->session->bugList, $lang->goback, '', "class='btn btn-back btn-wide'") : html::backButton();?> -
    -
    -
    - -
    - diff --git a/module/bug/view/browse.html.php b/module/bug/view/browse.html.php deleted file mode 100644 index 8fc4968669..0000000000 --- a/module/bug/view/browse.html.php +++ /dev/null @@ -1,457 +0,0 @@ - - * @package bug - * @version $Id: browse.html.php 5102 2013-07-12 00:59:54Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - -session->bugBrowseType == 'bysearch') ? 'all' : $this->session->bugBrowseType); -js::set('flow', $config->global->flow); -js::set('productID', $product->id); -js::set('branch', $branch); -$currentBrowseType = isset($lang->bug->mySelects[$browseType]) && in_array($browseType, array_keys($lang->bug->mySelects)) ? $browseType : ''; -?> - -app->getViewType() == 'xhtml'):?> -
    - name;?> -
    - -
    - -
    -
    - -
    -

    - bug->notice->noBug;?> - - createLink('bug', 'create', "productID={$product->id}&branch=$branch&extra=moduleID=$currentModuleID"), " " . $lang->bug->create, '', "class='btn btn-info'");?> - -

    -
    - - moduleName . ucfirst($this->methodName); - $useDatatable = (isset($config->datatable->$datatableId->mode) and $config->datatable->$datatableId->mode == 'datatable'); - ?> - app->getViewType() == 'xhtml'):?> -
    - - > - -
    - -
    - id}&branch=$branch&browseType=$browseType¶m=$param&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}"; - if($useDatatable) include '../../common/view/datatable.html.php'; - - $setting = $this->loadModel('datatable')->getSetting('bug'); - $widths = $this->datatable->setFixedFieldWidth($setting); - $columns = 0; - - $canBeChanged = common::canModify('product', $product); - $canBatchEdit = ($canBeChanged and common::hasPriv('bug', 'batchEdit')); - $canBatchConfirm = ($canBeChanged and common::hasPriv('bug', 'batchConfirm')); - $canBatchClose = common::hasPriv('bug', 'batchClose'); - $canBatchActivate = ($canBeChanged and common::hasPriv('bug', 'batchActivate')); - $canBatchChangeBranch = ($canBeChanged and common::hasPriv('bug', 'batchChangeBranch')); - $canBatchChangeModule = ($canBeChanged and common::hasPriv('bug', 'batchChangeModule')); - $canBatchResolve = ($canBeChanged and common::hasPriv('bug', 'batchResolve')); - $canBatchAssignTo = ($canBeChanged and common::hasPriv('bug', 'batchAssignTo')); - - $canBatchAction = ($canBatchEdit or $canBatchConfirm or $canBatchClose or $canBatchActivate or $canBatchChangeBranch or $canBatchChangeModule or $canBatchResolve or $canBatchAssignTo); - ?> - ';?> - ' id='bugList' data-fixed-left-width='' data-fixed-right-width=''> - - - app->getViewType() == 'xhtml'):?> - id == 'title' || $value->id == 'id' || $value->id == 'pri' || $value->id == 'status') - { - if($storyType == 'requirement' and (in_array($value->id, array('plan', 'stage')))) $value->show = false; - - $this->datatable->printHead($value, $orderBy, $vars, $canBatchAction); - $columns ++; - } - } - ?> - - show) - { - if(common::checkNotCN() and $value->id == 'severity') $value->name = $lang->bug->severity; - if(common::checkNotCN() and $value->id == 'pri') $value->name = $lang->bug->pri; - if(common::checkNotCN() and $value->id == 'confirmed') $value->name = $lang->bug->confirmed; - $this->datatable->printHead($value, $orderBy, $vars, $canBatchAction); - $columns ++; - } - } - ?> - - - - - - - app->getViewType() == 'xhtml'):?> - id == 'title' || $value->id == 'id' || $value->id == 'pri' || $value->id == 'status') - { - $this->bug->printCell($value, $bug, $users, $builds, $branchOption, $modulePairs, $executions, $plans, $stories, $tasks, $useDatatable ? 'datatable' : 'table'); - } - }?> - - bug->printCell($value, $bug, $users, $builds, $branchOption, $modulePairs, $executions, $plans, $stories, $tasks, $useDatatable ? 'datatable' : 'table', $projectPairs);?> - - - - -
    - ';?> -
    - diff --git a/module/chart/view/preview.html.php b/module/chart/view/preview.html.php deleted file mode 100644 index 024290f25e..0000000000 --- a/module/chart/view/preview.html.php +++ /dev/null @@ -1,122 +0,0 @@ - - * @package chart - * @version $Id$ - * @link https://www.zentao.net - */ -?> -getModuleRoot() . 'common/view/header.html.php';?> - - -id) ? $group->id : 0);?> - -chart->noChartSelected);?> -chart);?> -chart->widthInput);?> -chart->widthDate);?> -bi->pickerHeight);?> -
    ";?> - - - - -
    -
    -
    -
    -
    -
    name) ? $group->name : '';?>
    -
    -
    - -
    -
    - chart->noChart;?> -
    -
    - -
    - -
    - - chart->preview, '', 'btn btn-primary');?> -
    -
    - - config->edition == 'open'):?> -
    - isINT)) ? $lang->bizVersionINT : $lang->bizVersion;?> -
    - -
    -
    -
    -
    -
    -
    - -
    -
    - chart->noChart;?> -
    -
    - -
    -
    - -
    -
    -
    - name;?> - desc)):?> - - -
    -
    -
    -
    -
    - filters)):?> -
    chart->query, "onclick='queryData(this)'", 'btn btn-primary btn-query');?>
    - -
    -
    -
    -
    - - -
    -
    -
    -getModuleRoot() . 'common/view/footer.html.php';?> - - diff --git a/module/common/model.php b/module/common/model.php index 0f39d857db..4837bc872f 100644 --- a/module/common/model.php +++ b/module/common/model.php @@ -2570,23 +2570,25 @@ eof; * @access protected * @return array|bool */ - protected function checkPrivForOperateAction(array $actionData, string $action, string $moduleName, object $data, string $menu): array|bool + public function checkPrivForOperateAction(array $actionData, string $action, string $moduleName, object $data, string $menu): array|bool { $rawModule = $moduleName; if(!empty($actionData['url']) && is_array($actionData['url'])) { - $moduleName = ($actionData['url']['module'] == 'story' && in_array($moduleName, array('epic', 'requirement', 'story'))) ? $data->type : $actionData['url']['module']; - $methodName = $actionData['url']['method']; - $params = $actionData['url']['params']; - if(!common::hasPriv($moduleName, $methodName, $data)) return false; + $moduleName = ($actionData['url']['module'] == 'story' && in_array($moduleName, array('epic', 'requirement', 'story'))) ? $data->type : $actionData['url']['module']; + $methodName = $actionData['url']['method']; + $params = $actionData['url']['params']; + $storySubdivide = in_array($moduleName, array('epic', 'requirement', 'story')) && $action == 'subdivide'; + if(!$storySubdivide && !common::hasPriv($moduleName, $methodName, $data)) return false; $actionData['url'] = helper::createLink($moduleName, $methodName, $params, '', !empty($actionData['url']['onlybody']) ? true : false); } else if(!empty($actionData['data-url']) && is_array($actionData['data-url'])) { - $moduleName = ($actionData['data-url']['module'] == 'story' && in_array($moduleName, array('epic', 'requirement', 'story'))) ? $data->type : $actionData['data-url']['module']; - $methodName = $actionData['data-url']['method']; - $params = $actionData['data-url']['params']; - if(!common::hasPriv($moduleName, $methodName, $data)) return false; + $moduleName = ($actionData['data-url']['module'] == 'story' && in_array($moduleName, array('epic', 'requirement', 'story'))) ? $data->type : $actionData['data-url']['module']; + $methodName = $actionData['data-url']['method']; + $params = $actionData['data-url']['params']; + $storySubdivide = in_array($moduleName, array('epic', 'requirement', 'story')) && $action == 'subdivide'; + if(!$storySubdivide && !common::hasPriv($moduleName, $methodName, $data)) return false; $actionData['data-url'] = helper::createLink($moduleName, $methodName, $params, '', !empty($actionData['data-url']['onlybody']) ? true : false); } elseif(empty($actionData['url'])) diff --git a/module/common/test/lib/common.unittest.class.php b/module/common/test/lib/common.unittest.class.php new file mode 100644 index 0000000000..0049637c70 --- /dev/null +++ b/module/common/test/lib/common.unittest.class.php @@ -0,0 +1,30 @@ +objectModel = $tester->loadModel('common'); + } + + /** + * 检查详情页操作按钮的权限。 + * Check the privilege of the operate action. + * + * @param string $moduleName + * @param object $data + * @param object $menu + * @access protected + * @return array|bool + */ + public function checkPrivForOperateActionTest(string $moduleName, string $action, array $actionData) + { + global $config; + $object = $this->objectModel->dao->select('*')->from($config->objectTables[$moduleName])->where('id')->eq(1)->fetch(); + + $result = $this->objectModel->checkPrivForOperateAction($actionData, $action, $moduleName, $object, 'mainActions'); + return is_array($result) ? !empty($result['url']) : $result; + } +} diff --git a/module/common/test/model/checkprivforoperateaction.php b/module/common/test/model/checkprivforoperateaction.php new file mode 100755 index 0000000000..a4e5cde3f7 --- /dev/null +++ b/module/common/test/model/checkprivforoperateaction.php @@ -0,0 +1,58 @@ +#!/usr/bin/env php +gen(10); +su('admin'); + +/** + +title=测试 commonModel::checkPrivForOperateAction(); +timeout=0 +cid=1 + +- 测试研发需求创建日志按钮权限 @1 +- 测试任务开始按钮权限 @1 +- 测试确认BUG按钮权限 @1 +- 测试执行用例按钮权限 @0 +- 测试没有链接的情况 @0 + +*/ +zenData('task')->gen(1); +zenData('bug')->gen(1); +zenData('case')->gen(1); + +$storyData = zenData('story'); +$storyData->type->range('story,requirement,epic'); +$storyData->gen(3); + +$storyAction = array(); +$storyAction['url'] = array(); +$storyAction['url']['module'] = 'effort'; +$storyAction['url']['method'] = 'createForObject'; +$storyAction['url']['params'] = 'type=story&storyID=1'; + +$taskAction = array(); +$taskAction['url'] = array(); +$taskAction['url']['module'] = 'task'; +$taskAction['url']['method'] = 'start'; +$taskAction['url']['params'] = 'taskID=1'; + +$bugAction = array(); +$bugAction['url'] = array(); +$bugAction['url']['module'] = 'bug'; +$bugAction['url']['method'] = 'confirm'; +$bugAction['url']['params'] = 'bugID=1'; + +$caseAction = array(); +$caseAction['url'] = array(); +$caseAction['url']['module'] = 'testtask'; +$caseAction['url']['method'] = 'runCase'; +$caseAction['url']['params'] = 'runID=0&caseID=1'; + +$commonModel = new commonTest(); +r($commonModel->checkPrivForOperateActionTest('story', 'createeffort', $storyAction)) && p() && e('1'); //测试研发需求创建日志按钮权限 +r($commonModel->checkPrivForOperateActionTest('task', 'start', $taskAction)) && p() && e('1'); //测试任务开始按钮权限 +r($commonModel->checkPrivForOperateActionTest('bug', 'confirm', $bugAction)) && p() && e('1'); //测试确认BUG按钮权限 +r($commonModel->checkPrivForOperateActionTest('testcase', 'runCase', $caseAction)) && p() && e('0'); //测试执行用例按钮权限 +r($commonModel->checkPrivForOperateActionTest('bug', 'create', array())) && p() && e('0'); //测试没有链接的情况 diff --git a/module/company/view/browse.html.php b/module/company/view/browse.html.php deleted file mode 100755 index 3b6b68adb8..0000000000 --- a/module/company/view/browse.html.php +++ /dev/null @@ -1,161 +0,0 @@ - - * @package product - * @version $Id: browse.html.php 5096 2013-07-11 07:02:43Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> -user->confirmDelete); -?> - -
    - -
    -
    -
    ' method='post' id='userListForm'> - - - - - recTotal}&recPerPage={$pager->recPerPage}";?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - -
    - - idAB);?> -
    user->realname);?>user->account);?>user->role);?>user->company);?>user->email);?>user->gender);?>user->phone);?>config->isINT) ? common::printOrderLink('skype', $orderBy, $vars, $lang->user->skype) : common::printOrderLink('qq', $orderBy, $vars, $lang->user->qq);?>user->last);?>user->visits);?>actions;?>
    - - id => '')) . sprintf('%03d', $user->id);?> - - id);?> - - realname;?>account;?>'>user->roleList, $user->role, '');?>'>company, '');?>email);?>user->genderList, $user->gender, $user->gender);?>phone;?>config->isINT) ? $user->skype : ($user->qq ? html::a("tencent://message/?uin=$user->qq", $user->qq) : '');?>last) echo date('Y-m-d', $user->last);?>visits;?> - sso->turnon)) common::printIcon('user', 'unbind', "userID=$user->id", $user, 'list', 'unlink', "hiddenwin"); - common::printIcon('user', 'unlock', "userID=$user->id", $user, 'list', 'unlock', "hiddenwin"); - common::printIcon('user', 'edit', "userID=$user->id&from=company", '', 'list'); - - $deleteClass = (strpos($this->app->company->admins, ",{$user->account},") === false and common::hasPriv('user', 'delete')) ? 'btn iframe' : 'btn disabled'; - echo html::a($this->createLink('user', 'delete', "userID=$user->id"), '', '', "title='{$lang->user->delete}' class='{$deleteClass}'"); - ?> -
    - - - -
    -
    -
    - - diff --git a/module/company/view/dynamic.html.php b/module/company/view/dynamic.html.php deleted file mode 100644 index 2a5f8be1e2..0000000000 --- a/module/company/view/dynamic.html.php +++ /dev/null @@ -1,141 +0,0 @@ -dynamic view file of dashboard module of ZenTaoPMS. - * - * @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com) - * @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html) - * @author Chunsheng Wang - * @package dashboard - * @version $Id: action->dynamic.html.php 1477 2011-03-01 15:25:50Z wwccss $ - * @link https://www.zentao.net - */ -?> - - - - -
    '>
    -
    - -
    -

    - company->empty;?> -

    -
    - -
    - - $actions):?> - -
    -
    - - action->dynamic->today;?> - - - -
    -
      - $action):?> - action == 'adjusttasktowait') continue;?> - - major ? 'active' : '';?> - action, array('releaseddoc', 'collected'))) $class .= " {$action->action}";?> -
    • major) echo "class='$class'";?>> -
      - time?> - - actor);?> - actionLabel;?> - action != 'login' and $action->action != 'logout'):?> - objectLabel;?> - objectID):?> - objectType,") !== false and strpos(',created,edited,moved,', "$action->action") !== false) ? trim($action->extra, ',') : $action->objectID;?> - - - objectType == 'meeting') $tab = $action->project ? "data-app='project'" : "data-app='my'";?> - objectType == 'module' and $config->vision == 'lite') $tab = "data-app='project'";?> - - objectName) and $action->objectID) - { - echo '#' . $action->objectID; - } - elseif(empty($action->objectID) and $action->extra) - { - echo $action->extra; - } - elseif(empty($action->objectLink)) - { - echo $action->objectName; - } - else - { - echo html::a($action->objectLink, $action->objectName, '', $tab); - } - ?> - - - -
      -
    • - -
    -
    - -
    - -
    - -originalDate) + 24 * 3600); -$lastDate = substr($action->originalDate, 0, 10); -$hasPre = $this->action->hasPreOrNext($firstDate, 'pre'); -$hasNext = $this->action->hasPreOrNext($lastDate, 'next'); -$preLink = $hasPre ? inlink('dynamic', "browseType=$browseType¶m=$param&recTotal={$pager->recTotal}&date=" . strtotime($firstDate) . "&direction=pre&userID=$userID&productID=$productID&projectID=$projectID&executionID=$executionID&orderBy=$orderBy") : 'javascript:;'; -$nextLink = $hasNext ? inlink('dynamic', "browseType=$browseType¶m=$param&recTotal={$pager->recTotal}&date=" . strtotime($lastDate) . "&direction=next&userID=$userID&productID=$productID&projectID=$projectID&executionID=$executionID&orderBy=$orderBy") : 'javascript:;'; -?> - -
    - -
    - - - - diff --git a/module/company/view/edit.html.php b/module/company/view/edit.html.php deleted file mode 100644 index 344453c726..0000000000 --- a/module/company/view/edit.html.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @package company - * @version $Id: edit.html.php 4713 2013-05-02 08:04:38Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - -
    -
    -

    - name;?> - - arrow . $lang->company->edit;?> - -

    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    company->name;?>name, "class='form-control'");?>
    company->phone;?>phone, "class='form-control'");?>
    company->fax;?>fax, "class='form-control'");?>
    company->address;?>address, "class='form-control'");?>
    company->zipcode;?>zipcode, "class='form-control'");?>
    company->website;?>website ? $company->website : 'http://', "class='form-control'");?>
    company->backyard;?>backyard ? $company->backyard : 'http://', "class='form-control'");?>
    company->guest;?>company->guestOptions, $company->guest);?>
    -
    -
    - diff --git a/module/company/view/view.html.php b/module/company/view/view.html.php deleted file mode 100644 index 81ec7f4864..0000000000 --- a/module/company/view/view.html.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @package company - * @version $Id: edit.html.php 4488 2013-02-27 02:54:49Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - -
    -
    -

    company->view;?>

    -
    - edit, '', 'id="editCompany" class="btn btn-wide btn-primary iframe" data-width="580"', true, true);?> -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    company->name;?>name;?>
    company->phone;?>phone;?>
    company->fax;?>fax;?>
    company->address;?>address;?>
    company->zipcode;?>zipcode;?>
    company->website;?>website;?>
    company->backyard;?>backyard;?>
    company->guest;?>company->guestOptions[$company->guest];?>
    -
    - diff --git a/module/compile/config/dtable.php b/module/compile/config/dtable.php index 5410dc28ce..2d651a3ead 100644 --- a/module/compile/config/dtable.php +++ b/module/compile/config/dtable.php @@ -60,7 +60,7 @@ $config->compile->actionList = array(); $config->compile->actionList['logs']['icon'] = 'history'; $config->compile->actionList['logs']['text'] = $lang->compile->logs; $config->compile->actionList['logs']['hint'] = $lang->compile->logs; -$config->compile->actionList['logs']['url'] = array('module' => 'compile', 'method' => 'logs', 'params' => 'compileID={id}'); +$config->compile->actionList['logs']['url'] = 'javascript:openPipelineLog({id})'; $config->compile->actionList['result']['icon'] = 'list-alt'; $config->compile->actionList['result']['text'] = $lang->compile->result; diff --git a/module/compile/view/browse.html.php b/module/compile/view/browse.html.php deleted file mode 100644 index 129d1951ff..0000000000 --- a/module/compile/view/browse.html.php +++ /dev/null @@ -1,79 +0,0 @@ - - * @package compile - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - - -
    -

    noData;?>

    -
    - -
    -
    - - - - recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?> - - - - - - - - - - - - $build):?> - - - - - - pipeline) . '@' . $build->jenkinsName;?> - loadModel('job')->getTriggerConfig($build);?> - - compile->statusList, $build->status);?> - - - - - - -
    compile->id);?>compile->name);?>compile->buildType;?>job->repo;?>job->triggerType;?>compile->status);?>compile->time);?>actions;?>
    createLink('job', 'view', "jobID={$build->job}&compileID={$build->id}", 'html', true), $build->name, '', "class='iframe' data-width='90%'") : $build->name;?>engine;?>repoName;?>createdDate;?> - compile->logs); - if($build->testtask) - { - common::printLink('testtask', 'unitCases', "taskID=$build->testtask", $lang->compile->result, '', "class='iframe' data-width='90%'", true, true); - } - ?> -
    - - - -
    -
    - - diff --git a/module/compile/view/logs.html.php b/module/compile/view/logs.html.php deleted file mode 100644 index e303e20508..0000000000 --- a/module/compile/view/logs.html.php +++ /dev/null @@ -1,28 +0,0 @@ - - * @package compile - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -
    -
    -
    - diff --git a/module/convert/view/importjira.html.php b/module/convert/view/importjira.html.php deleted file mode 100644 index ff8abb84be..0000000000 --- a/module/convert/view/importjira.html.php +++ /dev/null @@ -1,66 +0,0 @@ - - * @package article - * @version $Id$ - * @link http://www.chanzhi.org - */ -?> - -
    -
    -

    convert->jira->importJira;?>

    -
    -
    -
    -
      - -
    -
    -
    convert->jira->start, '', "class='btn btn-primary' id='execButton'");?>
    -
    -
    - diff --git a/module/convert/view/index.html.php b/module/convert/view/index.html.php deleted file mode 100644 index 08f9c039bd..0000000000 --- a/module/convert/view/index.html.php +++ /dev/null @@ -1,29 +0,0 @@ - - * @package ZenTaoPMS - * @version $Id: index.html.php 4129 2013-01-18 01:58:14Z wwccss $ - */ -?> - -
    -
    -
    - - convert->common;?> -
    -
    -
    -
    - convert->desc);?> -
    - createLink('convert', 'selectsource'), $lang->convert->start, '', 'class="btn btn-primary"');?> -
    -
    -
    -
    - diff --git a/module/convert/view/initjirauser.html.php b/module/convert/view/initjirauser.html.php deleted file mode 100644 index f8cd7f19c2..0000000000 --- a/module/convert/view/initjirauser.html.php +++ /dev/null @@ -1,50 +0,0 @@ - - * @package user - * @version $Id: create.html.php 4728 2013-05-03 06:14:34Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - -
    -
    -
    -

    convert->jira->initJiraUser;?>

    -
    -
    - - - - - - - - - - - - - - - - - - -
    user->password;?> - - - - - convert->jira->passwordNotice;?>
    user->password2;?>
    user->group;?>convert->jira->groupNotice;?>
    - session->jiraDB}&step=4"), $lang->goback, '', "class='btn btn-wide'");?> - convert->jira->next);?> -
    -
    -
    -
    - diff --git a/module/convert/view/mapjira2zentao.html.php b/module/convert/view/mapjira2zentao.html.php deleted file mode 100644 index 8a6f274b5f..0000000000 --- a/module/convert/view/mapjira2zentao.html.php +++ /dev/null @@ -1,123 +0,0 @@ - - * @package convert - * @version $Id: execute.html.php 4129 2013-01-18 01:58:14Z wwccss $ - */ -?> - - -
    -
    -
    - -
    - - - - - - - - - - $issueType):?> - pname : $issueType['name'];?> - - - - - - - - - - - - - - - - $linkType):?> - linkname : $linkType['linkname'];?> - - - - - - - - - - - - - - - - - $resolution):?> - pname : $resolution['name'];?> - - - - - - - - - - - - - - - - - - - - $status):?> - pname : $status['name'];?> - - - - - - - - - - - - - - - -
    convert->jira->jiraObject;?>convert->jira->zentaoObject;?>
    $value), $id, "class='form-control chosen'");?>convert->jira->zentaoObjectList, '', "class='form-control chosen'");?>
    convert->jira->jiraLinkType;?>convert->jira->zentaoLinkType;?>
    $value), $id, "class='form-control chosen'");?>convert->jira->zentaoLinkTypeList, '', "class='form-control chosen'");?>
    convert->jira->jiraResolution;?>convert->jira->zentaoResolution;?>convert->jira->zentaoReason;?>
    $value), $id, "class='form-control chosen'");?>bug->resolutionList, '', "class='form-control chosen'");?>story->reasonList, '', "class='form-control chosen'");?>
    convert->jira->jiraStatus;?>convert->jira->storyStatus;?>convert->jira->storyStage;?>convert->jira->taskStatus;?>convert->jira->bugStatus;?>
    $value), $id, "class='form-control chosen'");?>story->statusList, '', "class='form-control chosen'");?>story->stageList, '', "class='form-control chosen'");?>task->statusList, '', "class='form-control chosen'");?>bug->statusList, '', "class='form-control chosen'");?>
    - convert->jira->next, "data-placement='bottom'");?> - goback, '', "class='btn btn-wide'"); - } - ?> -
    -
    -
    diff --git a/module/cron/view/create.html.php b/module/cron/view/create.html.php deleted file mode 100644 index 273576b3b0..0000000000 --- a/module/cron/view/create.html.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @package cron - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
    -
    -
    -

    - cron->common?> - arrow . $lang->cron->create?> -

    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    cron->m;?>cron->notice->m;?>
    cron->h;?>cron->notice->h;?>
    cron->dom;?>cron->notice->dom;?>
    cron->mon;?>cron->notice->mon;?>
    cron->dow;?>cron->notice->dow;?>
    cron->command;?>
    cron->remark;?>
    cron->type;?>cron->typeList, 'zentao', "class='form-control'")?>
    -
    -
    -
    - diff --git a/module/cron/view/edit.html.php b/module/cron/view/edit.html.php deleted file mode 100644 index 3547d63980..0000000000 --- a/module/cron/view/edit.html.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @package cron - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
    -
    -
    -

    - cron->common?> - arrow . $lang->cron->edit?> -

    -

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    cron->m;?>m, "class='form-control'")?>cron->notice->m;?>
    cron->h;?>h, "class='form-control'")?>cron->notice->h;?>
    cron->dom;?>dom, "class='form-control'")?>cron->notice->dom;?>
    cron->mon;?>mon, "class='form-control'")?>cron->notice->mon;?>
    cron->dow;?>dow, "class='form-control'")?>cron->notice->dow;?>
    cron->command;?>command), "class='form-control'")?>
    cron->remark;?>remark, "class='form-control'")?>
    cron->type;?>cron->typeList, $cron->type, "class='form-control'")?>
    -
    -
    -
    - diff --git a/module/cron/view/index.html.php b/module/cron/view/index.html.php deleted file mode 100644 index d95e695eb9..0000000000 --- a/module/cron/view/index.html.php +++ /dev/null @@ -1,78 +0,0 @@ - - * @package cron - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -
    - global->cron)):?> -
    -

    cron->list?>

    -
    - global->cron)) echo html::a(inlink('openProcess'), $lang->cron->openProcess, 'hiddenwin', "class='btn'")?> - global->cron)) echo html::a(inlink('turnon'), $lang->cron->turnonList[0], 'hiddenwin', "class='btn'");?> - cron->create, '', "class='btn btn-primary'")?> -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    cron->m?>cron->h?>cron->dom?>cron->mon?>cron->dow?>cron->command?>cron->remark?>cron->lastTime?>cron->status?>actions;?>
    m;?>h;?>dom;?>mon;?>dow;?>command;?>remark;?>lastTime, 2, 17);?>cron->statusList, $cron->status, '');?> - command)) echo html::a(inlink('toggle', "id=$cron->id&status=" . ($cron->status == 'stop' ? 'normal' : 'stop')), $cron->status == 'stop' ? $lang->cron->toggleList['start'] : $lang->cron->toggleList['stop'], 'hiddenwin'); - if(!empty($cron->command) and common::hasPriv('cron', 'edit')) echo html::a(inlink('edit', "id=$cron->id"), $lang->edit); - if($cron->buildin == 0 and common::hasPriv('cron', 'delete')) echo html::a(inlink('delete', "id=$cron->id"), $lang->delete, 'hiddenwin'); - ?> -
    -
    -
    cron->notice->help?>
    - -
    -
    - cron->introduction; - if(common::hasPriv('cron', 'turnon')) printf($lang->cron->confirmOpen, inlink('turnon')); - ?> -
    -
    - -
    - diff --git a/module/custom/view/browsestoryconcept.html.php b/module/custom/view/browsestoryconcept.html.php deleted file mode 100644 index 808f4a3387..0000000000 --- a/module/custom/view/browsestoryconcept.html.php +++ /dev/null @@ -1,89 +0,0 @@ - - * @package ZenTaoPMS - * @version $Id: browsestoryconcept.html.php 4129 2020-09-01 01:58:14Z sgm $ - */ -?> -getModuleRoot() . 'common/view/header.html.php';?> -
    - -
    -
    -
    - custom->product->fields['browsestoryconcept']?> -
    -
    - createLink('custom', 'setstoryconcept', '', '', true), $lang->custom->setStoryConcept, '', "class='btn btn-primary iframe' data-width=" . ($this->config->URAndSR ? "590px" : "405px"));?> -
    -
    - - - - - - - config->URAndSR):?> - - - - - - - - $URSR):?> - - - - - config->URAndSR):?> - - - - - - - -
    custom->default;?> custom->URConcept;?> custom->SRConcept;?> actions;?>
    custom->URSR) echo 'checked';?>> - custom->URSR ? "disabled=disabled" : '';?> - createLink('custom', 'editStoryConcept', "id=$key", '', true), "", '', "class='btn iframe' data-width=" . ($this->config->URAndSR ? "480px" : "330px") . " title={$lang->edit}");?> - createLink('custom', 'deleteStoryConcept', "id=$key"), "", 'hiddenwin', "class='btn' $disabled title={$lang->delete} data-group='admin'");?> -
    -
    -
    - - diff --git a/module/custom/view/code.html.php b/module/custom/view/code.html.php deleted file mode 100644 index 2005f2b72f..0000000000 --- a/module/custom/view/code.html.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @package custom - * @version $Id$ - * @link https://www.zentao.net - */ -?> -getModuleRoot() . 'common/view/header.html.php';?> -
    -
    - - - - - - - - - - - - - - -
    custom->setCode;?> - setCode) ? $config->setCode : 0;?> - custom->conceptOptions->URAndSR as $key => $value):?> - - -
    -
     
    -
    custom->notice->readOnlyOfCode;?>
    -
    - -
    -
    -
    - diff --git a/module/custom/view/editstoryconcept.html.php b/module/custom/view/editstoryconcept.html.php deleted file mode 100644 index 66dc7a7325..0000000000 --- a/module/custom/view/editstoryconcept.html.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @package ZenTaoPMS - * @version $Id: setstoryconcept.html.php 4129 2020-09-01 01:58:14Z sgm $ - */ -?> - -
    -
    - -
    -
    - diff --git a/module/custom/view/execution.html.php b/module/custom/view/execution.html.php deleted file mode 100644 index 6009e9a279..0000000000 --- a/module/custom/view/execution.html.php +++ /dev/null @@ -1,55 +0,0 @@ - - * @package custom - * @version $Id$ - * @link https://www.zentao.net - */ -?> -getModuleRoot() . 'common/view/header.html.php';?> -
    - vision == 'rnd') include 'sidebar.html.php';?> -
    -
    -
    -
    - custom->product->fields['product'];?> -
    -
    - - - - - - - - - - - - - - -
    custom->closedExecution;?> - CRExecution) ? $config->CRExecution : 0;?> - custom->CRExecution as $key => $value):?> - - -
    -  custom->notice->readOnlyOfExecution;?> -
    - -
    -
    -
    -
    - - diff --git a/module/custom/view/flow.html.php b/module/custom/view/flow.html.php deleted file mode 100644 index afc5af4ecd..0000000000 --- a/module/custom/view/flow.html.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @package ZenTaoPMS - * @version $Id: deny.html.php 4129 2013-01-18 01:58:14Z wwccss $ - */ -?> -getModuleRoot() . 'common/view/header.html.php';?> -config->conceptSetted)):?> -
    -
    -
    - custom->flow?> -
    -
    - -
    - -
    - - - diff --git a/module/custom/view/hours.html.php b/module/custom/view/hours.html.php deleted file mode 100644 index 523a6aa55e..0000000000 --- a/module/custom/view/hours.html.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @package custom - * @version $Id$ - * @link https://www.zentao.net - */ -?> -getModuleRoot() . 'common/view/header.html.php';?> -
    - -
    -
    -
    -
    ' id='hoursContent'> -
    -
    - custom->setHours?> -
    -
    - - - - - - -
    custom->workingHours;?>
    -
    -
    ' id='weekendContent'> -
    -
    - custom->setWeekend?> -
    -
    - - - - - - - - - - -
    custom->weekendRole;?>custom->weekendList, $weekend);?>
    -
    -
    - -
    -
    -
    - diff --git a/module/custom/view/kanban.html.php b/module/custom/view/kanban.html.php deleted file mode 100644 index f566c1459e..0000000000 --- a/module/custom/view/kanban.html.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @package custom - * @version $Id$ - * @link https://www.zentao.net - */ -?> -getModuleRoot() . 'common/view/header.html.php';?> -
    -
    -
    -
    - custom->product->fields['product'];?> -
    -
    - - - - - - - - - - - - - - -
    custom->closedKanban;?> - CRKanban) ? $config->CRKanban : 1;?> - custom->CRKanban as $key => $value):?> - - -
    -  custom->notice->readOnlyOfKanban;?> -
    - -
    -
    -
    - - diff --git a/module/custom/view/limittaskdate.html.php b/module/custom/view/limittaskdate.html.php deleted file mode 100644 index e75ef51133..0000000000 --- a/module/custom/view/limittaskdate.html.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @package custom - * @version $Id$ - * @link https://www.zentao.net - */ -?> -getModuleRoot() . 'common/view/header.html.php';?> -
    - -
    -
    -
    -
    - custom->$module->fields['limitTaskDate'];?> -
    -
    - - - - - - - - - -
    custom->beginAndEndDateRange;?> - limitTaskDate) ? $config->limitTaskDate : 0;?> - custom->limitTaskDate as $key => $value):?> - - -
    - -
    -
    -
    -
    - - diff --git a/module/custom/view/mode.html.php b/module/custom/view/mode.html.php deleted file mode 100644 index 44e7014835..0000000000 --- a/module/custom/view/mode.html.php +++ /dev/null @@ -1,100 +0,0 @@ - - * @package custom - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -custom->changeModeTips, $lang->custom->modeList[$mode == 'light' ? 'ALM' : 'light']));?> - - -
    -
    -
    -

    custom->modeManagement;?>

    -
    -
    -

    - - - - - - - - - - - - - - - - - - - - - - - - custom->allFeatures as $feature):?> - - - - - - - - - - - - - - - - -
    lang->custom->mode;?>custom->modeList['light'];?>custom->modeList['ALM'];?>
    custom->usage;?>custom->modeIntroductionList['light'];?>custom->modeIntroductionList['ALM'];?>
    lang->custom->scrum->common, implode($lang->comma, $disabledScrumFeatures)) : $this->lang->custom->features[$feature];?>
    lang->custom->scrum->common, implode($lang->comma, $enabledScrumFeatures)) : $this->lang->custom->features[$feature];?>
    lang->custom->selectUsage;?>> - - custom->useLight, "id='useLight' data-mode='light' $disabled", "btn btn-wide btn-primary");?> - > - - custom->useALM, "id='useALM' data-mode='ALM' $disabled", "btn btn-wide btn-primary");?> - -
    -
    - - -
    -
    - diff --git a/module/custom/view/percent.html.php b/module/custom/view/percent.html.php deleted file mode 100644 index 5d8029f786..0000000000 --- a/module/custom/view/percent.html.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @package custom - * @version $Id$ - * @link https://www.zentao.net - */ -?> -getModuleRoot() . 'common/view/header.html.php';?> -
    -
    - - - - - - - - - - - - - - -
    custom->setPercent;?> - setPercent) ? $config->setPercent : 0;?> - custom->conceptOptions->URAndSR as $key => $value):?> - - -
    -
     
    -
    custom->notice->readOnlyOfPercent;?>
    -
    - -
    -
    -
    - diff --git a/module/custom/view/product.html.php b/module/custom/view/product.html.php deleted file mode 100644 index 123c8924c6..0000000000 --- a/module/custom/view/product.html.php +++ /dev/null @@ -1,55 +0,0 @@ - - * @package custom - * @version $Id$ - * @link https://www.zentao.net - */ -?> -getModuleRoot() . 'common/view/header.html.php';?> -
    - -
    -
    -
    -
    - custom->$module->fields['product'];?> -
    -
    - - - - - - - - - - - - - - -
    custom->closedProduct;?> - CRProduct) ? $config->CRProduct : 0;?> - custom->CRProduct as $key => $value):?> - - -
    -  custom->notice->readOnlyOfProduct;?> -
    - -
    -
    -
    -
    - - diff --git a/module/custom/view/required.html.php b/module/custom/view/required.html.php deleted file mode 100644 index 87c2238f26..0000000000 --- a/module/custom/view/required.html.php +++ /dev/null @@ -1,60 +0,0 @@ - - * @package custom - * @version $Id$ - * @link https://www.zentao.net - */ -?> -getModuleRoot() . 'common/view/header.html.php';?> -
    - vision == 'rnd'))) include 'sidebar.html.php';?> -
    -
    -
    -
    - custom->required;?> -
    -
    - - - $requiredField):?> - - - - - - - - - - - -
    - custom->getFormFields($module, $method); - if(empty($fields)) continue; - if($module == 'caselib' and $method == 'createcase') continue; - - $actionKey = $method . 'Action'; - if(isset($lang->$module->$actionKey)) - { - echo $lang->$module->$actionKey . $lang->custom->page; - } - else - { - echo $lang->$module->$method . $lang->custom->page; - } - ?> - custom->notice->required}'" : ''));?>
    - - custom->restore, 'hiddenwin', "class='btn btn-wide'");?> -
    -
    -
    -
    - diff --git a/module/custom/view/set.html.php b/module/custom/view/set.html.php deleted file mode 100644 index 545f116a6f..0000000000 --- a/module/custom/view/set.html.php +++ /dev/null @@ -1,310 +0,0 @@ - - * @package custom - * @version $Id$ - * @link https://www.zentao.net - */ -?> -getModuleRoot() . 'common/view/header.html.php';?> - - - - - - - - - - - - - -EOT; -?> - - - - -custom->notice->confirmReviewCase)?> - - - - -
    - -
    -
    -
    -
    - custom->$module->fields[$field]?> -
    -
    - - - - - - - - - - - - - - - -
    text-left'>custom->project->currencySetting;?>
    project->unitList, $unitList);?>
    custom->project->defaultCurrency;?>project->unitList, $defaultCurrency, "class='form-control chosen' required");?>
    - - - - - - - - - - - - - - -
    custom->reviewRule;?>custom->reviewRules, $reviewRule);?>
    custom->superReviewers;?>
    - - - - - - - - - getClientLang() != 'zh-cn' and $app->getClientLang() != 'zh-tw') ? ' ': '';?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - > - - - - - > - - - - - - - - -
    custom->storyReview;?>custom->reviewList, $needReview);?>
    custom->notice->forceReview, $lang->$module->common) . $lang->custom->notice->storyReviewTip;?>
    custom->notice->forceNotReview, $lang->$module->common) . $lang->custom->notice->storyReviewTip;?>
    custom->forceReview . $space . $lang->custom->account;?>
    custom->forceReview . $space . $lang->custom->role;?>user->roleList, $forceReviewRoles, "class='form-control picker-select' multiple");?>
    custom->forceReview . $space . $lang->custom->dept;?>
    custom->forceNotReview . $space . $lang->custom->account;?>
    custom->forceNotReview . $space . $lang->custom->role;?>user->roleList, $forceNotReviewRoles, "class='form-control picker-select' multiple");?>
    custom->forceNotReview . $space . $lang->custom->dept;?>
    custom->forceReview;?>custom->notice->forceReview, $lang->$module->common);?>
    custom->forceNotReview;?>custom->notice->forceNotReview, $lang->$module->common);?>
    - - - - - - - -
    custom->bug->fields['longlife'];?> -
    - - day?> -
    -
    -
    custom->notice->longlife;?>
    - - - - - - - - - - - -
    custom->block->fields['closed'];?> - custom->notice->noClosedBlock; - } - else - { - echo html::select('closed[]', $blockPairs, $closedBlock, "class='form-control chosen' multiple"); - } - ?> -
    - - app->loadConfig('user'); - $this->app->loadLang('user'); - ?> - - - - - - - - - -
    custom->user->fields['contactField'];?>user->contactFieldList, $config->user->contactField, "class='form-control picker-select' multiple");?>
    - - custom->restore, inlink('restore', "module=user&field=contactField"), 'hiddenwin', '', 'btn btn-wide');?> -
    - - - - - - - - - - -
    custom->user->fields['deleted'];?>custom->deletedList, $showDeleted);?>
    - - - - - - - - - $value):?> - - system : 1;?> - - - - - - - - - - -
    custom->key;?>custom->value;?>
    - value : $value, "class='form-control' " . (empty($key) ? 'readonly' : ''));?> - - - -
    - $lang->custom->currentLang, 'all' => $lang->custom->allLang); - echo html::radio('lang', $appliedTo, $lang2Set); - echo html::submitButton(); - if(common::hasPriv('custom', 'restore')) echo html::linkButton($lang->custom->restore, inlink('restore', "module=$module&field=$field"), 'hiddenwin', '', 'btn btn-wide'); - ?> -
    - -
    custom->notice->canNotAdd;?>
    - - - -
    -
    -
    - - - - - - - diff --git a/module/custom/view/setstoryconcept.html.php b/module/custom/view/setstoryconcept.html.php deleted file mode 100644 index 747ab354a7..0000000000 --- a/module/custom/view/setstoryconcept.html.php +++ /dev/null @@ -1,85 +0,0 @@ - - * @package ZenTaoPMS - * @version $Id: setstoryconcept.html.php 4129 2020-09-01 01:58:14Z sgm $ - */ -?> -config->URAndSR) -{ - $itemRow = << - - - - - - - -EOT; -} -else -{ - $itemRow = << - - - - - - -EOT; - -} -?> - - -
    -
    - -
    -
    - - diff --git a/module/custom/view/sidebar.html.php b/module/custom/view/sidebar.html.php deleted file mode 100644 index f0f7a2f578..0000000000 --- a/module/custom/view/sidebar.html.php +++ /dev/null @@ -1,36 +0,0 @@ -custom->{$module}->fields)):?> - - diff --git a/module/custom/view/timezone.html.php b/module/custom/view/timezone.html.php deleted file mode 100644 index bff558f203..0000000000 --- a/module/custom/view/timezone.html.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @package custom - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
    -
    - -
    custom->notice->cannotSetTimezone;?>
    - - app->getConfigRoot() . 'timezones.php';?> -
    - - - - - - - - - -
    custom->timezone;?>timezone, "class='form-control chosen'");?>
    -
    - -
    -
    - diff --git a/module/dept/view/browse.html.php b/module/dept/view/browse.html.php deleted file mode 100644 index 04bb289cb6..0000000000 --- a/module/dept/view/browse.html.php +++ /dev/null @@ -1,207 +0,0 @@ - - * @package dept - * @version $Id: browse.html.php 4728 2013-05-03 06:14:34Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - -dept->repeatDepart);?> -
    -
    -
    -
    -
    -
    -
    -
      -
      -
      -
      -
      -
      -
      -
      dept->manageChild;?>
      -
      -
      -
      ' id="dataForm"> - - - - - - - - - - -
      - - createLink('dept', 'browse'), $this->app->company->name); - echo $lang->arrow; - foreach($parentDepts as $dept) - { - echo html::a($this->createLink('dept', 'browse', "deptID=$dept->id"), $dept->name); - echo $lang->arrow; - } - ?> - - - order > $maxOrder) $maxOrder = $sonDept->order; - echo html::input("depts[id$sonDept->id]", $sonDept->name, "class='form-control'"); - } - for($i = 0; $i < $config->dept->newChildCount; $i ++) echo html::input("depts[]", '', "class='form-control'"); - ?> -
      - - createLink('company', 'browse'), $lang->goback, '', "class='btn btn-back btn-wide'");?> - - -
      -
      -
      -
      -
      -
      - - diff --git a/module/dept/view/edit.html.php b/module/dept/view/edit.html.php deleted file mode 100644 index e137798105..0000000000 --- a/module/dept/view/edit.html.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @package dept - * @version $Id: edit.html.php 4795 2013-06-04 05:59:58Z zhujinyonging@gmail.com $ - * @link https://www.zentao.net - */ -?> -app->getWebRoot(); -$jsRoot = $webRoot . "js/"; -if(isset($pageCSS)) css::internal($pageCSS); -?> - - diff --git a/module/design/model.php b/module/design/model.php index dcff4ea4cc..47e53c9fa3 100755 --- a/module/design/model.php +++ b/module/design/model.php @@ -78,6 +78,8 @@ class designModel extends model $designID = $this->dao->lastInsertID(); if($this->config->edition != 'open' && !empty($design->story)) { + if(!isset($stories[$design->story])) continue; + $relation = new stdClass(); $relation->AID = $design->story; $relation->AType = $stories[$design->story]->type; @@ -433,7 +435,7 @@ class designModel extends model ->where($this->session->designQuery) ->andWhere('deleted')->eq('0') ->andWhere('project')->eq($projectID) - ->beginIF($productID)->andWhere('product')->eq($productID)->fi() + ->beginIF($productID)->andWhere('product')->in(is_numeric($productID) ? "0,$productID" : array_merge($productID, array(0)))->fi() ->orderBy($orderBy) ->page($pager) ->fetchAll('id'); diff --git a/module/design/test/model/batchcreate.php b/module/design/test/model/batchcreate.php index a031fa9a64..ed5962acab 100755 --- a/module/design/test/model/batchcreate.php +++ b/module/design/test/model/batchcreate.php @@ -1,8 +1,10 @@ #!/usr/bin/env php batchCreate(); +timeout=0 cid=1 - 批量创建概要设计 @@ -49,4 +51,4 @@ r($designTester->batchCreateTest($dbdsDesgins)) && p('0:name,type') && e r($designTester->batchCreateTest($adsDesgins)) && p('0:name,type') && e('接口设计1,ADS'); // 批量创建接口设计 r($designTester->batchCreateTest($noTypeDesgins)) && p('0') && e('『设计类型』不能为空。'); // 批量创建无类型设计 r($designTester->batchCreateTest($allDesgins)) && p('0:name,type') && e('概要设计3,HLDS'); // 批量创建所有类型设计 -r($designTester->batchCreateTest($storyDesgins)) && p('0:name,type,story') && e('概要设计4,HLDS,1'); // 批量创建需求关联设计 +r($designTester->batchCreateTest($storyDesgins)) && p('0:name,type,story') && e('概要设计4,HLDS,1'); // 批量创建需求关联设计 \ No newline at end of file diff --git a/module/design/ui/view.html.php b/module/design/ui/view.html.php index ebd70fdc0d..11b662c166 100644 --- a/module/design/ui/view.html.php +++ b/module/design/ui/view.html.php @@ -13,6 +13,7 @@ namespace zin; jsVar('type', strtolower($design->type)); detailHeader ( + set::backUrl(createLink('design', 'browse', "projectID={$design->project}")), to::title(entityLabel(set(array('entityID' => $design->id, 'level' => 1, 'text' => $design->name))), $design->deleted ? span(setClass('label danger'), $lang->deleted) : null), ); @@ -93,7 +94,7 @@ detailBody ( set::prefix ( - array(array('icon' => 'back', 'text' => $lang->goback, 'data-back' => 'design-browse,projectstory-track,my-effort,my-index', 'className' => 'open-url')) + array(array('icon' => 'back', 'text' => $lang->goback, 'data-back' => 'design-browse,projectstory-track,my-effort,my-index', 'data-url' => createLink('design', 'browse', "projectID={$design->project}"), 'className' => 'open-url')) ), set::main($operateMenus), set::suffix($commonActions), diff --git a/module/design/view/assignto.html.php b/module/design/view/assignto.html.php deleted file mode 100644 index 669cc7fc07..0000000000 --- a/module/design/view/assignto.html.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @package design - * @version $Id: assignto.html.php 4903 2020-09-02 09:32:59Z tianshujie@easycorp.ltd $ - * @link https://www.zentao.net - */ -?> - - -
      -
      -

      - id;?> - name'>" . $design->name . '';?> -

      -
      -
      - - - - - - - - - - - - - - -
      design->assignedTo;?>assignedTo, "class='form-control chosen'");?>
      comment;?>
      -
      -
      - diff --git a/module/design/view/batchcreate.html.php b/module/design/view/batchcreate.html.php deleted file mode 100644 index f763cc6d8d..0000000000 --- a/module/design/view/batchcreate.html.php +++ /dev/null @@ -1,47 +0,0 @@ - - * @package design - * @version $Id: batchcreate.html.php 4903 2020-09-02 09:32:59Z tianshujie@easycorp.ltd $ - * @link https://www.zentao.net - */ -?> - - -
      -

      design->batchCreate;?>

      -
      - - - - - - - - - - - - - - - - - - - - - - - - -
      design->id;?>design->story;?>design->type;?>design->name;?>design->desc;?>
      - -
      -
      -
      - diff --git a/module/design/view/browse.html.php b/module/design/view/browse.html.php deleted file mode 100644 index 259f8d0b5b..0000000000 --- a/module/design/view/browse.html.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @package design - * @version $Id: browse.html.php 5102 2020-09-03 10:59:54Z tianshujie@easycorp.ltd $ - * @link https://www.zentao.net - */ -?> - - - - - - -
      -
      - -
      -

      design->noDesign;?>

      -
      - -
      - - recTotal}&recPerPage={$pager->recPerPage}";?> - - - - - - - - - - - - - - - - - - - - - - - - - - -
      idAB);?> design->name);?>design->product);?> design->type);?>design->assignedTo);?> design->createdByAB);?> design->createdDate);?> design->actions;?>
      id);?>createLink('design', 'view', "id={$design->id}"), $design->name) : $design->name;?>product);?> type);?> design->printAssignedHtml($design, $users);?> createdBy);?>createdDate, 0, 11);?> - id}"; - common::printIcon('design', 'edit', $vars, $design, 'list', 'alter'); - if(helper::hasFeature('devops')) common::printIcon('design', 'viewCommit', $vars, $design, 'list', 'list-alt', '', 'iframe showinonlybody', true); - common::printIcon('design', 'delete', $vars, $design, 'list', 'trash', 'hiddenwin'); - ?> -
      - -
      - -
      - diff --git a/module/design/view/create.html.php b/module/design/view/create.html.php deleted file mode 100755 index d191160337..0000000000 --- a/module/design/view/create.html.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @package design - * @version $Id: create.html.php 4903 2020-09-02 09:32:59Z tianshujie@easycorp.ltd $ - * @link https://www.zentao.net - */ -?> - - - - -
      -
      -
      -

      design->create;?>

      -
      -
      - - - hasProduct)) echo "class='hide'";?>> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      design->product;?>
      design->story;?>
      design->type;?>
      design->name;?>
      design->desc;?>
      design->file;?>fetch('file', 'buildform', 'fileCount=1&percent=0.85');?>
      -
      -
      -
      - diff --git a/module/design/view/edit.html.php b/module/design/view/edit.html.php deleted file mode 100755 index f0a02b40c5..0000000000 --- a/module/design/view/edit.html.php +++ /dev/null @@ -1,105 +0,0 @@ - - * @package design - * @version $Id: edit.html.php 4903 2020-09-02 09:32:59Z tianshujie@easycorp.ltd $ - * @link https://www.zentao.net - */ -?> - - -type);?> -project);?> -
      -
      -
      -

      - id;?> - createLink('design', 'view', "id=$design->id"), $design->name, '');?> -

      -

      - arrow . ' ' . $lang->design->edit;?> -

      -
      -
      - - - hasProduct)) echo "class='hide'";?>> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      design->product;?>product, "class='form-control chosen'");?>
      design->story;?>story, "class='form-control chosen'");?>
      design->type;?>type, "class='form-control chosen'");?>
      design->name;?>name, "class='form-control'");?>
      design->desc;?>desc, 'class="form-control"');?>
      design->file;?>fetch('file', 'buildform', 'fileCount=1&percent=0.85');?>
      story->checkAffection;?> -
      - -
      -
      - - - - - - - - - - - - - tasks as $task):?> - - - - - - - - - - -
      task->id;?> task->name;?> task->assignedTo;?>task->status;?> task->consumed;?> task->left;?>
      id?>createLink('task', 'view', "taskID=$task->id"), $task->name, '_blank');?>assignedTo);?>processStatus('task', $task);?>consumed;?>left;?>
      -
      -
      -
      -
      -
      -
      -
      - diff --git a/module/design/view/linkcommit.html.php b/module/design/view/linkcommit.html.php deleted file mode 100644 index 2751c4582e..0000000000 --- a/module/design/view/linkcommit.html.php +++ /dev/null @@ -1,91 +0,0 @@ - - * @package design - * @version $Id: linkcommit.html.php 4903 2020-09-02 09:32:59Z tianshujie@easycorp.ltd $ - * @link https://www.zentao.net - */ -?> - -
      -
      -

      - id;?> - name?> - arrow . $lang->design->linkCommit;?> -

      -
      - -
      -

      design->noCommit;?>

      -
      - - -
      method='post'> - - - - - - SCM) and $repo->SCM == 'Git'):?> - - - - - - - - - - - - - SCM == 'Git'):?> - - - - - comment, ENT_QUOTES);?> - - - - -
      repo->revisionA?>repo->commit?>repo->time?>repo->committer?>repo->comment?>
      -
      - - -
      -
      repo->createLink('revision', "repoID=$repoID&objectID={$design->project}&revision={$log->revision}"), $repo->SCM == 'Git' ? substr($log->revision, 0, 10) : $log->revision);?>commit?>time, 0, 10);?>committer, $log->committer);?>comment?>
      - -
      - -
      - - -design->errorDate);?> - diff --git a/module/design/view/view.html.php b/module/design/view/view.html.php deleted file mode 100755 index d9710c2e51..0000000000 --- a/module/design/view/view.html.php +++ /dev/null @@ -1,98 +0,0 @@ - - * @package design - * @version $Id: view.html.php 4903 2020-09-02 09:32:59Z tianshujie@easycorp.ltd $ - * @link https://www.zentao.net - */ -?> - -type);?> - -project);?> - -
      -
      -
      -
      -
      design->desc;?>
      -
      - desc;?> -
      -
      - fetch('file', 'printFiles', array('files' => $design->files, 'fieldset' => 'true'));?> -
      -
      -
      -
      - createLink('design', 'browse', "projectID=$design->project"); - common::printBack($app->session->designList != false ? $app->session->designList : $backLink); - ?> -
      ";?> - deleted):?> - id", $design, 'button', '', '', 'iframe showinonlybody', true); - if(helper::hasFeature('devops')) common::printIcon('design', 'linkCommit', "designID=$design->id", $design, 'button', 'link', '', 'iframe showinonlybody', true, "id='linkCommit'"); - common::printIcon('design', 'edit', "designID=$design->id", $design, 'button', 'alter'); - common::printIcon('design', 'delete', "designID=$design->id", $design, 'button', 'trash', 'hiddenwin'); - ?> - -
      -
      -
      -
      -
      -
      -
      design->basicInfo;?>
      -
      - - - - - - hasProduct)) echo "class='hide'";?>> - - - - - - hasProduct) ? 'projectstory' : 'story';?> - - - - - - - - - - - - - - -
      design->type;?>type);?>
      design->product;?>productName;?>
      design->story;?>story ? html::a($this->createLink($moduleName, 'view', "id=$design->story"), zget($stories, $design->story)) : '';?>
      design->submission;?>commit;?>
      design->createdBy;?>createdBy);?>
      design->createdDate;?>createdDate, 0, 11);?>
      -
      -
      -
      -
      -
      - diff --git a/module/design/view/viewcommit.html.php b/module/design/view/viewcommit.html.php deleted file mode 100644 index a0d10a2251..0000000000 --- a/module/design/view/viewcommit.html.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @package design - * @version $Id: viewcommit.html.php 4903 2020-09-02 09:32:59Z tianshujie@easycorp.ltd $ - * @link https://www.zentao.net - */ -?> - - -project);?> -
      -
      -

      - id;?> - name?> - arrow . $lang->design->submission;?> -

      -
      -
      - id", "" . $lang->design->linkCommit, '', "class='btn btn-primary' id='linkCommit'");?> -
      - commit)):?> -
      -

      design->noCommit;?>

      -
      - - - - - - - - - - - - - commit as $commit):?> - - - - - - - - - -
      design->submission;?>design->commitBy;?>design->commitDate;?>design->comment;?> design->actions;?>
      id"), "#$commit->id", '_blank');?>committer, $commit->committer);?>time, 0, 11);?>comment;?> - id&commitID=$commit->id", $design, 'list', 'unlink', 'hiddenwin', 'iframe showinonlybody', true);?> -
      - - -
      - diff --git a/module/dev/view/api.html.php b/module/dev/view/api.html.php deleted file mode 100644 index 5099cc18d5..0000000000 --- a/module/dev/view/api.html.php +++ /dev/null @@ -1,91 +0,0 @@ - - -
      - -
      - -
      - -
      - -
      - createLink($selectedModule, $methodName, $params, 'json'); - ?> -
      -
      - - - - - - - - - - - - - - - - - - -
      dev->params?>dev->type?>dev->desc?>
      dev->noParams?>
      - dev->postParams[$selectedModule][$methodName])):?> - app->loadLang($selectedModule); - $this->app->loadConfig($selectedModule); - ?> - - - - - - - - dev->postParams[$selectedModule][$methodName] as $paramName => $paramType):?> - - - - $selectedModule->$paramName)) $paramDesc .= $lang->$selectedModule->$paramName . ' '; - if(isset($lang->$selectedModule->$listKey)) $paramDesc .= sprintf($lang->dev->paramRange, join(' | ', array_keys($lang->$selectedModule->$listKey))); - if($paramType == 'date') $paramDesc .= $lang->dev->paramDate; - if($paramName == 'color') $paramDesc .= $lang->dev->paramColor; - if(isset($config->$selectedModule->$methodName->requiredFields) and strpos($config->$selectedModule->$methodName->requiredFields, $paramName) !== false) $paramDesc .= "*{$lang->required}"; - if($paramName == 'product') $paramDesc .= "*{$lang->required}"; - if($paramName == 'mailto') $paramDesc .= $lang->dev->paramMailto; - ?> - - - -
      dev->post;?>
      dev->params?>dev->type?>dev->desc?>
      - -
      -
      - -
      - -
      -
      - diff --git a/module/dev/view/db.html.php b/module/dev/view/db.html.php deleted file mode 100644 index 7a36762adf..0000000000 --- a/module/dev/view/db.html.php +++ /dev/null @@ -1,47 +0,0 @@ - - -
      - -
      - -
      -
      -
      - - - - - - - - - - - - - - $field):?> - - - - - - - - - - -
      dev->fields['id']?>dev->fields['name']?>dev->fields['desc']?>dev->fields['type']?>dev->fields['length']?>dev->fields['null']?>
      -
      -
      - -
      -
      - diff --git a/module/dev/view/editor.html.php b/module/dev/view/editor.html.php deleted file mode 100644 index 9a827b28ec..0000000000 --- a/module/dev/view/editor.html.php +++ /dev/null @@ -1,22 +0,0 @@ - - * @package dev - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
      -
      - dev->noteEditor; - if(common::hasPriv('editor', 'turnon')) echo html::a($this->createLink('editor', 'turnon', 'status=1'), $lang->dev->switchList[1], '', "class='btn btn-primary'"); - ?> -
      -
      - diff --git a/module/dev/view/langitem.html.php b/module/dev/view/langitem.html.php deleted file mode 100644 index a2ee149297..0000000000 --- a/module/dev/view/langitem.html.php +++ /dev/null @@ -1,106 +0,0 @@ - - * @package dev - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -dev->navTypes); ?> - - - -
      - dev->navTypes)):?> - - - -
      -
      -
      - app->getClientLang()) != $language):?> -
      dev->currentLang;?>
      - -
      dev->defaultValue?>
      -
      dev->modifyValue?>
      -
      -
      - app->getClientLang()) == $language;?> - $originalLang):?> - custom->commonLang[$originalLang])) continue; - $itemKey = "{$moduleName}_{$langKey}"; - if(!$isCurrentLang) $currentLangs[$langKey] = strtr($currentLangs[$langKey], $currentCommonLang); - $defaultValue = $this->dev->parseCommonLang($originalLang); - $customedLang = $this->dev->parseCommonLang(zget($customedLangs, $langKey, '')); - $originalLang = strtr($originalLang, $config->custom->commonLang); - ?> -
      - -
      - -
      -
      - - dev->isOriginalLangChanged($defaultValue, $customedLang);?> - - - $subLang):?> - custom->commonLang[$subLang])):?> -
      custom->commonLang[$subLang]?> >custom->commonLang[$subLang] . html::hidden("{$itemKey}[]", $subLang);?>
      - - - - - - - -
      -
      - -
      -
      -
      - - restore, 'hiddenwin', "id='reset' class='btn btn-wide reset-btn'");?> -
      -
      -
      - diff --git a/module/dev/view/restapi.html.php b/module/dev/view/restapi.html.php deleted file mode 100644 index db855c3d82..0000000000 --- a/module/dev/view/restapi.html.php +++ /dev/null @@ -1,149 +0,0 @@ - - * @package doc - * @version $Id$ - * @link https://www.zentao.net - */ -include 'header.html.php'; -js::set('confirmDelete', $lang->api->confirmDelete); -?> -
      - -
      -
      -
      -
      -
      -
      method;?>
      -
      path;?>
      -
      -
      -
      -

      title;?>

      -
      desc;?>
      - params['header']):?> -

      api->header;?>

      - - - - - - - - - - - params['header'] as $param):?> - - - - - - - - -
      api->req->name;?>api->req->type;?>api->req->required;?>api->req->desc;?>
      Stringapi->boolList[$param['required']];?>
      - - params['query']):?> -

      api->query;?>

      - - - - - - - - - - - params['query'] as $param):?> - - - - - - - - -
      api->req->name;?>api->req->type;?>api->req->required;?>api->req->desc;?>
      Stringapi->boolList[$param['required']];?>
      - - '; - $field = ''; - for($i = 0; $i < $level; $i++) $field .= '  '. ($i == $level-1 ? '∟' : ' ') . '  '; - $field .= $data['field']; - $str .= '' . $field . ''; - $str .= '' . zget($typeList, $data['paramsType'], '') . ''; - $str .= '' . zget($lang->api->boolList, $data['required'], '') . ''; - $str .= '' . $data['desc'] . ''; - $str .= ''; - if(isset($data['children']) && count($data['children']) > 0) - { - $level++; - foreach($data['children'] as $item) $str .= parseTree($item, $typeList, $level); - } - return $str; - } - ?> - params['params']):?> -

      api->params;?>

      - - - - - - - - - - params['params'] as $item) echo parseTree($item, $typeList);?> -
      api->req->name;?>api->req->type;?>api->req->required;?>api->req->desc;?>
      - - paramsExample):?> -

      api->paramsExample;?>

      -
      paramsExample;?>
      - - response):?> -

      api->response;?>

      - - - - - - - - - - - response as $item) echo parseTree($item, $typeList);?> - -
      api->req->name;?>api->req->type;?>api->req->required;?>api->req->desc;?>
      - - responseExample):?> -

      api->responseExample;?>

      -
      responseExample;?>
      - -
      -
      -
      -
      -
      - diff --git a/module/doc/control.php b/module/doc/control.php index 11543ac7fa..24991def08 100755 --- a/module/doc/control.php +++ b/module/doc/control.php @@ -226,9 +226,14 @@ class doc extends control if($type == 'productRelease') { - $children = implode(',', array_column($this->view->data, 'releases')); + $releaseList = array(); + foreach($this->view->data as $release) + { + if($release->id == $release->rowID) $releaseList[$release->id] = $release; + } + $children = implode(',', array_column($releaseList, 'releases')); $childReleases = $this->loadModel('release')->getListByCondition(explode(',', $children), 0, true); - $this->view->data = $this->release->processReleaseListData($this->view->data, $childReleases, false); + $this->view->data = $this->release->processReleaseListData($releaseList, $childReleases, false); } $this->display(); @@ -583,14 +588,14 @@ class doc extends control * * @param int $libID * @param string $type - * @param int $docID + * @param mixed $docID * @param string $orderBy * @param int $recPerPage * @param int $pageID * @access public * @return void */ - public function browseTemplate(int $libID = 0, string $type = 'all', int $docID = 0, string $orderBy = 'id_desc', int $recPerPage = 20, int $pageID = 1, string $mode = 'home') + public function browseTemplate(int $libID = 0, string $type = 'all', mixed $docID = 0, string $orderBy = 'id_desc', int $recPerPage = 20, int $pageID = 1, string $mode = 'home') { /* 添加内置的范围、分类、文档模板。*/ /* Add the built-in scopes and type and doc template. */ @@ -613,11 +618,15 @@ class doc extends control $allModules = array_column($allModules, 'fullName', 'id'); foreach($templateList as $template) $template->moduleName = zget($allModules, $template->module); + $docVersion = 0; + if(is_string($docID) && strpos($docID, '_') !== false) list($docID, $docVersion) = explode('_', $docID); + $this->view->title = $this->lang->doc->template; $this->view->libID = $libID; $this->view->users = $this->loadModel('user')->getPairs('noclosed,noletter'); $this->view->templateList = $templateList; $this->view->docID = $docID; + $this->view->docVersion = $docVersion; $this->view->orderBy = $orderBy; $this->view->recPerPage = $recPerPage; $this->view->pageID = $pageID; @@ -1359,6 +1368,8 @@ class doc extends control $isApi = is_string($docID) && strpos($docID, 'api.') === 0; $docID = $isApi ? (int)str_replace('api.', '', $docID) : (int)$docID; $doc = $isApi ? $this->loadModel('api')->getByID($docID, $version) : $this->doc->getByID($docID, $version, true); + $docParam = $version ? ($docID . '_' . $version) : $docID; + if($isApi) $docParam = 'api.' . $docParam; if(!$doc || !isset($doc->id)) { if(defined('RUN_MODE') && RUN_MODE == 'api') return $this->send(array('status' => 'fail', 'code' => 404, 'message' => '404 Not found')); @@ -1378,7 +1389,7 @@ class doc extends control if($doc->templateType) { - echo $this->fetch('doc', 'browseTemplate', "libID=$doc->lib&type=all&docID=$docID&orderBy=id_desc&recPerPage=20&pageID=1&mode=view"); + echo $this->fetch('doc', 'browseTemplate', "libID=$doc->lib&type=all&docID=$docParam&orderBy=id_desc&recPerPage=20&pageID=1&mode=view"); return; } @@ -1398,8 +1409,6 @@ class doc extends control if($docID) $this->doc->createAction($docID, 'view'); $this->view->title = $doc->title; - $docParam = $version ? ($docID . '_' . $version) : $docID; - if($isApi) $docParam = 'api.' . $docParam; $libID = isset($lib->id) ? $lib->id : 0; echo $this->fetch('doc', 'app', "type=$objectType&spaceID=$objectID&libID=$libID&moduleID=$doc->module&docID=$docParam&mode=view"); } @@ -2405,6 +2414,7 @@ class doc extends control if(!empty($doc->rawContent)) { + $doc->html = $doc->content; $doc->content = $doc->rawContent; unset($doc->rawContent); } diff --git a/module/doc/css/quick.ui.css b/module/doc/css/quick.ui.css index 433d635192..447a66aaef 100644 --- a/module/doc/css/quick.ui.css +++ b/module/doc/css/quick.ui.css @@ -1 +1,2 @@ .doc-tree-actions {display: none;} +#mainContent.loading > * {opacity: 0;} diff --git a/module/doc/js/quick.ui.js b/module/doc/js/quick.ui.js index f86f32eab7..c688c08280 100644 --- a/module/doc/js/quick.ui.js +++ b/module/doc/js/quick.ui.js @@ -3,9 +3,10 @@ window.setDocAppOptions = function(_, options) { options = window._setDocAppOptions(_, options); const onSwitchView = options.onSwitchView; - return $.extend(options, + const initLibID = options.libID; + options = $.extend(options, { - docFetcher: {url: options.docFetcher, dataFilter: (data) => $.extend(data, {lib: options.libID})}, + docFetcher: {url: options.docFetcher, dataFilter: (data) => $.extend(data, {lib: initLibID || options.libID})}, viewModeUrl: function(options) { const lib = this.getLib(options.libID); @@ -15,7 +16,7 @@ window.setDocAppOptions = function(_, options) onSwitchView: function(mode, location, info) { onSwitchView.call(this, mode, location, info); - trySwitchView(this, location.libID); + trySwitchView(this, location.libID, mode); }, formatDataItem: function(type, item) { @@ -23,6 +24,8 @@ window.setDocAppOptions = function(_, options) return item; } }); + if(typeof window._currentLibID === 'number') options.libID = window._currentLibID; + return options; }; /** @@ -30,11 +33,14 @@ window.setDocAppOptions = function(_, options) * Try to switch view. * @param {Object} docApp - 文档应用实例。 * @param {number} libID - 库ID。 + * @param {string} mode - 模式。 */ -function trySwitchView(docApp, libID) +function trySwitchView(docApp, libID, mode) { if(window._trySwitchViewTimer) clearTimeout(window._trySwitchViewTimer); + if(libID === window._currentLibID || mode !== 'list') return; + window._currentLibID = libID; window._trySwitchViewTimer = setTimeout(() => { window._trySwitchViewTimer = 0; if(libID === docApp.props.libID) return; @@ -43,8 +49,9 @@ function trySwitchView(docApp, libID) const quickType = lib ? lib.data.quickType : 'view'; const url = $.createLink('doc', 'quick', `type=${quickType}`); docApp.signals.loading.value = true; - loadPartial(url, '#mainContent', {complete: () => - { + $('#mainContent').addClass('loading'); + loadPartial(url, '#mainContent', {complete: () => { + $('#mainContent').removeClass('loading'); docApp.signals.loading.value = false; }}); }, 10); diff --git a/module/doc/model.php b/module/doc/model.php index 5bf3a0f230..259fcd33fa 100644 --- a/module/doc/model.php +++ b/module/doc/model.php @@ -1540,8 +1540,17 @@ class docModel extends model ->batchCheck($this->config->doc->create->requiredFields, 'notempty') ->exec(); if(dao::isError()) return false; - $docID = $this->dao->lastInsertID(); + + /* Update order and path. */ + $path = ",{$docID}"; + if(!empty($doc->parent)) + { + $parentDoc = $this->getByID($doc->parent); + $path = $parentDoc->path . $path; + } + $this->dao->update(TABLE_DOC)->set('`order`')->eq($docID)->set('path')->eq($path)->where('id')->eq($docID)->exec(); + $this->file->updateObjectID($this->post->uid, $docID, 'doc'); $fileTitle = $this->file->saveAFile($file, 'doc', $docID); $docsAction[$docID] = $fileTitle; diff --git a/module/doc/ui/quick.html.php b/module/doc/ui/quick.html.php index c5f7d5e554..6b532a8d7c 100644 --- a/module/doc/ui/quick.html.php +++ b/module/doc/ui/quick.html.php @@ -36,6 +36,7 @@ docApp set::libID($libID), set::docID($docID), set::noSpace(), + set::fetcher(false), set::noModule(), set::spaceType('quick'), set::homeName(false), diff --git a/module/doc/ui/templatelist.html.php b/module/doc/ui/templatelist.html.php index 93cfc714fd..4d34f44052 100644 --- a/module/doc/ui/templatelist.html.php +++ b/module/doc/ui/templatelist.html.php @@ -95,6 +95,7 @@ docApp set::spaceID($spaceID), set::libID($libID), set::docID((int)$docID), + set::docVersion($docVersion), set::docIcon('file-archive'), set::noSpace('hidden'), set::noModule(), diff --git a/module/doc/ui/zentaolist.html.php b/module/doc/ui/zentaolist.html.php index 56caf69ffa..a8a3cfbade 100644 --- a/module/doc/ui/zentaolist.html.php +++ b/module/doc/ui/zentaolist.html.php @@ -102,6 +102,7 @@ div set::localPager(), set::footPager($pagerSetting), set::footer(array('flex', 'pager')), + $type == 'productRelease' ? set::rowKey('rowID') : null, $type == 'productRelease' ? set::plugins(array('cellspan')) : null, $type == 'productRelease' ? set::getCellSpan(jsRaw('window.getCellSpan')) : null ) : null, diff --git a/module/doc/view/create.html.php b/module/doc/view/create.html.php deleted file mode 100644 index 59d1d04e25..0000000000 --- a/module/doc/view/create.html.php +++ /dev/null @@ -1,39 +0,0 @@ - - * @package doc - * @version $Id: create.html.php 975 2010-07-29 03:30:25Z jajacn@126.com $ - * @link https://www.zentao.net - */ -?> -doc->officeTypes, $docType) !== false):?> - -
      -
      -
      -

      doc->create;?>

      -
      - config->edition != 'open'):?> -
      - doc->notSetOffice, zget($lang->doc->typeList, $docType), common::hasPriv('custom', 'libreoffice') ? $this->createLink('custom', 'libreoffice', '', '', true) : '###');?> -
      - -
      doc->cannotCreateOffice, zget($lang->doc->typeList, $docType));?>
      - -
      -
      - - - - - - diff --git a/module/doc/view/createlib.html.php b/module/doc/view/createlib.html.php deleted file mode 100644 index aaf0861f70..0000000000 --- a/module/doc/view/createlib.html.php +++ /dev/null @@ -1,109 +0,0 @@ - - * @package doc - * @version $Id: createlib.html.php 975 2010-07-29 03:30:25Z jajacn@126.com $ - * @link https://www.zentao.net - */ -?> - - - - - - - -
      -
      -
      -
      -
      -

      doc->createLib;?>

      -
      -
      - - - - vision == 'lite') echo 'class="hidden"'?>> - - - - - - - - - tab == 'doc' and $type == 'project'):?> - - - - - - - - - - - - - - - - - - - - - - - - - -
      doc->libType;?> - doclib->type, 'wiki', "onchange='changeDoclibAcl(this.value)'")?> -
      doc->{$type}?>
      doc->execution?> - multiple ? '' : 'disabled';?> - - -
      doclib->name?>
      doclib->control;?> - doclib->aclList, $acl, "onchange='toggleAcl(this.value, \"lib\")'", 'block')?> -
      - - -
      -
      -
      -
      -
      -
      - - diff --git a/module/doc/view/displaysetting.html.php b/module/doc/view/displaysetting.html.php deleted file mode 100644 index a7efbb5d86..0000000000 --- a/module/doc/view/displaysetting.html.php +++ /dev/null @@ -1,32 +0,0 @@ - - * @package doc - * @version $Id: displaysetting.html.php 4769 2023-04-05 14:24:21Z $ - * @link https://www.zentao.net - */ -?> - - - - diff --git a/module/doc/view/doclist.html.php b/module/doc/view/doclist.html.php deleted file mode 100644 index be37afce6f..0000000000 --- a/module/doc/view/doclist.html.php +++ /dev/null @@ -1,152 +0,0 @@ - - * @package doc - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - - - - -
      -

      - doc->noDoc;?> - doc->printCreateBtn($lib, $moduleID, 'list'); - } - ?> -

      -
      - -recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?> -
      -
      - - - - - - - - - - - - - - - collector, ',' . $this->app->user->account . ',') !== false ? 'star' : 'star-empty';?> - collector, ',' . $this->app->user->account . ',') !== false ? $lang->doc->cancelCollection : $lang->doc->collect;?> - - {$type}) ? $doc->{$type} : 0;?> - - - - - - - - - - - -
      - -
      - -
      - - idAB);?> -
      doc->title);?>doc->addedByAB);?>doc->addedDate);?>doc->editedBy);?>doc->editedDate);?>actions;?>
      - -
      - - -
      - - id);?> -
      - doc->iconList, $doc->type); - $icon = html::image("static/svg/{$docType}.svg", "class='file-icon'"); - if(common::hasPriv('doc', 'view')) - { - echo html::a($this->createLink('doc', 'view', "docID=$doc->id"), $icon . $doc->title, '', "title='{$doc->title}' class='doc-title' data-app='{$this->app->tab}'"); - } - else - { - echo "$icon {$doc->title}"; - } - ?> - status == 'draft') echo "{$lang->doc->draft}";?> - - id&objectType=doc");?>" title="" class='btn btn-link ajaxCollect'> - - addedBy);?>addedDate, 'Y-m-d');?>editedBy);?>editedDate, 'Y-m-d');?> - - type != 'text' or isonlybody()) - { - $iframe = 'iframe'; - $onlybody = true; - } - ?> - id&comment=false", "", '', "title='{$lang->edit}' class='btn $iframe'", true, $onlybody);?> - id&confirm=no", "", 'hiddenwin', "title='{$lang->delete}' class='btn'")?> - -
      - - - - -
      - - diff --git a/module/doc/view/edit.html.php b/module/doc/view/edit.html.php deleted file mode 100644 index 2c9b46e45a..0000000000 --- a/module/doc/view/edit.html.php +++ /dev/null @@ -1,17 +0,0 @@ - - * @package doc - * @version $Id: edit.html.php 975 2010-07-29 03:30:25Z jajacn@126.com $ - * @link https://www.zentao.net - */ -?> -type == 'text' and !isonlybody()):?> - - - - diff --git a/module/doc/view/editlib.html.php b/module/doc/view/editlib.html.php deleted file mode 100644 index 763048ba75..0000000000 --- a/module/doc/view/editlib.html.php +++ /dev/null @@ -1,74 +0,0 @@ - - * @package doc - * @version $Id: editlib.html.php 975 2010-07-29 03:30:25Z jajacn@126.com $ - * @link https://www.zentao.net - */ -?> - - -id);?> -type == 'product'):?> - - - - -
      -
      -
      -

      - icons['doclib']);?> - type != 'book' ? $lang->doc->editLib : $lang->doc->editBook;?> -

      -
      - - - type, array('product', 'project', 'execution'))):?> - - - - - - - - - - - - - - - - - - - - -
      doc->{$lib->type};?>name?>
      type != 'book' ? $lang->doc->libName : $lang->doc->bookName;?> - name, "class='form-control'");?> - -
      doclib->control;?> - type != 'api' and empty($lib->main)) echo html::radio('acl', $lang->doclib->aclList, $lib->acl, "onchange='toggleAcl(this.value, \"lib\")'", 'block')?> - type == 'api' and empty($lib->main)) echo html::radio('acl', $lang->api->aclList, $lib->acl, "onchange='toggleAcl(this.value, \"lib\")'", 'block')?> - main)) echo html::radio('acl', $lang->doclib->aclList, 'default', "onchange='toggleAcl(this.value, \"lib\")'", 'block');;?> -
      - -
      -doc->noticeAcl['lib']);?> -type);?> - diff --git a/module/doc/view/lefttree.html.php b/module/doc/view/lefttree.html.php deleted file mode 100644 index cad7c5e488..0000000000 --- a/module/doc/view/lefttree.html.php +++ /dev/null @@ -1,741 +0,0 @@ - - -build->common); -js::set('spaceType', $this->session->spaceType); -js::set('rawModule', $this->app->rawModule); -js::set('rawMethod', $this->app->rawMethod); - -/* ObjectType and objectID used for other space. */ -js::set('objectType', isset($type) ? $type : ''); -js::set('objectID', isset($objectID) ? $objectID : ''); -js::set('isFirstLoad', isset($isFirstLoad) ? $isFirstLoad: ''); -js::set('canViewFiles', common::hasPriv('doc', 'showfiles')); -js::set('spaceMethod', $config->doc->spaceMethod); -js::set('canSortDocCatalog', common::hasPriv('doc', 'sortCatalog')); -js::set('canSortAPICatalog', common::hasPriv('api', 'sortCatalog')); -?> - - -rawMethod == 'view' and common::hasPriv('doc', 'displaySetting')):?> -
      - doc->displaySetting, '', "class='btn btn-info btn-wide iframe' data-width='400px'", true, true);?> -
      - - - - - - - - diff --git a/module/doc/view/mydoclist.html.php b/module/doc/view/mydoclist.html.php deleted file mode 100644 index 8661548f26..0000000000 --- a/module/doc/view/mydoclist.html.php +++ /dev/null @@ -1,204 +0,0 @@ - - * @package doc - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - - - - - -
      -

      - doc->noDoc;?> - doc->printCreateBtn($lib, $moduleID, 'list'); - } - ?> -

      -
      - -recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?> -rawMethod == 'myspace') $vars = "type=$type&" . $vars;?> -
      -
      - - - - - - - - - - - - - - - - - - - - - - - collector, ',' . $this->app->user->account . ',') !== false ? 'star' : 'star-empty';?> - collector, ',' . $this->app->user->account . ',') !== false ? $lang->doc->cancelCollection : $lang->doc->collect;?> - - {$type}) ? $doc->{$type} : 0;?> - - - - - - - - - - - - - - - - - - -
      - -
      - -
      - - idAB);?> -
      doc->title);?>doc->object;?>doc->position);?>doc->addedByAB);?>doc->addedDate);?>doc->editedBy);?>doc->editedDate);?>actions;?>
      - -
      - - -
      - - id);?> -
      - doc->iconList, $doc->type); - $icon = html::image("static/svg/{$docType}.svg", "class='file-icon'"); - if(common::hasPriv('doc', 'view')) - { - echo html::a($this->createLink('doc', 'view', "docID=$doc->id"), $icon . $doc->title, '', "title='{$doc->title}' class='doc-title' data-app='{$this->app->tab}'"); - } - else - { - echo "$icon {$doc->title}"; - } - ?> - status == 'draft') echo "{$lang->doc->draft}";?> - - id&objectType=doc");?>" title="" class='btn btn-link ajaxCollect'> - - - doc->objectIconList, $doc->objectType);?> - " . $doc->objectName;?> - - moduleName ? ' > ' : ''; - $moduleName = $doc->libName . $moduleDivide . $doc->moduleName; - $spaceMethod = zget($config->doc->spaceMethod, $doc->objectType); - $spaceParams = "libID={$doc->lib}&moduleID={$doc->module}"; - if(in_array($doc->objectType, array('product', 'project', 'execution', 'custom'))) $spaceParams = "objectID={$doc->objectID}&$spaceParams"; - if($doc->objectType == 'mine') $spaceParams = "type={$doc->objectType}&$spaceParams"; - - if(common::hasPriv('doc', $spaceMethod)) - { - echo html::a($this->createLink('doc', $spaceMethod, $spaceParams), $moduleName, '', "title='$moduleName' data-app='{$this->app->tab}'"); - } - else - { - echo "$moduleName"; - } - ?> - addedBy);?>addedDate, 'Y-m-d');?>editedBy);?>editedDate, 'Y-m-d');?> - - type != 'text' or isonlybody()) - { - $iframe = 'iframe'; - $onlybody = true; - } - ?> - id&comment=false", "", '', "title='{$lang->edit}' class='btn $iframe'", true, $onlybody);?> - id&confirm=no", "", 'hiddenwin', "title='{$lang->delete}' class='btn'")?> - -
      - - - - -
      - - diff --git a/module/doc/view/myspace.html.php b/module/doc/view/myspace.html.php deleted file mode 100644 index 1067b704a1..0000000000 --- a/module/doc/view/myspace.html.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @package lib - * @version $Id: browse.html.php 958 2010-07-22 08:09:42Z wwccss $ - * @link https://www.zentao.net - */ -?> - - - -doc);?> -doc->confirmDelete)?> -tab)?> - - -
      - -
      -

      - doc->noLib;?> -

      -
      - - - -
      -
      >
      - -
      - -
      - diff --git a/module/doc/view/selectlibtype.html.php b/module/doc/view/selectlibtype.html.php deleted file mode 100644 index 72ebff7bcf..0000000000 --- a/module/doc/view/selectlibtype.html.php +++ /dev/null @@ -1,142 +0,0 @@ - - * @package doc - * @version $Id: selectlibtype.html.php 958 2021-09-3 17:09:42Z liyuchun $ - * @link https://www.zentao.net - */ -?> - -
      -
      -
      -

      ' . $lang->doc->create . '';?>

      -
      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      doc->space?>
      doc->type;?>
      doc->libAndModule?>
      doc->nextStep, 'disabled');?>
      - -
      - - diff --git a/module/doc/view/showfiles.html.php b/module/doc/view/showfiles.html.php deleted file mode 100644 index c370f9bd5d..0000000000 --- a/module/doc/view/showfiles.html.php +++ /dev/null @@ -1,272 +0,0 @@ - - * @package doc - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -doc);?> - - - - -app->tab);?> - - -
      - - -
      - - -
      - - - - app->rawMethod = 'showfiles';?> - recTotal&recPerPage=$pager->recPerPage&pageID=$pager->pageID&searchTitle=$searchTitle";?> - - - - - - - - - - - - - pathname)) continue;?> - - file->getImageSize($file); - $imageWidth = isset($imageSize[0]) ? $imageSize[0] : 0; - ?> - - - - - - - - - - - -
      doc->id);?>doc->fileTitle);?>doc->source);?>doc->extension);?>doc->size);?>doc->addedBy);?>doc->addedDate);?>actions;?>
      id);?>extension, '', $file->title);?>'> - extension, $config->file->imageExtensions)):?> -
      - - id];?> - - extension, '', $file->title);?> -
      - objectType == 'requirement') - { - $commonTitle = $lang->URCommon . ' : '; - } - else - { - if(!isset($lang->{$file->objectType}->common)) $app->loadLang($file->objectType); - $commonTitle = $lang->{$file->objectType}->common . ' : '; - } - echo $commonTitle; - ?> - objectType != 'doc';?> - objectType), 'view', "objectID=$file->objectID", '', $isonlybody);?>' class='' data-width='90%'> - objectType][$file->objectID])) echo $sourcePairs[$file->objectType][$file->objectID];?> - - extension;?>size / 1024, 1) . 'K';?>addedBy) ? zget($users, $file->addedBy) : '';?>addedDate) ? substr($file->addedDate, 0, 10) : '';?>id", '', "", "class='btn' title={$lang->doc->download}", true, false, $file);?>
      -
      - - -
      pager->noRecord;?>
      - - -
      -
      -
      - - pathname)) continue;?> -
      -
      - file->getImageSize($file); - $imageWidth = isset($imageSize[0]) ? $imageSize[0] : 0; - - $fileID = $file->id; - $url = helper::createLink('file', 'download', 'fileID=' . $fileID); - $url .= strpos($url, '?') === false ? '?' : '&'; - $url .= session_name() . '=' . session_id(); - ?> - -
      -
      - -
      - - - -
      pager->noRecord;?>
      - -
      -
      -
      - -
      -
      - - - - - diff --git a/module/doc/view/tablecontents.html.php b/module/doc/view/tablecontents.html.php deleted file mode 100644 index 308c5f5fda..0000000000 --- a/module/doc/view/tablecontents.html.php +++ /dev/null @@ -1,101 +0,0 @@ - - * @package doc - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - - -doc);?> - - -
      - -
      -

      - doc->noLib;?> - ' . $this->lang->doc->createLib, '', 'class="btn btn-info iframe"'); - } - ?> -

      -
      - - - -
      -
      >
      - -
      - -
      - diff --git a/module/doc/view/uploaddocs.html.php b/module/doc/view/uploaddocs.html.php deleted file mode 100644 index 38d51c8323..0000000000 --- a/module/doc/view/uploaddocs.html.php +++ /dev/null @@ -1,106 +0,0 @@ - - * @package doc - * @version $Id: uploaddocs.html.php 975 2023-10-31 13:49:25Z $ - * @link https://www.zentao.net - */ -?> - -app->loadConfig('file');?> -
      -
      -
      -

      doc->uploadDoc;?>

      -
      -
      - - - - - - - app->tab == 'doc'):?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      doc->project;?>doc->execution?>doc->placeholder->execution}' onchange='loadObjectModules(\"execution\", this.value)'")?>
      doc->execution;?>
      doc->product;?>
      doc->libAndModule?>
      doc->uploadFile;?>fetch('file', 'buildform');?>
      doclib->control;?>> - doc->aclList, $objectType == 'mine' ? 'private' : 'open', "onchange='toggleAcl(this.value, \"doc\")'");?> -
      - -
      -
      -
      -
      -doc->textTypes);?> - - -doc->placeholder);?> - -getModuleRoot() . 'common/view/footer.lite.html.php';?> diff --git a/module/doc/view/view.html.php b/module/doc/view/view.html.php deleted file mode 100644 index 1a1fe37e81..0000000000 --- a/module/doc/view/view.html.php +++ /dev/null @@ -1,78 +0,0 @@ - - * @package doc - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - - - - -doc);?> - - -tab == 'execution'):;?> - - - -
      - - deleted)):?> - - - -
      - - - -
      -
      - doc->noDoc;?> -
      -
      - -
      - -
      -
      - doc->noLib;?> - createLink('doc', 'createLib', "type={$objectType}&objectID=$object->id"), " " . $lang->doc->createLib, '', "class='btn btn-info iframe'");?> -
      -
      - -
      - - - diff --git a/module/editor/view/edit.html.php b/module/editor/view/edit.html.php deleted file mode 100644 index f2a55a97ce..0000000000 --- a/module/editor/view/edit.html.php +++ /dev/null @@ -1,165 +0,0 @@ - - * @package editor - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -getModuleRoot() . 'common/view/header.lite.html.php';?> -clientLang); -js::import($jsRoot . 'monaco-editor/min/vs/loader.js'); -?> -
      -
      - - - editor->filePath;?> - - -
      -
      -
      '> - - - - - - - - - - - - - - - - - -
      - " . $lang->editor->sourceFile . ''?>
      -
      -
      -
      - -
      -
      -
      - editor->fileName;?> - - - editor->exampleHook; - } - elseif($action and $action == 'extendOther' and strpos(basename($filePath), '.js') !== false or $action == 'newJS') - { - echo $lang->editor->exampleJs; - } - elseif($action and $action == 'extendOther' and strpos(basename($filePath), '.css') !== false or $action == 'newCSS') - { - echo $lang->editor->exampleCss; - } - else - { - echo $lang->editor->examplePHP; - } - ?> - -
      -
      -
      -
      - - - - -getModuleRoot() . 'common/view/footer.lite.html.php';?> diff --git a/module/editor/view/extend.html.php b/module/editor/view/extend.html.php deleted file mode 100644 index a1e8c45f14..0000000000 --- a/module/editor/view/extend.html.php +++ /dev/null @@ -1,66 +0,0 @@ - - * @package editor - * @version $Id$ - * @link https://www.zentao.net - */ -?> -getModuleRoot() . 'common/view/header.lite.html.php';?> -
      -
      - - editor->modules, $module, isset($lang->{$module}->common) ? $lang->{$module}->common : $module);?> -
      -
      -
      - -
      - - - - diff --git a/module/editor/view/index.html.php b/module/editor/view/index.html.php deleted file mode 100644 index 3ea099efbf..0000000000 --- a/module/editor/view/index.html.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @package editor - * @version $Id$ - * @link https://www.zentao.net - */ -?> -getModuleRoot() . 'dev/view/header.html.php';?> - - - - -
      - -
      -
      - -
      -
      -
      - -
      -
      -getModuleRoot() . 'common/view/footer.html.php';?> diff --git a/module/editor/view/newpage.html.php b/module/editor/view/newpage.html.php deleted file mode 100644 index 930dccfa0f..0000000000 --- a/module/editor/view/newpage.html.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @package editor - * @version $Id$ - * @link https://www.zentao.net - */ -?> -getModuleRoot() . 'common/view/header.lite.html.php';?> -
      -
      editor->newPage?>
      -
      -
      -
      - - - - - - - - - - -
      editor->filePath?>
      editor->pageName?> - editor->examplePHP}'"); - ?> -
      -
      -
      -getModuleRoot() . 'common/view/footer.lite.html.php';?> diff --git a/module/entry/view/browse.html.php b/module/entry/view/browse.html.php deleted file mode 100644 index b9c2408171..0000000000 --- a/module/entry/view/browse.html.php +++ /dev/null @@ -1,66 +0,0 @@ - - * @package entry - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -entry->confirmDelete);?> -
      -
      - - - - recTotal&recPerPage=$pager->recPerPage&pageID=$pager->pageID";?> - - - - - - - - - - - $entry):?> - - - - - - - - - - - -
      entry->id);?>entry->name);?>entry->code);?>entry->key);?>entry->ip);?>entry->desc);?>actions;?>
      name;?>code;?>key;?>ip;?>desc;?> - createLink('entry', 'delete', "entryID=$id&confirm=yes"); - echo html::a("javascript:ajaxDelete(\"$deleteURL\", \"entryList\", confirmDelete)", '', '', "title='{$lang->entry->delete}' class='btn'"); - } - ?> -
      - - - -
      -
      - diff --git a/module/entry/view/create.html.php b/module/entry/view/create.html.php deleted file mode 100644 index b241326384..0000000000 --- a/module/entry/view/create.html.php +++ /dev/null @@ -1,78 +0,0 @@ - - * @package entry - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -
      -
      -
      -

      - entry->common;?> - arrow . ' ' . $lang->entry->create;?> -

      -
      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      entry->name;?>entry->note->name}' placeholder='{$lang->entry->note->name}'");?>
      entry->code;?>entry->note->code}' placeholder='{$lang->entry->note->code}'");?>
      entry->freePasswd;?>entry->freePasswdList, '');?>
      entry->account;?>entry->note->account}'");?>
      entry->key;?>entry->createKey, '', 'onclick="createKey()" tabIndex="-1" class="btn"')?>
      entry->ip;?>entry->note->ip}' placeholder='{$lang->entry->note->ip}'");?> -
      - - -
      -
      entry->desc;?>
      - - entry->helpLink, $lang->entry->help, '_blank', "class='help'");?> - entry->notifyLink, $lang->entry->notify, '_blank', "class='help'");?> -
      -
      -
      -
      - diff --git a/module/entry/view/edit.html.php b/module/entry/view/edit.html.php deleted file mode 100644 index 82311a74c9..0000000000 --- a/module/entry/view/edit.html.php +++ /dev/null @@ -1,75 +0,0 @@ - - * @package entry - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -
      -
      -
      -

      - entry->common;?> - arrow . ' ' . $lang->entry->edit;?> -

      -
      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      entry->name;?>name, "class='form-control' title='{$lang->entry->note->name}' placeholder='{$lang->entry->note->name}'");?>
      entry->code;?>code, "class='form-control' title='{$lang->entry->note->code}' placeholder='{$lang->entry->note->code}'");?>
      entry->freePasswd;?>entry->freePasswdList, $entry->freePasswd);?>
      entry->account;?>account, "class='form-control chosen'");?>
      entry->key;?>key, "class='form-control' readonly='readonly'");?>entry->createKey, '', 'onclick="createKey()" tabIndex="-1" class="btn"')?>
      entry->ip;?>ip, "class='form-control' title='{$lang->entry->note->ip}' placeholder='{$lang->entry->note->ip}'");?> -
      - - -
      -
      entry->desc;?>desc, "rows='3' class='form-control'");?>
      - - entry->helpLink, $lang->entry->help, '_blank', "class='help'");?> - entry->notifyLink, $lang->entry->notify, '_blank', "class='help'");?> -
      -
      -
      -
      - diff --git a/module/entry/view/log.html.php b/module/entry/view/log.html.php deleted file mode 100644 index 54ad9625cb..0000000000 --- a/module/entry/view/log.html.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @package entry - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
      -
      -
      -

      - name;?> - entry->log;?> -
      - " . $lang->entry->setting, '', "class='btn btn-primary iframe'", '', true);?> - -
      -

      -
      -
      - - - - id}&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?> - - - - - - - $log):?> - - - - - - - -
      entry->id);?>entry->date);?>entry->url);?>
      date;?>url;?>
      - - - -
      - diff --git a/module/execution/test/lib/activateinlite.ui.class.php b/module/execution/test/lib/activateinlite.ui.class.php index 2884ce3c37..2f58182916 100644 --- a/module/execution/test/lib/activateinlite.ui.class.php +++ b/module/execution/test/lib/activateinlite.ui.class.php @@ -60,7 +60,8 @@ class activateExecutionTester extends tester */ public function activateWithLessEnd($end, $executionId) { - $this->switchVision('lite', 5); + $currentVision = $this->page->getCookie('vision'); + if(!isset($currentVision) || $currentVision != 'lite') $this->switchVision('lite'); $this->inputFields($end, $executionId); $form = $this->loadPage(); $form->wait(1); diff --git a/module/execution/test/lib/closeinlite.ui.class.php b/module/execution/test/lib/closeinlite.ui.class.php index 2e07cb768e..a283b9e152 100644 --- a/module/execution/test/lib/closeinlite.ui.class.php +++ b/module/execution/test/lib/closeinlite.ui.class.php @@ -58,7 +58,8 @@ class closeExecutionTester extends tester */ public function closeWithGreaterDate($realEnd, $executionId) { - $this->switchVision('lite', 5); + $currentVision = $this->page->getCookie('vision'); + if(!isset($currentVision) || $currentVision != 'lite') $this->switchVision('lite'); $this->inputFields($realEnd, $executionId); $form = $this->loadPage(); $field = $form->dom->realEndField->getText(); diff --git a/module/execution/test/lib/createinlite.ui.class.php b/module/execution/test/lib/createinlite.ui.class.php index cbd20e1dbb..55f9d269bc 100755 --- a/module/execution/test/lib/createinlite.ui.class.php +++ b/module/execution/test/lib/createinlite.ui.class.php @@ -88,7 +88,8 @@ class createExecutionTester extends tester */ public function create($execution, $module = 'execution') { - $this->switchVision('lite', 5); + $currentVision = $this->page->getCookie('vision'); + if(!isset($currentVision) || $currentVision != 'lite') $this->switchVision('lite'); $this->inputFields($execution); /* 创建成功会跳转至看板列表全部标签下,从url中获取status字段内容 */ diff --git a/module/execution/test/lib/editinlite.ui.class.php b/module/execution/test/lib/editinlite.ui.class.php index 31e73869e9..ae76ba68e5 100755 --- a/module/execution/test/lib/editinlite.ui.class.php +++ b/module/execution/test/lib/editinlite.ui.class.php @@ -88,7 +88,8 @@ class editExecutionTester extends tester */ public function edit($execution) { - $this->switchVision('lite', 5); + $currentVision = $this->page->getCookie('vision'); + if(!isset($currentVision) || $currentVision != 'lite') $this->switchVision('lite'); $this->inputFields($execution); if($this->checkFormTips('execution')) return $this->success('编辑看板表单页提示信息正确'); diff --git a/module/execution/test/lib/executionzen.unittest.class.php b/module/execution/test/lib/executionzen.unittest.class.php index f6205dd36a..2738671de0 100644 --- a/module/execution/test/lib/executionzen.unittest.class.php +++ b/module/execution/test/lib/executionzen.unittest.class.php @@ -46,4 +46,17 @@ class executionZenTest if(dao::isError()) return dao::getError(); return $result; } + + /** + * 给详情页面分配变量。 + * Given variables to view page. + * + * @param int $executionID + * @access public + * @return object + */ + public function assignViewVarsTest(int $executionID): object + { + return callZenMethod('execution', 'assignViewVars', [$executionID], 'view'); + } } diff --git a/module/execution/test/lib/grouptaskinlite.ui.class.php b/module/execution/test/lib/grouptaskinlite.ui.class.php index 0b66f775ff..ff440bb7ed 100644 --- a/module/execution/test/lib/grouptaskinlite.ui.class.php +++ b/module/execution/test/lib/grouptaskinlite.ui.class.php @@ -13,7 +13,8 @@ class grouptaskTester extends tester */ public function checkGroupData($groupData, $nums) { - $this->switchVision('lite', 5); + $currentVision = $this->page->getCookie('vision'); + if(!isset($currentVision) || $currentVision != 'lite') $this->switchVision('lite'); $form = $this->initForm('execution', 'grouptask', array('execution' => '2', 'groupBy' => $groupData ), 'appIframe-project'); preg_match_all('/\d+(?:\.\d+)?/', $form->dom->task->getText(), $matches); if($matches[0][0] != $nums['tasks']) return $this->failed('总任务数目错误'); diff --git a/module/execution/test/lib/kanbaninlite.ui.class.php b/module/execution/test/lib/kanbaninlite.ui.class.php index 49241d4c2a..9af9be12f7 100644 --- a/module/execution/test/lib/kanbaninlite.ui.class.php +++ b/module/execution/test/lib/kanbaninlite.ui.class.php @@ -15,7 +15,8 @@ class kanbanTester extends tester */ public function checkKanban($col, $num, $groupId = '', $lane = '1') { - $this->switchVision('lite', 5); + $currentVision = $this->page->getCookie('vision'); + if(!isset($currentVision) || $currentVision != 'lite') $this->switchVision('lite'); $form = $this->initForm('execution', 'kanban', array('kanbanID' => '2'), 'appIframe-project'); $form->wait(1); diff --git a/module/execution/test/lib/putoffinlite.ui.class.php b/module/execution/test/lib/putoffinlite.ui.class.php index 666d8d7dfd..480b1f3330 100644 --- a/module/execution/test/lib/putoffinlite.ui.class.php +++ b/module/execution/test/lib/putoffinlite.ui.class.php @@ -36,7 +36,8 @@ class putoffExecutionTester extends tester */ public function putoff($execution, $executionId) { - $this->switchVision('lite', 5); + $currentVision = $this->page->getCookie('vision'); + if(!isset($currentVision) || $currentVision != 'lite') $this->switchVision('lite'); $this->inputFields($execution, $executionId); $form = $this->loadPage(); $form->wait(1); diff --git a/module/execution/test/lib/startinlite.ui.class.php b/module/execution/test/lib/startinlite.ui.class.php index 62cbd9d7f7..eac5b038ab 100644 --- a/module/execution/test/lib/startinlite.ui.class.php +++ b/module/execution/test/lib/startinlite.ui.class.php @@ -54,7 +54,8 @@ class startExecutionTester extends tester */ public function startWithGreaterDate($realBegan, $kanbanId) { - $this->switchVision('lite', 5); + $currentVision = $this->page->getCookie('vision'); + if(!isset($currentVision) || $currentVision != 'lite') $this->switchVision('lite'); $this->inputFields($realBegan, $kanbanId); $form = $this->loadPage(); $field = $form->dom->realBegan->getValue(); diff --git a/module/execution/test/lib/suspendinlite.ui.class.php b/module/execution/test/lib/suspendinlite.ui.class.php index d2b2e62fd4..b46cacbec2 100644 --- a/module/execution/test/lib/suspendinlite.ui.class.php +++ b/module/execution/test/lib/suspendinlite.ui.class.php @@ -12,7 +12,8 @@ class suspendExecutionTester extends tester */ public function suspend($executionId) { - $this->switchVision('lite', 5); + $currentVision = $this->page->getCookie('vision'); + if(!isset($currentVision) || $currentVision != 'lite') $this->switchVision('lite'); $form = $this->initForm('execution', 'kanban', array('execution' => $executionId ), 'appIframe-project'); $form->wait(1); $form->dom->kanbanSettingInLite->click(); diff --git a/module/execution/test/lib/taskinlite.ui.class.php b/module/execution/test/lib/taskinlite.ui.class.php index 2b624525ce..3f8bed2bf9 100755 --- a/module/execution/test/lib/taskinlite.ui.class.php +++ b/module/execution/test/lib/taskinlite.ui.class.php @@ -13,7 +13,8 @@ class taskExecutionTester extends tester */ public function checkTab($tab, $expectNum) { - $this->switchVision('lite', 5); + $currentVision = $this->page->getCookie('vision'); + if(!isset($currentVision) || $currentVision != 'lite') $this->switchVision('lite'); $form = $this->initForm('execution', 'task', array('execution' => '2'), 'appIframe-project'); $form->wait(1); $params = array('allTab', 'unclosedTab', 'myTab', 'involvedTab', 'assignedByMeTab', 'changedByMeTab'); diff --git a/module/execution/test/lib/treeinlite.ui.class.php b/module/execution/test/lib/treeinlite.ui.class.php index 3b3b92bb0b..689e2543ab 100644 --- a/module/execution/test/lib/treeinlite.ui.class.php +++ b/module/execution/test/lib/treeinlite.ui.class.php @@ -14,7 +14,8 @@ class treeTester extends tester */ public function checkTreeData($level, $num, $click = false) { - $this->switchVision('lite', 5); + $currentVision = $this->page->getCookie('vision'); + if(!isset($currentVision) || $currentVision != 'lite') $this->switchVision('lite'); $form = $this->initForm('execution', 'tree', array('kanbanID' => '2'), 'appIframe-project'); $form->wait(1); if($click) $form->dom->onlyStoryBtn->click(); diff --git a/module/execution/test/zen/assignviewvars.php b/module/execution/test/zen/assignviewvars.php new file mode 100644 index 0000000000..563174fdbd --- /dev/null +++ b/module/execution/test/zen/assignviewvars.php @@ -0,0 +1,34 @@ +#!/usr/bin/env php +loadYaml('execution')->gen(10); +zenData('projectproduct')->loadYaml('projectproduct')->gen(10); +zenData('product')->gen(10); +zenData('branch')->gen(0); +zenData('doc')->gen(0); +zenData('user')->gen(5); +su('admin'); + +$executionTester = new executionZenTest(); +$result = $executionTester->assignViewVarsTest(101); +r($result->products) && p('5:name,type,status') && e('正常产品5,normal,normal'); // 获取产品数据 +r($result->users) && p('admin,user1,user2,user3') && e('admin,用户1,用户2,用户3'); // 获取用户数据 diff --git a/module/execution/ui/task.html.php b/module/execution/ui/task.html.php index 7a81bcbe68..0171b2b227 100644 --- a/module/execution/ui/task.html.php +++ b/module/execution/ui/task.html.php @@ -336,6 +336,7 @@ dtable ))), !$isFromDoc ? null : set::afterRender(jsCallback()->call('toggleCheckRows', $idList)), !$isFromDoc ? null : set::onCheckChange(jsRaw('window.checkedChange')), + !$isFromDoc ? null : set::noNestedCheck(true), !$isFromDoc ? null : set::height(400), $isFromDoc ? null : set::customCols(true), $isFromDoc ? null : set::sortLink(createLink('execution', 'task', "executionID={$execution->id}&status={$status}¶m={$param}&orderBy={name}_{sortType}&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}")), diff --git a/module/execution/view/activate.html.php b/module/execution/view/activate.html.php deleted file mode 100644 index 994bbf8b6f..0000000000 --- a/module/execution/view/activate.html.php +++ /dev/null @@ -1,80 +0,0 @@ - - * @package execution - * @version $Id: suspend.html.php 935 2013-01-16 07:49:24Z wwccss@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - - -
      -
      -

      - id;?> - name'>" . $execution->name . '') : html::a($this->createLink('execution', 'view', 'execution=' . $execution->id), $execution->name, '_blank');?> - - arrow . $lang->execution->activate;?> - -

      -
      -
      - - - - - - - - - - - printExtendFields($execution, 'table', 'columns=5');?> - - - - - - - -
      execution->beginAndEnd;?> -
      begin . ' ~ ' . $execution->end;?>
      -
      -
      - - ~ - -
      -
      -
      -
      -
      -
      -
      -
      - -
      -
      -
      execution->status;?>
      comment;?>
      execution->activate . $lang->executionCommon) . html::linkButton($lang->goback, $this->session->taskList, 'self', '', 'btn btn-wide'); ?>
      -
      -
      -
      -
      - - diff --git a/module/execution/view/all.html.php b/module/execution/view/all.html.php deleted file mode 100644 index a73823c2ac..0000000000 --- a/module/execution/view/all.html.php +++ /dev/null @@ -1,199 +0,0 @@ - - * @package execution - * @version $Id: index.html.php 5094 2013-07-10 08:46:15Z chencongzhi520@gmail.com $ - */ -?> - - -execution->generateCol($orderBy); -$executions = $this->execution->generateRow($executionStats, $users, $productID); - -$sortLink = $this->createLink('execution', 'all', "status=$status&orderBy={orderBy}&productID=$productID¶m=$param&recTotal=$pager->recTotal&recPerPage=$pager->recPerPage&pageID=$pager->pageID"); - -js::set('sortLink', $sortLink); -js::set('cols', json_encode($cols)); -js::set('data', json_encode($executions)); - -js::set('orderBy', $orderBy); -js::set('status', $status); -js::set('from', $from); - -js::set('isCNLang', !$this->loadModel('common')->checkNotCN()); -?> - - - - - -
      -
      - -
      -

      - execution->noExecutions : $lang->execution->noExecution;?> - - - createLink('execution', 'create'), " " . ($from == 'execution' ? $lang->execution->createExec : $lang->execution->create), '', "class='btn btn-info' data-app='execution'");?> - - -

      -
      - -
      -
      - -
      -
      - -
      - - -
      - diff --git a/module/execution/view/batchedit.html.php b/module/execution/view/batchedit.html.php deleted file mode 100755 index 14e9c1291d..0000000000 --- a/module/execution/view/batchedit.html.php +++ /dev/null @@ -1,150 +0,0 @@ - - * @package ZenTaoPMS - * @version $Id: index.html.php 4129 2013-01-18 01:58:14Z wwccss $ - */ -?> - - -
      -
      -

      execution->batchEdit;?>

      -
      - createLink('custom', 'ajaxSaveCustomFields', 'module=execution§ion=custom&key=batchEditFields')?> - -
      -
      - execution->edit->requiredFields) as $field) - { - if($field) - { - $requiredFields[$field] = ''; - if(strpos(",{$config->execution->customBatchEditFields},", ",{$field},") !== false) $visibleFields[$field] = ''; - } - } - $maxCount = strpos($this->app->getClientLang(), 'zh-') !== false ? 5 : 3; - $minWidth = (count($visibleFields) > $maxCount) ? 'w-150px' : ''; - $name = $from == 'execution' ? 'execName' : 'name'; - $code = $from == 'execution' ? 'execCode' : 'code'; - $PM = $from == 'execution' ? 'execPM' : 'PM'; - $type = $from == 'execution' ? 'execType' : 'type'; - $desc = $from == 'execution' ? 'execDesc' : 'desc'; - ?> -
      '> -
      - - - - - model == 'scrum'):?> - - - tab == 'project' and isset($project) and ($project->model == 'agileplus' or $project->model == 'waterfallplus')):?> - - - - setCode) and $config->setCode == 1):?> - - - - - - - - - - - - - execution->getFlowExtendFields(); - foreach($extendFields as $extendField) echo ""; - ?> - - - - $execution):?> - config->moreLinks["PM"])) $this->config->moreLinks["PMs[$executionID]"] = $this->config->moreLinks["PM"]; - if(!empty($this->config->moreLinks["PO"])) $this->config->moreLinks["POs[$executionID]"] = $this->config->moreLinks["PO"]; - if(!empty($this->config->moreLinks["QD"])) $this->config->moreLinks["QDs[$executionID]"] = $this->config->moreLinks["QD"]; - if(!empty($this->config->moreLinks["RD"])) $this->config->moreLinks["RDs[$executionID]"] = $this->config->moreLinks["RD"]; - ?> - - - model == 'scrum'):?> - - - tab == 'project' and isset($project) and ($project->model == 'agileplus' or $project->model == 'waterfallplus')):?> - - - - setCode) and $config->setCode == 1):?> - - - - - - - - - - - - - control == 'select' or $extendField->control == 'multi-select') ? " style='overflow:visible'" : '') . ">" . $this->loadModel('flow')->getFieldControl($extendField, $executions[$executionID], $extendField->field . "[{$executionID}]") . "";?> - - config->moreLinks["PMs[$executionID]"])) unset($this->config->moreLinks["PMs[$executionID]"]); - if(isset($this->config->moreLinks["POs[$executionID]"])) unset($this->config->moreLinks["POs[$executionID]"]); - if(isset($this->config->moreLinks["QDs[$executionID]"])) unset($this->config->moreLinks["QDs[$executionID]"]); - if(isset($this->config->moreLinks["RDs[$executionID]"])) unset($this->config->moreLinks["RDs[$executionID]"]); - ?> - - - - - - - -
      idAB;?>execution->projectName;?>execution->method;?>execution->$name;?>execution->$code;?>'>execution->$PM;?>'>execution->PO;?>'>execution->QD;?>'>execution->RD;?>'> - execution->$type;?> - app->tab == 'execution' or (isset($project) and ($project->model == 'waterfall' or $project->model == 'waterfallplus'))):?> - app->tab == 'execution' ? $lang->execution->waterfallTip . lcfirst($lang->execution->typeTip) : $lang->execution->typeTip;?> - - - execution->begin;?>execution->end;?>'>execution->$desc;?>'>execution->teamName;?>'>execution->days;?>{$extendField->name}
      project, "class='form-control picker-select' data-lastselected='{$executions[$executionID]->project}' onchange='changeProject(this, $executionID, {$executions[$executionID]->project})'");?>execution->typeList, $executions[$executionID]->type);?>name, "class='form-control' id='names{$executionID}'");?>code, "id='codes{$executionID}' class='form-control'");?>' style='overflow:visible'>PM, "class='form-control picker-select'");?>' style='overflow:visible'>PO, "class='form-control picker-select'");?>' style='overflow:visible'>QD, "class='form-control picker-select'");?>' style='overflow:visible'>RD, "class='form-control picker-select'");?>'> - project]) and ($projects[$execution->project]->model == 'waterfall' or $projects[$execution->project]->model == 'waterfallplus')):?> - stage->typeList, $executions[$executionID]->attribute, 'class=form-control');?> - - execution->lifeTimeList, $executions[$executionID]->lifetime, 'class=form-control');?> - - begin, "id='begins{$executionID}' class='form-control form-date' onchange='computeWorkDays(this.id)'");?>end, "id='ends{$executionID}' class='form-control form-date' onchange='computeWorkDays(this.id)'");?>'>desc, "rows='1' class='form-control autosize'");?>'>team, "class='form-control'");?>'> -
      - days, "id='dayses{$executionID}' class='form-control'");?> - execution->day;?> -
      -
      - - goback, $this->session->executionList, 'self', '', 'btn btn-wide');;?> -
      -
      -
      -
      -execution->weekend); -js::set('confirmSync', $lang->execution->confirmSync); -?> - diff --git a/module/execution/view/bug.html.php b/module/execution/view/bug.html.php deleted file mode 100644 index 617ae3467c..0000000000 --- a/module/execution/view/bug.html.php +++ /dev/null @@ -1,221 +0,0 @@ - - * @package execution - * @version $Id: bug.html.php 4894 2013-06-25 01:28:39Z wyd621@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - - -app->getViewType() == 'xhtml'):?> -
      - - project->getById($execution->project)->name . ' / ' . $this->execution->getByID($execution->id)->name) ?> - -
      - -
      - -
      -
      - -
      -

      - bug->notice->noBug;?> - - createLink('bug', 'create', "productID=$defaultProduct&branch=0&extra=executionID=$execution->id"), " " . $lang->bug->create, '', "class='btn btn-info' data-app='execution'");?> - -

      -
      - - moduleName . ucfirst($this->methodName); - $useDatatable = (isset($config->datatable->$datatableId->mode) and $config->datatable->$datatableId->mode == 'datatable'); - ?> - app->getViewType() == 'xhtml'):?> -
      - - > - -
      - -
      - id}&productID={$productID}&branch={$branchID}&orderBy=%s&build=$buildID&type=$type¶m=$param&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}"; - - $useDatatable ? include '../../common/view/datatable.html.php' : include '../../common/view/tablesorter.html.php'; - - $setting = $this->datatable->getSetting('execution'); - $widths = $this->datatable->setFixedFieldWidth($setting); - $columns = 0; - - $canBatchAssignTo = common::hasPriv('bug', 'batchAssignTo'); - ?> - ';?> - ' id='bugList' data-fixed-left-width='' data-fixed-right-width=''> - - - app->getViewType() == 'xhtml'):?> - id == 'title' || $value->id == 'id' || $value->id == 'pri' || $value->id == 'status') - { - $this->datatable->printHead($value, $orderBy, $vars, $canBatchAssignTo); - $columns ++; - } - } - ?> - - hasProduct and $project->model != 'scrum' and $value->id == 'plan') continue; - if(!$project->hasProduct and $value->id == 'branch') continue; - if($value->show) - { - if(common::checkNotCN() and $value->id == 'severity') $value->name = $lang->bug->severity; - if(common::checkNotCN() and $value->id == 'pri') $value->name = $lang->bug->pri; - if(common::checkNotCN() and $value->id == 'confirmed') $value->name = $lang->bug->confirmed; - $this->datatable->printHead($value, $orderBy, $vars, $canBatchAssignTo); - $columns ++; - } - } - ?> - - - - - - - app->getViewType() == 'xhtml'):?> - id == 'title' || $value->id == 'id' || $value->id == 'pri' || $value->id == 'status') - { - $this->bug->printCell($value, $bug, $users, $builds, $branchOption, $modulePairs, array($execution), $plans, $stories, $tasks, $useDatatable ? 'datatable' : 'table'); - } - }?> - - hasProduct and $project->model != 'scrum' and $value->id == 'plan') continue; - if(!$project->hasProduct and $value->id == 'branch') continue; - $this->bug->printCell($value, $bug, $users, $builds, $branchOption, $modulePairs, $executions, $plans, $stories, $tasks, $useDatatable ? 'datatable' : 'table', $projectPairs); - } - ?> - - - - -
      - ';?> -
      -
      - - - - - diff --git a/module/execution/view/build.html.php b/module/execution/view/build.html.php deleted file mode 100644 index 38c8be2d44..0000000000 --- a/module/execution/view/build.html.php +++ /dev/null @@ -1,104 +0,0 @@ - - * @package execution - * @version $Id: build.html.php 4262 2013-01-24 08:48:56Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - -build->confirmDelete)?> - - -
      -
      - -
      -

      - build->noBuild;?> - - createLink('build', 'create', "execution=$execution->id"), " " . $lang->build->create, '', "class='btn btn-info'");?> - -

      -
      - -
      - - - - - - - - - - - - - - - - - $builds):?> - $build):?> - - - - - - - - - - - - - - - -
      build->id;?>build->product;?>build->branch;?>build->name;?>build->url;?>build->date;?>build->builder;?>actions;?>
      id"), sprintf('%03d', $build->id));?>productName;?>branchName;?>createLink('build', 'view', "build=$build->id"), $build->name);?> - scmPath) - { - $colorStyle = strpos($build->scmPath, 'http') === 0 ? "style='color:#2463c7;'" : ''; - echo "
      "; - echo ""; - echo $colorStyle ? html::a($build->scmPath, $build->scmPath, '_blank', $colorStyle) : $build->scmPath; - echo '
      '; - } - if($build->filePath) - { - $colorStyle = strpos($build->filePath, 'http') === 0 ? "style='color:#2463c7;'" : ''; - echo "
      "; - echo ""; - echo $colorStyle ? html::a($build->filePath, $build->filePath, '_blank', $colorStyle) : $build->filePath; - echo '
      '; - } - ?> -
      date?>builder);?>build->buildOperateMenu($build, 'browse', "executionID={$execution->id}&productID={$productID}");?>
      -
      - -
      - diff --git a/module/execution/view/burn.html.php b/module/execution/view/burn.html.php deleted file mode 100644 index 5fd4662896..0000000000 --- a/module/execution/view/burn.html.php +++ /dev/null @@ -1,142 +0,0 @@ - - * @package execution - * @version $Id: burn.html.php 4164 2013-01-20 08:27:55Z wwccss $ - * @link https://www.zentao.net - */ -?> - - - -name);?> -execution->watermark);?> -execution->burnXUnit);?> -execution->burnYUnit);?> - - - -
      -

      - lang->execution->burn . '(' . zget($lang->execution->burnByList, $burnBy) . ')';?> - delay)):?> - execution->delayed;?> - -

      -
      -
      - -
      -
      execution->storyPoint})" : "({$lang->execution->workHour})";?>
      -
      execution->burnXUnit;?>
      -
      -
      execution->charts->burn->graph->reference;?>
      -
      execution->charts->burn->graph->actuality;?>
      - -
      execution->charts->burn->graph->delay;?>
      - -
      -
      -
      - - diff --git a/module/execution/view/cfd.html.php b/module/execution/view/cfd.html.php deleted file mode 100644 index 1feb3033d6..0000000000 --- a/module/execution/view/cfd.html.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @package execution - * @version $Id: cfd.html.php 4164 2013-01-20 08:27:55Z wwccss $ - * @link https://www.zentao.net - */ -?> - - - - - - - -execution->count); ?> -execution->burnXUnit); ?> -execution->charts->cfd->dateRangeTip); ?> - - - -
      -

      execution->cfdTypeList, $type) . $lang->execution->CFD;?>

      - -
      -
      - -
      - -
      -

      execution->noPrintData;?>

      -
      - -
      - diff --git a/module/execution/view/close.html.php b/module/execution/view/close.html.php deleted file mode 100644 index 8dc737a865..0000000000 --- a/module/execution/view/close.html.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @package execution - * @version $Id: suspend.html.php 935 2013-01-16 07:49:24Z wwccss@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -
      -
      -

      - id;?> - name'>" . $execution->name . '') : html::a($this->createLink('execution', 'view', 'execution=' . $execution->id), $execution->name, '_blank');?> - - arrow . $lang->execution->close;?> - -

      -
      -
      - - - - - - - printExtendFields($execution, 'table');?> - - - - - - - - - - - - -
      execution->status;?>
      execution->realEnd;?> -
      - realEnd) && $execution->realEnd != '0000-00-00' ? $execution->realEnd : date('Y-m-d')), "class='form-control form-date' required");?> -
      -
      comment;?>
      execution->close . $lang->executionCommon) . html::linkButton($lang->goback, $this->session->taskList, 'self', '', 'btn btn-wide'); ?>
      -
      -
      -
      -
      - diff --git a/module/execution/view/create.html.php b/module/execution/view/create.html.php deleted file mode 100644 index 285ed9bc01..0000000000 --- a/module/execution/view/create.html.php +++ /dev/null @@ -1,342 +0,0 @@ - - * @package execution - * @version $Id: create.html.php 4728 2013-05-03 06:14:34Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -createLink('execution', 'task', "execution=$executionID");?> - - - - - - - - - - - -execution->weekend);?> -execution->placeholder);?> -execution->errorSameProducts);?> -execution->errorSameBranches);?> - - - -project->common);?> - - - -execution->cancelCopy);?> -execution->copyNoExecution);?> -model) ? $project->model : '');?> -project->manageProducts);?> -project->manageProductPlan);?> -
      -
      -
      -

      execution->createExec : $lang->execution->create;?>

      -
      - -
      -
      -
      - - - getClientLang(), 'zh-') === false and !empty($project->model) and $project->model == 'agileplus') ? 'w-150px' : 'w-120px';?> - - - - - model) and $project->model == 'agileplus'):?> - execution->typeList['stage'], $lang->execution->typeList['']);?> - - - - - - - - - - - - - setCode) and $config->setCode == 1):?> - - - - - - - - - - - - - - - model != 'kanban') and $type != 'kanban'):?> - - - - - - - setPercent) and $config->setPercent == 1):?> - - - - - - - - - - - - printExtendFields('', 'table', 'columns=3');?> - - hasProduct)) $hidden = ''?> - hasProduct) and !empty($project->hasProduct) and $products):?> - - - - - - - - - hasProduct) and !in_array($project->model, array('waterfall', 'kanban', 'waterfallplus'))):?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      execution->projectName;?>
      execution->method;?>execution->typeList, $type, "class='form-control chosen' required onchange='setType(this.value)'");?> - -
      execution->execName : $lang->execution->name;?>
      execution->execCode : $lang->execution->code;?>
      execution->dateRange;?> -
      - begin) ? $plan->begin : date('Y-m-d')), "class='form-control form-date' onchange='computeWorkDays()' placeholder='" . $lang->execution->begin . "' required");?> - execution->to;?> - end) ? $plan->end : ''), "class='form-control form-date' onchange='computeWorkDays()' placeholder='" . $lang->execution->end . "' required");?> -
      -
      execution->endList , '', "onclick='computeEndDate(this.value)'");?>
      execution->days;?> -
      - begin) ? (helper::workDays($plan->begin, $plan->end) + 1) : ''), "class='form-control'");?> - execution->day;?> -
      -
      execution->execType : $lang->execution->type;?> - stage->typeList, '', "class='form-control chosen'"); - } - else - { - echo html::select('lifetime', $lang->execution->lifeTimeList, '', "class='form-control' onchange='showLifeTimeTips()'"); - } - ?> -
      execution->typeDesc;?>
      stage->percent;?> -
      - - % -
      -
      execution->status;?>
      project->manageProductPlan;?> -
      -
      -
      -
      - type != 'normal' and isset($branchGroups[$product->id]);?> -
      '> - productCommon;?> - stageBy == 'project') ? "disabled='disabled'" : '';?> - id, "class='form-control chosen' $disabled onchange='loadBranches(this)' data-last='" . $product->id . "' data-type='" . $product->type . "'");?> - stageBy == 'project') echo html::hidden("products[$i]", $product->id);?> -
      -
      -
      '> -
      - project->branch;?> - branches) ? join(',', $product->branches) : '';?> - id]) ? $branchGroups[$product->id] : array(), $branchIdList, "class='form-control chosen' multiple onchange=\"loadPlans('#products{$i}', this)\"");?> - id]) ? $branchGroups[$product->id] : array(), !empty($linkedBranches[$product->id]) ? $linkedBranches[$product->id] : array(), "class='form-control chosen' multiple onchange=\"loadPlans('#products{$i}', this)\"");?> -
      -
      -
      -
      -
      -
      > - product->plan;?> - id)) echo html::select("plans[$product->id][]", isset($productPlans[$product->id]) ? $productPlans[$product->id] : array(), isset($product->plans) ? $product->plans : '', "class='form-control chosen' multiple");?> - id) echo html::select("plans[$product->id][]", !empty($productPlan) ? $productPlan : array(), isset($productPlan[$plan->id]) ? $plan->id : '', "class='form-control chosen' multiple");?> - stageBy == 'project')):?> -
      - - > -
      - -
      -
      -
      -
      execution->linkPlan;?> - - - - -
      project->manageProductPlan;?> -
      -
      -
      -
      -
      - productCommon;?> - -
      -
      - -
      -
      -
      -
      - product->plan;?> - - stageBy == 'product')):?> -
      - - -
      - -
      -
      -
      -
      execution->teamName;?>
      execution->copyTeam;?>execution->copyTeamTip}'"); ?>
      execution->owner;?> -
      - execution->PO;?> - PO, "class='form-control chosen'");?> -
      -
      -
      - execution->QD;?> - QD, "class='form-control chosen'");?> -
      -
      -
      - execution->PM;?> - PM, "class='form-control chosen'");?> -
      -
      -
      - execution->RD;?> - RD, "class='form-control chosen'");?> -
      -
      execution->team;?>
      execution->execDesc : $lang->execution->desc;?> - fetch('user', 'ajaxPrintTemplates', 'type=execution&link=desc');?> - -
      execution->acl;?>execution->aclList, $acl, "onclick='setWhite(this.value);'", 'block'));?>
      - - goback, '', 'class="btn btn-wide"') : html::backButton();?> -
      -
      -
      -
      - - diff --git a/module/execution/view/dynamic.html.php b/module/execution/view/dynamic.html.php deleted file mode 100755 index 99e447e44e..0000000000 --- a/module/execution/view/dynamic.html.php +++ /dev/null @@ -1,131 +0,0 @@ -dynamic view file of dashboard module of ZenTaoPMS. - * - * @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com) - * @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html) - * @author Chunsheng Wang - * @package dashboard - * @version $Id: action->dynamic.html.php 1477 2011-03-01 15:25:50Z wwccss $ - * @link https://www.zentao.net - */ -?> - - - -
      - -
      -

      action->noDynamic;?>

      -
      - -
      - - $actions):?> - -
      -
      - - action->dynamic->today;?> - - - -
      -
        - - $action):?> - action == 'adjusttasktowait') continue;?> - - major ? 'active' : '';?> - action, array('releaseddoc', 'collected'))) $class .= " {$action->action}";?> -
      • major) echo "class='$class'";?>> -
        - time?> - - actor);?> - actionLabel;?> - objectLabel;?> - objectID;?> - objectName) echo !empty($action->objectLink) ? html::a($action->objectLink, $action->objectName) : $action->objectName;?> - -
        -
      • - -
      -
      - -
      - -
      - -originalDate) + 24 * 3600); -$lastDate = substr($action->originalDate, 0, 10); -$hasPre = $this->action->hasPreOrNext($firstDate, 'pre'); -$hasNext = $this->action->hasPreOrNext($lastDate, 'next'); -$preLink = $hasPre ? inlink('dynamic', "executionID=$executionID&type=$type¶m=$param&recTotal={$pager->recTotal}&date=" . strtotime($firstDate) . '&direction=pre') : 'javascript:;'; -$nextLink = $hasNext ? inlink('dynamic', "executionID=$executionID&type=$type¶m=$param&recTotal={$pager->recTotal}&date=" . strtotime($lastDate) . '&direction=next') : 'javascript:;'; -?> - -
      - -
      - - - - diff --git a/module/execution/view/edit.html.php b/module/execution/view/edit.html.php deleted file mode 100644 index 28a43fb72c..0000000000 --- a/module/execution/view/edit.html.php +++ /dev/null @@ -1,334 +0,0 @@ - - * @package execution - * @version $Id: edit.html.php 4728 2013-05-03 06:14:34Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - - -model == 'waterfall' or $project->model == 'waterfallplus')));?> -attribute);?> -project->manageProducts);?> -project->manageProductPlan);?> -
      -
      -
      -

      - id;?> - createLink('execution', 'view', 'execution=' . $execution->id), $execution->name, '_blank');?> - arrow . ' ' . $lang->execution->edit;?> -

      -
      - id);?> -
      - - - model == 'scrum'):?> - - - - - model == 'kanban'):?> - id);?> - model == 'agileplus'):?> - - - - - tab == 'project' and $project->model == 'waterfallplus'):?> - - - - - - - - - - - setCode) and $config->setCode == 1):?> - - - - - - - - - - - - - - model, array('waterfall', 'waterfallplus'))):?> - - - - - - type != 'kanban' and $project->model != 'ipd'):?> - - - - - - - - - - model != 'ipd'):?> - - - - - - - - - - - - - - - type == 'stage' and isset($config->setPercent) and $config->setPercent == 1):?> - - - - - - model != 'waterfall' and $project->model != 'waterfallplus'): ?> - - hasProduct)) $hidden = ''?> - hasProduct) and $linkedProducts):?> - - - - - - - - - hasProduct)):?> - - - - - - - - - - - hasProduct)):?> - - - - - - - - - - - - - - - - - - - - - - - printExtendFields($execution, 'table');?> - - - grade == 2 ? "disabled='disabled'" : '';?> - - - - - - - -
      execution->projectName;?>project, "class='form-control chosen' onchange='changeProject(this.value)' required");?>
      execution->method;?>execution->typeList, $execution->type);?>
      programplan->parent;?>parent, "class='form-control chosen '");?>
      execution->name;?>name, "class='form-control' required");?>
      execution->code;?>code, "class='form-control' required");?>
      execution->dateRange;?> -
      - begin, "class='form-control form-date' onchange='computeWorkDays()' required placeholder='" . $lang->execution->begin . "'");?> - execution->to;?> - end, "class='form-control form-date' onchange='computeWorkDays()' required placeholder='" . $lang->execution->end . "'");?> -
      - - -
      -
      -
      execution->days;?> -
      - days, "class='form-control'");?> - execution->day;?> -
      -
      stage->type;?> - model == 'ipd' ? $lang->stage->ipdTypeList : $lang->stage->typeList, $execution->attribute, "class='form-control chosen'") : zget($lang->stage->typeList, $execution->attribute); ?> - - -
      execution->type;?> - execution->lifeTimeList, $execution->lifetime, "class='form-control' onchange='showLifeTimeTips()'"); ?> -
      execution->teamName;?>team, "class='form-control'");?>
      execution->status;?>execution->statusList, $execution->status, "class='form-control chosen'");?>
      execution->owner;?> -
      - execution->PO;?> - PO, "class='form-control chosen'");?> -
      -
      -
      - execution->QD;?> - QD, "class='form-control chosen'");?> -
      -
      -
      - execution->PM;?> - PM, "class='form-control chosen'");?> -
      -
      -
      - execution->RD;?> - RD, "class='form-control chosen'");?> -
      -
      stage->percent;?> -
      - percent, "class='form-control'");?> - % -
      -
      project->manageProductPlan;?> -
      -
      -
      -
      - type != 'normal' and isset($branchGroups[$product->id]);?> -
      '> - productCommon;?> - type == 'stage' and $execution->stageBy == 'project') ? "disabled='disabled'" : '';?> - id, "class='form-control chosen' $disabled onchange='loadBranches(this)' data-last='" . $product->id . "' data-type='" . $product->type . "'");?> - type == 'stage' and $execution->stageBy == 'project') echo html::hidden("products[$i]", $product->id);?> -
      -
      -
      '> -
      - product->branchName['branch'];?> - branches);?> - id]) ? $branchGroups[$product->id] : array(), $branchIdList, "class='form-control chosen' multiple onchange=\"loadPlans('#products{$i}', this)\"");?> -
      -
      -
      -
      -
      -
      > - product->plan;?> - id][]", isset($productPlans[$product->id]) ? $productPlans[$product->id] : array(), $product->plans, "class='form-control chosen' multiple");?> - type == 'stage' and $execution->stageBy == 'project')):?> -
      - - > -
      - -
      -
      -
      -
      execution->linkPlan;?> - - plans : '', "class='form-control chosen' multiple");?> - - -
      project->manageProductPlan;?> -
      -
      -
      -
      -
      - productCommon;?> - -
      -
      - -
      -
      -
      -
      - product->plan;?> - -
      - - -
      -
      -
      -
      -
      project->manageProductPlan;?> -
      -
      -
      -
      - type != 'normal' and isset($branchGroups[$product->id]);?> -
      '> - productCommon;?> - model == 'waterfall' or $project->model == 'waterfallplus') ? "disabled='disabled'" : '';?> - id, "class='form-control chosen' $disabled onchange='loadBranches(this)' data-last='" . $product->id . "' data-type='" . $product->type . "'");?> - type == 'stage' and $project->stageBy == 'product') echo html::hidden("products[$i]", $product->id);?> -
      -
      -
      '> -
      - project->branch;?> - branches) ? join(',', $product->branches) : '';?> - id]) ? $branchGroups[$product->id] : array(), $branchIdList, "class='form-control chosen' multiple onchange=\"loadPlans('#products{$i}', this)\"");?> -
      -
      -
      -
      -
      -
      > - product->plan;?> - id][]", isset($productPlans[$product->id]) ? $productPlans[$product->id] : array(), isset($product->plans) ? $product->plans : '', "class='form-control chosen' multiple");?> -
      -
      -
      -
      execution->team;?>
      execution->desc;?>desc), "rows='6' class='form-control kindeditor' hidefocus='true'");?>
      execution->acl;?>execution->aclList, $execution->acl, "onclick='setWhite(this.value);' $class", 'block'));?>
      whitelist;?> -
      - whitelist, 'class="form-control picker-select" multiple');?> - fetch('my', 'buildContactLists', "dropdownName=whitelist");?> -
      -
      -
      -
      -
      -execution->weekend);?> -execution->errorSameProducts);?> -execution->errorSameBranches);?> - - - - -execution->confirmSync);?> - - -project);?> -project->unLinkProductTip);?> - diff --git a/module/execution/view/executionkanban.html.php b/module/execution/view/executionkanban.html.php deleted file mode 100644 index 1e47f61198..0000000000 --- a/module/execution/view/executionkanban.html.php +++ /dev/null @@ -1,45 +0,0 @@ - - - - -
      -

      execution->noExecutions;?>

      -
      - -
      -
      -
      -
      -
      -
      -execution->kanbanColType); -js::set('statusColorList', $lang->execution->statusColorList); -js::set('langMyExecutions', $lang->execution->myExecutions); -js::set('langDoingProject', $lang->execution->doingProject); -js::set('projectNames', $projects); -js::set('priv', - array( - 'canStart' => common::hasPriv('execution', 'start'), - 'canSuspend' => common::hasPriv('execution', 'suspend'), - 'canClose' => common::hasPriv('execution', 'close'), - 'canActivate' => common::hasPriv('execution', 'activate'), - ) -); -?> - - diff --git a/module/execution/view/export.html.php b/module/execution/view/export.html.php deleted file mode 100644 index 74887d4199..0000000000 --- a/module/execution/view/export.html.php +++ /dev/null @@ -1,13 +0,0 @@ - - * @package execution - * @version $Id$ - * @link https://www.zentao.net - */ -?> - diff --git a/module/execution/view/fixfirst.html.php b/module/execution/view/fixfirst.html.php deleted file mode 100644 index be2290b3af..0000000000 --- a/module/execution/view/fixfirst.html.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @package execution - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
      -
      -

      execution->fixFirst;?>

      -
      -
      - - - - - - - -
      -
      - begin?> - estimate) ? $firstBurn->estimate : (!empty($firstBurn->left) ? $firstBurn->left : ''), "class='form-control' placeholder='{$lang->execution->placeholder->totalLeft}'")?> - -
      - - -
      -
      - save, '', "btn btn-primary");?> -
      -
      -
      execution->totalEstimate;?> : totalEstimate;?> execution->workHour;?>
      -
      -
      -
      - diff --git a/module/execution/view/grouptask.html.php b/module/execution/view/grouptask.html.php deleted file mode 100644 index 99eb250682..0000000000 --- a/module/execution/view/grouptask.html.php +++ /dev/null @@ -1,254 +0,0 @@ - - * @package execution - * @version $Id: grouptask.html.php 4143 2013-01-18 07:01:06Z wyd621@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -
      - -
      -

      - task->noTask;?> - - createLink('task', 'create', "execution=$executionID" . (isset($moduleID) ? "&storyID=0&moduleID=$moduleID" : '')), " " . $lang->task->create, '', "class='btn btn-info'");?> - -

      -
      - - - - - - - - - - - - - - - - - - - - - - - $groupTasks):?> - lang->task->noStory : zget($groupByList, $groupKey); - if($groupBy == 'assignedTo' and $groupName == '') $groupName = $this->lang->task->noAssigned; - ?> - $task) - { - if($groupBy == 'story') - { - if($task->parent >= 0) - { - $groupEstimate += $task->estimate; - $groupConsumed += $task->consumed; - if($task->status != 'cancel' && $task->status != 'closed') $groupLeft += $task->left; - } - } - else - { - if($task->parent >= 0) - { - $groupEstimate += $task->estimate; - $groupConsumed += $task->consumed; - if($groupBy == 'status' || ($task->status != 'cancel' && $task->status != 'closed')) $groupLeft += $task->left; - } - } - - if($task->status == 'wait') $groupWait++; - if($task->status == 'doing') $groupDoing++; - if($task->status == 'done') $groupDone++; - if($task->status == 'closed') $groupClosed++; - } - $groupSum = count($groupTasks); - ?> - - - assignedTo == $app->user->account ? "style='color:red'" : '';?> - createLink('task','view',"taskID=$task->id"); ?> - 1 and $i == 0) echo "class='divider-top'";?>> - - - - - - - - - - - - - - - - - - - - - ' data-id=''> - - - - - - - -
      - - task->id;?>execution->pri;?>>priAB;?>task->name;?>task->status;?>task->assignedTo;?>task->finishedBy;?>task->estimateAB;?>task->consumedAB;?>task->leftAB;?>task->progressAB;?>typeAB;?>task->deadlineAB;?>actions;?>
      '> -
      - " . $groupName, '', "class='text-primary' title='$groupName'");?> -
      - - assignedTo])) printf($lang->execution->memberHoursAB, zget($users, $task->assignedTo), $members[$task->assignedTo]->totalHours);?> - execution->groupSummaryAB, $groupSum, $groupWait, $groupDoing, $groupEstimate . $lang->execution->workHourUnit, $groupConsumed . $lang->execution->workHourUnit, $groupLeft . $lang->execution->workHourUnit);?> -
      -
      -
      id);?>pri?>' title='task->priList, $task->pri, $task->pri);?>'>task->priList, $task->pri, $task->pri);?> - team)) echo '' . $lang->task->multipleAB . ' '; - if($task->parent > 0) echo '' . $lang->task->childrenAB . ' '; - if(isset($task->children) && $task->children == true) echo '' . $lang->task->parentAB . ' '; - if(!common::printLink('task', 'view', "task=$task->id", $task->name)) echo $task->name; - ?> - processStatus('task', $task);?>" . $task->assignedToRealName . "";?>finishedBy);?>estimate . $lang->execution->workHourUnit;?>consumed . $lang->execution->workHourUnit;?>left . $lang->execution->workHourUnit;?>progress . '%';?>task->typeList, $task->type);?>'>deadline, 0, 4) > 0) echo '' . substr($task->deadline, 5, 6) . '';?> - - execution&taskID=$task->id", $task, 'list', '', '', 'iframe', true);?> - id", '', 'list');?> - execution&taskid=$task->id", '', 'list', 'trash', 'hiddenwin');?> - -
      - -
      - diff --git a/module/execution/view/importbug.html.php b/module/execution/view/importbug.html.php deleted file mode 100755 index d1ee8742f6..0000000000 --- a/module/execution/view/importbug.html.php +++ /dev/null @@ -1,89 +0,0 @@ - - * @package task - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - - - - - - -
      -
      -
      -
      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - deadline > helper::today() and $bug->deadline > $execution->begin) ? $bug->deadline : '0000-00-00';?> - - - - -
      -
      - -
      - idAB;?> -
      bug->severity;?>> bug->abbr->severity;?>execution->pri;?>>priAB;?>bug->title;?>bug->abbr->status;?>'>task->pri;?>'>task->assignedTo;?>'>task->estimate;?>'>task->estStarted;?>'>task->deadline;?>
      -
      - - -
      - id) . html::hidden("id[$bug->id]", $bug->id);?> -
      bug->severityList, $bug->severity, $bug->severity)?>' data-severity="severity?>">bug->severityList, $bug->severity, $bug->severity)?>pri;?>' title='bug->priList, $bug->pri, $bug->pri)?>'>bug->priList, $bug->pri, $bug->pri)?>id", $bug->title, '', "class='preview'", true, true);?>processStatus('bug', $bug);?>id]", $lang->task->priList, zget($lang->task->priList, $bug->pri ? $bug->pri : 3, 3), "class='form-control chosen'");?>id]", $users, zget($users, $bug->assignedTo, '', $bug->assignedTo), "class='form-control chosen'");?>id]", '', 'size=4 class="form-control"');?>id]", '0000-00-00', 'size=4 class="form-control form-date"');?>id]", $deadline, 'size=4 class="form-control form-date"');?>
      - -
      -
      - diff --git a/module/execution/view/importtask.html.php b/module/execution/view/importtask.html.php deleted file mode 100644 index eb4cba11c2..0000000000 --- a/module/execution/view/importtask.html.php +++ /dev/null @@ -1,110 +0,0 @@ - - * @package execution - * @version $Id: importtask.html.php 4669 2013-04-23 02:28:08Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - - - - -
      -
      - - - - - - - - - - - - - - - - lifetime != 'ops' and !in_array($execution->attribute, array('request', 'review'))):?> - - - - - - - assignedTo == $app->user->account ? 'style=color:red' : '';?> - - - - - - - - - - lifetime != 'ops' and !in_array($execution->attribute, array('request', 'review'))):?> - - - - - -
      -
      - -
      - idAB;?> -
      execution->name ?>execution->pri;?>>priAB;?>task->name;?>task->name;?>task->assignedTo;?>task->leftAB;?>task->deadlineAB;?>statusAB;?>task->story;?>
      -
      - - -
      - id);?> -
      execution];?>pri == '0' ? '' : zget($lang->task->priList, $task->pri, $task->pri);?>id", $task->name, '', "class='preview iframe' data-width='90%'", true, true)) echo $task->name;?>>assignedToRealName;?>left . ' ' . $lang->execution->workHourUnit;?>deadline, 0, 4) > 0) echo '' . $task->deadline . '';?>processStatus('task', $task);?> - storyID) - { - if(common::hasPriv('execution', 'storyView')) - { - echo html::a($this->createLink('execution', 'storyView', "storyid=$task->storyID", '', true), $task->storyTitle, '', "class='preview'"); - } - else - { - echo $task->storyTitle; - } - } - ?> -
      - - - -
      -
      - diff --git a/module/execution/view/kanban.html.php b/module/execution/view/kanban.html.php deleted file mode 100644 index e5f7024bc2..0000000000 --- a/module/execution/view/kanban.html.php +++ /dev/null @@ -1,353 +0,0 @@ - - * @package execution - * @version $Id: kanban.html.php 935 2022-01-11 16:49:24Z $ - * @link https://www.zentao.net - */ -?> - - - -laneCount; -} - -js::set('regions', $regions); -js::set('browseType', $browseType); -js::set('kanbanData', $kanbanData); -js::set('orderBy', $orderBy); -js::set('groupBy', $groupBy); -js::set('execution', $execution); -js::set('productID', $productID); -js::set('hourUnit', $config->hourUnit); -js::set('kanbanLang', $lang->kanban); -js::set('kanbanlaneLang', $lang->kanbanlane); -js::set('storyLang', $lang->story); -js::set('executionLang', $lang->execution); -js::set('bugLang', $lang->bug); -js::set('taskLang', $lang->task); -js::set('deadlineLang', $lang->task->deadlineAB); -js::set('estStartedLang', $lang->task->estStarted); -js::set('kanbancolumnLang', $lang->kanbancolumn); -js::set('kanbancardLang', $lang->kanbancard); -js::set('executionID', $execution->id); -js::set('laneCount', $laneCount); -js::set('userList', $userList); -js::set('noAssigned', $lang->kanbancard->noAssigned); -js::set('users', $users); -js::set('entertime', time()); -js::set('displayCards', $execution->displayCards); -js::set('productNum', $productNum); -js::set('fluidBoard', $execution->fluidBoard); -js::set('minColWidth', $execution->fluidBoard == '0' ? $execution->colWidth : $execution->minColWidth); -js::set('maxColWidth',$execution->fluidBoard == '0' ? $execution->colWidth : $execution->maxColWidth); -js::set('colorListLang', $lang->kanbancard->colorList); -js::set('colorList', $this->config->kanban->cardColorList); -js::set('projectID', $projectID); -js::set('vision', $this->config->vision); -js::set('productCount', count($productNames)); -js::set('executionID', $execution->id); -js::set('needLinkProducts', $lang->execution->needLinkProducts); -js::set('lastUpdateData', ''); -js::set('rdSearchValue', ''); -js::set('defaultMinColWidth', $this->config->minColWidth); -js::set('defaultMaxColWidth', $this->config->maxColWidth); - -$canSortRegion = commonModel::hasPriv('kanban', 'sortRegion') && count($regions) > 1; -$canCreateRegion = common::hasPriv('kanban', 'createRegion') && $groupBy == 'default'; -$canEditRegion = commonModel::hasPriv('kanban', 'editRegion'); -$canDeleteRegion = commonModel::hasPriv('kanban', 'deleteRegion'); -$canCreateLane = commonModel::hasPriv('kanban', 'createLane'); -$canCreateTask = common::hasPriv('task', 'create'); -$canBatchCreateTask = common::hasPriv('task', 'batchCreate'); -$canImportTask = common::hasPriv('execution', 'importTask') && $execution->multiple; - -$canCreateBug = $features['qa'] && $productID && common::hasPriv('bug', 'create'); -$canBatchCreateBug = $features['qa'] && $productID && common::hasPriv('bug', 'batchCreate') && $execution->multiple; -$canImportBug = $features['qa'] && $productID && common::hasPriv('execution', 'importBug') && $execution->multiple; -$hasBugButton = $features['qa'] && ($canCreateBug || $canBatchCreateBug); - -$canCreateStory = $features['story'] && $productID && common::hasPriv('story', 'create'); -$canBatchCreateStory = $features['story'] && $productID && common::hasPriv('story', 'batchCreate'); -$canLinkStory = $features['story'] && $productID && common::hasPriv('execution', 'linkStory') && !empty($execution->hasProduct); -$canLinkStoryByPlan = $features['story'] && $productID && common::hasPriv('execution', 'importplanstories') && !empty($project->hasProduct); -$hasStoryButton = $features['story'] && ($canCreateStory || $canBatchCreateStory || $canLinkStory || $canLinkStoryByPlan); - -$hasTaskButton = $canCreateTask || $canBatchCreateTask || $canImportBug; - -js::set('priv', - array( - 'canCreateTask' => $canCreateTask, - 'canBatchCreateTask' => $canBatchCreateTask, - 'canImportBug' => $canImportBug, - 'canCreateBug' => $canCreateBug, - 'canBatchCreateBug' => $canBatchCreateBug, - 'canCreateStory' => $canCreateStory, - 'canBatchCreateStory' => $canBatchCreateStory, - 'canLinkStory' => $canLinkStory, - 'canLinkStoryByPlan' => $canLinkStoryByPlan, - 'canViewBug' => common::hasPriv('bug', 'view'), - 'canAssignBug' => common::hasPriv('bug', 'assignto'), - 'canConfirmBug' => common::hasPriv('bug', 'confirm'), - 'canResolveBug' => common::hasPriv('bug', 'resolve'), - 'canCopyBug' => common::hasPriv('bug', 'create'), - 'canEditBug' => common::hasPriv('bug', 'edit'), - 'canDeleteBug' => common::hasPriv('bug', 'delete'), - 'canActivateBug' => common::hasPriv('bug', 'activate'), - 'canViewTask' => common::hasPriv('task', 'view'), - 'canAssignTask' => common::hasPriv('task', 'assignto'), - 'canFinishTask' => common::hasPriv('task', 'finish'), - 'canPauseTask' => common::hasPriv('task', 'pause'), - 'canCancelTask' => common::hasPriv('task', 'cancel'), - 'canCloseTask' => common::hasPriv('task', 'close'), - 'canActivateTask' => common::hasPriv('task', 'activate'), - 'canActivateStory' => common::hasPriv('story', 'activate'), - 'canStartTask' => common::hasPriv('task', 'start'), - 'canRestartTask' => common::hasPriv('task', 'restart'), - 'canEditTask' => common::hasPriv('task', 'edit'), - 'canDeleteTask' => common::hasPriv('task', 'delete'), - 'canRecordWorkhourTask' => common::hasPriv('task', 'recordWorkhour'), - 'canToStoryBug' => common::hasPriv('story', 'create'), - 'canAssignStory' => common::hasPriv('story', 'assignto'), - 'canEditStory' => common::hasPriv('story', 'edit'), - 'canDeleteStory' => common::hasPriv('story', 'delete'), - 'canChangeStory' => common::hasPriv('story', 'change'), - 'canCloseStory' => common::hasPriv('story', 'close'), - 'canUnlinkStory' => (common::hasPriv('execution', 'unlinkStory') && !empty($execution->hasProduct)), - 'canViewStory' => common::hasPriv('execution', 'storyView'), - ) -); -?> - - - - - - - - -
      -
      -
      - -
      - -
      -
      - -
      -
      -
      - -
      -
      -
      -
      -
      -
      -
      -
      -
      - - - - - - - diff --git a/module/execution/view/linkstory.html.php b/module/execution/view/linkstory.html.php deleted file mode 100644 index 750d49acb0..0000000000 --- a/module/execution/view/linkstory.html.php +++ /dev/null @@ -1,126 +0,0 @@ - - * @package execution - * @version $Id: linkstory.html.php 4129 2013-01-18 01:58:14Z wwccss $ - * @link https://www.zentao.net - */ -?> - - - - -
      -
      -
      -
      -
      - - - - - - - hasProduct):?> - - - - - - hasProduct && $productType != 'normal'):?> - - - - - - - - - - app->tab == 'execution' ? $this->createLink('execution', 'storyView', "storyID=$story->id", '', true) : $this->createLink('projectstory', 'view', "storyID=$story->id", '', true);?> - - - - - hasProduct):?> - - - - - - hasProduct && $productType != 'normal'):?> - - - - - - - - -
      - -
      - -
      - - idAB;?> -
      execution->pri;?>>priAB;?>story->title;?>story->product;?>story->module;?>'>story->plan;?>story->stage;?>product->branchName[$productType];?>openedByAB;?>story->estimateAB;?>
      - id => sprintf('%03d', $story->id)));?> - id]", $story->product);?> - - pri):?> - pri;?>' title='story->priList, $story->pri, $story->pri);?>'>story->priList, $story->pri, $story->pri);?> - - - parent > 0) echo "{$lang->story->childrenAB}"; - if(common::hasPriv('execution', 'storyView')) - { - echo html::a($storyLink, $story->title, '', "class='iframe' data-width='80%'"); - } - else - { - echo '' . $story->title . ''; - } - ?> - createLink('product', 'browse', "productID=$story->product&branch=$story->branch"), $products[$story->product]->name);?>'>module, '')?>' title='planTitle;?>'>planTitle;?>story->stageList, $story->stage);?>product][$story->branch])) echo $branchGroups[$story->product][$story->branch];?>openedBy);?>estimate . $config->hourUnit;?>
      - - - -
      - rawModule == 'execution' and !$project->hasProduct) ? 'projectNoStories' : 'whyNoStories';?> - loadLang('projectstory');?> -

      multiple ? $lang->{$app->rawModule}->{$emptyTips} : $lang->projectstory->whyNoStories;?>

      -
      - -
      -
      - - - - diff --git a/module/execution/view/managemembers.html.php b/module/execution/view/managemembers.html.php deleted file mode 100644 index 2d0403217f..0000000000 --- a/module/execution/view/managemembers.html.php +++ /dev/null @@ -1,145 +0,0 @@ - - * @package execution - * @version $Id: managemembers.html.php 4662 2013-04-18 02:34:33Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - -project->common);?> -id);?> - - - -
      -
      - - - - - - - - - - - - - - - account])) continue;?> - account]);?> - - - - - - - - - - - - - - - - - - - - - - - - $userName):?> - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      team->account;?>team->role;?>team->days;?>team->hours;?>team->limited;?> actions;?>
      - - - team->limitedList, $member->limited);?> - - -
      account, "class='form-control picker-select' onchange='setRole(this.value, $i)'");?> - - team->limitedList, 'no');?> - - -
      maxCount);?> - - team->limitedList, 'no');?> - - -
      maxCount);?> - - team->limitedList, 'no');?> - - -
      - -
      -
      -
      - - - - - - - - - - - -
      - diff --git a/module/execution/view/manageproducts.html.php b/module/execution/view/manageproducts.html.php deleted file mode 100644 index 13d294c519..0000000000 --- a/module/execution/view/manageproducts.html.php +++ /dev/null @@ -1,105 +0,0 @@ - - * @package execution - * @version $Id: manageproducts.html.php 4129 2013-01-18 01:58:14Z wwccss $ - * @link https://www.zentao.net - */ -?> - - - - - - -project->unLinkProductTip);?> - -
      -
      -
      -
      -
      execution->linkedProducts;?>
      -
      - - $productName):?> - - -
      -
      '> -
      - ";?> - -
      - -
      -
      - - - - - - - - -
      -
      - grade == 1):?> -
      -
      execution->unlinkedProducts;?>
      -
      - $productName):?> -
      -
      '> -
      - ";?> - -
      - -
      -
      - - -
      -
      -
      - - -
      - - grade == 2):?> -
      -
      execution->unlinkedProducts;?>
      -
      - $productName):?> - type != 'normal'):?> -
      -
      '> -
      - ";?> - -
      - -
      -
      - - - -
      -
      -
      - - -
      - -
      -
      -
      - diff --git a/module/execution/view/preview.html.php b/module/execution/view/preview.html.php deleted file mode 100644 index 47e628880d..0000000000 --- a/module/execution/view/preview.html.php +++ /dev/null @@ -1,274 +0,0 @@ - - - - - - $data):?> - $content):?> - - - - - - - - - - - - - -
      -
      -
      -
      - story : $content->storyID; - echo $lang->story->common . "#" . (empty($story) ? '0' : $story) . ''; - echo ' '; - } - ?> - story->common : ($dataType == 'task' ? $lang->task->common : $lang->bug->common)?> - #id;?>
      - Ppri ? $content->pri : '  ';?> -
      -
      '> -
      '> - title : $content->name; - echo $col == 'story' ? mb_substr($title, 0, 22, 'utf8') : mb_substr($title, 0, 85, 'utf8') - ?> -
      - - id]->spec : $content->steps;?> -

      "), 0, 90, 'utf8')?>
      - -
      - -
      -
      -

      - - - - - - -
      -
      -
      story->common : ($dataType == 'task' ? $lang->task->common : $lang->bug->common)?>#
      - P   -
      -
      '> -
      '> -
      - - -
      - -
      - - - - - - - -

      - - -
      - - -
      - - - diff --git a/module/execution/view/printkanban.html.php b/module/execution/view/printkanban.html.php deleted file mode 100644 index 49ae86cad1..0000000000 --- a/module/execution/view/printkanban.html.php +++ /dev/null @@ -1,36 +0,0 @@ - - - - -
      -
      -
      -
      -
      -

      printKanban->common;?>

      -
      -
      - - - - - -
      printKanban->content?>: - printKanban->typeList, 'all')?> -     printKanban->print)?> -
      -
      -
      -
      -
      -
      - diff --git a/module/execution/view/putoff.html.php b/module/execution/view/putoff.html.php deleted file mode 100644 index 3cfcfd5d58..0000000000 --- a/module/execution/view/putoff.html.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @package execution - * @version $Id: delay.html.php 935 2013-01-16 07:49:24Z wwccss@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - -
      -
      -

      - id;?> - name'>" . $execution->name . '') : html::a($this->createLink('execution', 'view', 'execution=' . $execution->id), $execution->name, '_blank');?> - - arrow . $lang->execution->putoff;?> - -

      -
      -
      - - - - - - - - - - - - - - - - - printExtendFields($execution, 'table', 'columns=3');?> - - - - - - - - -
      execution->dateRange;?> -
      - begin, "class='form-control form-date' onchange='computeWorkDays()' placeholder='" . $lang->execution->begin . "'");?> - execution->to;?> - end, "class='form-control form-date' onchange='computeWorkDays()' placeholder='" . $lang->execution->end . "'");?> -
      - - -
      -
      -
      execution->days;?> -
      - days, "class='form-control'");?> - execution->day;?> -
      -
      execution->status;?>status);?>
      comment;?>
      goback, $this->session->taskList, 'self', '', 'btn btn-wide'); ?>
      -
      -
      -
      -
      -execution->weekend);?> - diff --git a/module/execution/view/setkanban.html.php b/module/execution/view/setkanban.html.php deleted file mode 100644 index 173ff5719b..0000000000 --- a/module/execution/view/setkanban.html.php +++ /dev/null @@ -1,55 +0,0 @@ - - * @package execution - * @version $Id: edit.html.php 4728 2013-05-03 06:14:34Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - -
      -
      -
      -

      - execution->setKanban;?> -

      -
      -
      - - - - - - 1):?> - - - - - - - - - - -
      kanban->columnWidth;?> -
      - $lang->kanbancolumn->fluidBoardList['0']), $execution->fluidBoard, "class='inline-block'");?> - colWidth) ? $execution->colWidth : $this->config->colWidth, "class='form-control inline-block setting-input' placeholder='{$this->config->colWidth}' autocomplete='off'");?>px -
      kanbancolumn->fixedTip;?>
      -
      -
      - $lang->kanbancolumn->fluidBoardList['1']), $execution->fluidBoard, "class='inline-block'");?> - minColWidth) ? $execution->minColWidth: $this->config->minColWidth, "class='form-control inline-block setting-input' placeholder='{$this->config->minColWidth}' autocomplete='off'");?>px - ~ - maxColWidth) ? $execution->maxColWidth: $this->config->maxColWidth, "class='form-control inline-block setting-input' placeholder='{$this->config->maxColWidth}' autocomplete='off'");?>px -
      kanbancolumn->autoTip;?>
      -
      -
      kanban->laneHeight;?>kanbanlane->heightTypeList, $heightType, "onclick='setCardCount(this.value);'"));?>
      -
      -
      -
      - diff --git a/module/execution/view/start.html.php b/module/execution/view/start.html.php deleted file mode 100644 index 518c41e4c8..0000000000 --- a/module/execution/view/start.html.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @package execution - * @version $Id: start.html.php 935 2013-01-16 07:49:24Z wwccss@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -
      -
      -

      - id;?> - name'>" . $execution->name . '') : html::a($this->createLink('execution', 'view', 'execution=' . $execution->id), $execution->name, '_blank');?> - - arrow . $lang->execution->start;?> - -

      -
      -
      - - - printExtendFields($execution, 'table', 'columns=2');?> - - - - - - - - - - - - -
      execution->realBegan;?> -
      - realBeganDate) && $execution->realBegan != '0000-00-00' ? $execution->realBegan : date('Y-m-d')), "class='form-control form-date' required");?> -
      -
      comment;?>
      execution->start . $lang->executionCommon) . ' ' . html::linkButton($lang->goback, $this->session->taskList, 'self', '', 'btn btn-wide'); ?>
      -
      -
      -
      - -
      -
      - diff --git a/module/execution/view/story.html.php b/module/execution/view/story.html.php deleted file mode 100644 index b8f01c798d..0000000000 --- a/module/execution/view/story.html.php +++ /dev/null @@ -1,514 +0,0 @@ - - * @package execution - * @version $Id: story.html.php 5117 2013-07-12 07:03:14Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - - -cookie->storyModuleParam);?> -cookie->storyProductParam);?> -cookie->storyBranchParam));?> -id);?> -project);?> - -hasProduct and !$execution->multiple and $config->URAndSR));?> -execution->confirmUnlinkStory)?> -lang->error->notempty, $this->lang->task->type))?> -lang->error->notempty, $this->lang->task->type));?> -lang->error->notempty, $this->lang->story->convertRelations));?> -lang->story->float, $this->lang->story->convertRelations));?> -lang->error->notempty, $this->lang->workingHour))?> - -execution->confirmStoryToTask);?> - -hasProduct && $execution->type != 'sprint'):?> - - -name) && empty($product->name) && empty($branch);?> -tree->all;?> - - - -app->getViewType() == 'xhtml'):?> -
      - - project->getById($execution->project)->name . ' / ' . $this->execution->getByID($execution->id)->name) ?> - -
      - -
      - -
      -
      '>
      - -
      -

      - story->noStory;?> - createLink('execution', 'linkStory', "execution=$execution->id"), " " . $lang->execution->linkStory, '', "class='btn btn-info'"); - } - else - { - $storyModuleID = (int)$this->cookie->storyModuleParam; - if(common::hasPriv('story', 'create')) - { - $createStoryLink = $this->createLink('story', 'create', "productID=$productID&branch=0&moduleID={$storyModuleID}&story=0&execution=$execution->id&bugID=0&planID=0&todoID=0&extra=&storyType=$storyType"); - echo html::a($createStoryLink, " " . $lang->execution->createStory, '', "class='btn btn-info' data-app=$app->tab"); - } - elseif(common::hasPriv('story', 'batchCreate')) - { - $batchCreateLink = $this->createLink('story', 'batchCreate', "productID=$productID&branch=0&moduleID={$storyModuleID}&story=0&execution=$execution->id&plan=0&storyType=$storyType"); - echo html::a($batchCreateLink, " " . $lang->story->batchCreate, '', "class='btn btn-info' data-app=$app->tab"); - } - } - } - ?> -

      -
      - -
      - -
      -
      - moduleName . ucfirst($this->methodName); - $useDatatable = (isset($config->datatable->$datatableId->mode) and $config->datatable->$datatableId->mode == 'datatable'); - $vars = "executionID={$execution->id}&storyType=$storyType&orderBy=%s&type=$type¶m=$param&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}"; - - if($useDatatable) include '../../common/view/datatable.html.php'; - if(!$execution->hasProduct and !$execution->multiple) - { - $planKey = array_search('plan', $config->story->datatable->defaultField); - if($planKey) unset($config->story->datatable->defaultField[$planKey]); - } - - $setting = $this->datatable->getSetting('execution'); - $widths = $this->datatable->setFixedFieldWidth($setting); - $columns = 0; - - $checkObject = new stdclass(); - $checkObject->execution = $execution->id; - - $totalEstimate = 0; - $canBatchEdit = common::hasPriv('story', 'batchEdit'); - $canBatchClose = (common::hasPriv('story', 'batchClose') and $storyType != 'requirement'); - $canBatchChangeStage = (common::hasPriv('story', 'batchChangeStage') and $storyType != 'requirement'); - $canBatchUnlink = common::hasPriv('execution', 'batchUnlinkStory'); - $canBatchToTask = (common::hasPriv('story', 'batchToTask', $checkObject) and $storyType != 'requirement'); - $canBatchAssignTo = common::hasPriv($storyType, 'batchAssignTo'); - - $canBatchAction = ($canBeChanged and ($canBatchEdit or $canBatchClose or $canBatchChangeStage or $canBatchUnlink or $canBatchToTask or $canBatchAssignTo)); - ?> - ';?> - ' id='storyList' data-fixed-left-width='' data-fixed-right-width=''> - - - $value) - { - if(!$execution->hasProduct and $value->id == 'branch') continue; - if(!$execution->hasProduct and !$execution->multiple and $value->id == 'plan') continue; - if(!$execution->hasProduct and !$execution->multiple and $storyType == 'requirement' and $value->id == 'stage') continue; - if(!$execution->hasProduct and !$execution->multiple and $storyType == 'requirement' and $value->id == 'taskCount') continue; - if($value->show) - { - $this->datatable->printHead($value, $orderBy, $vars, $canBatchAction); - $columns ++; - } - } - ?> - - - - $story):?> - estimate; - $story->from = $this->app->tab; - ?> - - $value) - { - if(!$execution->hasProduct and $value->id == 'branch') continue; - if(!$execution->hasProduct and !$execution->multiple and $value->id == 'plan') continue; - if(!$execution->hasProduct and !$execution->multiple and $storyType == 'requirement' and $value->id == 'stage') continue; - if(!$execution->hasProduct and !$execution->multiple and $storyType == 'requirement' and $value->id == 'taskCount') continue; - $this->story->printCell($value, $story, $users, $branchOption, $storyStages, $modulePairs, $storyTasks, $storyBugs, $storyCases, $useDatatable ? 'datatable' : 'table', $storyType, $execution, $showBranch); - } - ?> - - children)):?> - - children as $key => $child):?> - from = $this->app->tab;?> - - children)) ? ' table-child-bottom' : '';?> - - $value) - { - if(!$execution->hasProduct and $value->id == 'branch') continue; - if(!$execution->hasProduct and !$execution->multiple and $value->id == 'plan') continue; - if(!$execution->hasProduct and !$execution->multiple and $storyType == 'requirement' and $value->id == 'stage') continue; - if(!$execution->hasProduct and !$execution->multiple and $storyType == 'requirement' and $value->id == 'taskCount') continue; - $this->story->printCell($value, $child, $users, $branchOption, $storyStages, $modulePairs, $storyTasks, $storyBugs, $storyCases, $useDatatable ? 'datatable' : 'table', $storyType, $execution); - }?> - - - - - - -
      - ';?> - -
      - -
      -
      - - - - -id);?> - - - - - - diff --git a/module/execution/view/storyestimate.html.php b/module/execution/view/storyestimate.html.php deleted file mode 100644 index 180abd7edd..0000000000 --- a/module/execution/view/storyestimate.html.php +++ /dev/null @@ -1,88 +0,0 @@ - - * @package execution - * @version $Id - * @link https://www.zentao.net - */ -?> - - - - -
      -
      -

      - - title;?> -

      -
      - -
      -

      execution->noTeam;?>

      -
      - -
      - -
      - execution->selectRound?> - -
      -
      - execution->reestimate, '', 'class="btn btn-primary"');?> -
      - -
      -
      - - - - - - - - - - - - - - account, "class='form-control'");?> - estimate)):?> - - - - - - - - - - estimate)):?> - - - - - - - - - - - - - -
      execution->team;?> story->estimate;?>execution->newEstimate;?>
      account);?>estimate->{$user->account}) ? $estimateInfo->estimate->{$user->account}->estimate : '';?>
      execution->average;?>average;?>

      -
      - -
      - diff --git a/module/execution/view/storykanban.html.php b/module/execution/view/storykanban.html.php deleted file mode 100644 index 5e2591bb25..0000000000 --- a/module/execution/view/storykanban.html.php +++ /dev/null @@ -1,137 +0,0 @@ - - -execution->confirmUnlinkStory)?> - -app->user->account; -$canLinkStory = $execution->hasProduct or $execution->multiple; -?> - -
      - -
      -

      - story->noStory;?> - createLink('execution', 'linkStory', "execution=$execution->id"), " " . $lang->execution->linkStory, '', "class='btn btn-info'"); - } - else - { - $storyModuleID = (int)$this->cookie->storyModuleParam; - if(common::hasPriv('story', 'create')) - { - $createStoryLink = $this->createLink('story', 'create', "productID=$productID&branch=0&moduleID={$storyModuleID}&story=0&execution=$execution->id"); - echo html::a($createStoryLink, " " . $lang->execution->createStory, '', "class='btn btn-info' data-app=$app->tab"); - } - } - } - ?> -

      -
      - - - - - - - - - - - - - - - -
      story->stageList[$col] . ' (' . $storiesCount . ')';?>
      -
      -
      - -
      - - -
      - createLink('execution', 'storyView', "story=$story->id", '', true), "#{$story->id} {$story->title}", '', 'class="title kanbaniframe" title="' . $story->title . '"'); - } - else - { - echo "" . "#" . $story->id . $story->title . ""; - } - ?> -
      - story->priList, $story->pri);?> - story->statusList[$story->status];?> - -
      createLink('execution', 'unlinkStory', "executionID=$executionID&story=$story->id"), "", 'hiddenwin', "title='{$lang->execution->unlinkStory}'");?>
      - -
      estimate . "$config->hourUnit ";?>
      -
      -
      - - -
      - -
      -
      -
      - -
      - - diff --git a/module/execution/view/suspend.html.php b/module/execution/view/suspend.html.php deleted file mode 100644 index f7a5a1e02c..0000000000 --- a/module/execution/view/suspend.html.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @package execution - * @version $Id: suspend.html.php 935 2013-01-16 07:49:24Z wwccss@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -
      -
      -

      - id;?> - name'>" . $execution->name . '') : html::a($this->createLink('execution', 'view', 'execution=' . $execution->id), $execution->name, '_blank');?> - - arrow . $lang->execution->suspend;?> - -

      -
      -
      - - - - - - printExtendFields($execution, 'table');?> - - - - - - - -
      execution->status;?>
      comment;?>
      execution->suspend . $lang->executionCommon) . html::linkButton($lang->goback, $this->session->taskList, 'self', '', 'btn btn-wide'); ?>
      -
      -
      -
      -
      - diff --git a/module/execution/view/task.html.php b/module/execution/view/task.html.php deleted file mode 100644 index 84166c1eb7..0000000000 --- a/module/execution/view/task.html.php +++ /dev/null @@ -1,491 +0,0 @@ - - * @package execution - * @version $Id: task.html.php 4894 2013-06-25 01:28:39Z wyd621@gmail.com $ - * @link https://www.zentao.net - */ -?> -lifetime == 'ops' or in_array($execution->attribute, array('request', 'review'))) ? 'unsetStory' : ''); - -/* Set unfold parent taskID. */ -$unfoldTasks = isset($config->execution->task->unfoldTasks) ? json_decode($config->execution->task->unfoldTasks, true) : array(); -$unfoldTasks = zget($unfoldTasks, $executionID, array()); -js::set('unfoldTasks', $unfoldTasks); -js::set('unfoldAll', $lang->execution->treeLevel['all']); -js::set('foldAll', $lang->execution->treeLevel['root']); -?> - - -app->getViewType() == 'xhtml'):?> -
      - - - -
      - -
      - -
      -
      - -
      -

      - task->noTask;?> - - " . $lang->task->create, '', "class='btn btn-info'");?> - -

      -
      - -
      -
      - -
      - moduleName . ucfirst($this->methodName); - $useDatatable = (isset($config->datatable->$datatableId->mode) and $config->datatable->$datatableId->mode == 'datatable'); - $vars = "executionID=$execution->id&status=$status&parma=$param&orderBy=%s&recTotal=$recTotal&recPerPage=$recPerPage"; - - if($useDatatable) include '../../common/view/datatable.html.php'; - - $customFields = $this->datatable->getSetting('execution'); - if($execution->lifetime == 'ops' or in_array($execution->attribute, array('request', 'review'))) - { - foreach($customFields as $id => $customField) - { - if($customField->id == 'story') unset($customFields[$id]); - } - } - $widths = $this->datatable->setFixedFieldWidth($customFields); - $columns = 0; - - $task = reset($tasks); - $canBatchEdit = common::hasPriv('task', 'batchEdit', !empty($task) ? $task : null); - $canBatchClose = (common::hasPriv('task', 'batchClose', !empty($task) ? $task : null) and strtolower($browseType) != 'closed'); - $canBatchCancel = (common::hasPriv('task', 'batchCancel', !empty($task) ? $task : null) and strtolower($browseType) != 'cancel'); - $canBatchChangeModule = common::hasPriv('task', 'batchChangeModule', !empty($task) ? $task : null); - $canBatchAssignTo = common::hasPriv('task', 'batchAssignTo', !empty($task) ? $task : null); - - $canBatchAction = ($canBatchEdit or $canBatchClose or $canBatchCancel or $canBatchChangeModule or $canBatchAssignTo); - ?> - ';?> - ' id='taskList' data-fixed-left-width='' data-fixed-right-width=''> - - - app->getViewType() == 'xhtml'):?> - id == 'name' || $field->id == 'id' || $field->id == 'pri' || $field->id == 'status') - { - if($field->show) - { - $this->datatable->printHead($field, $orderBy, $vars, $canBatchAction); - $columns++; - } - } - }?> - - show) - { - $this->datatable->printHead($field, $orderBy, $vars, $canBatchAction); - $columns++; - } - } - ?> - - - - - - children)) echo 'class="table-parent" '; ?>data-id='id;?>' data-status='status?>' data-estimate='estimate?>' data-consumed='consumed?>' data-left='left?>'> - app->getViewType() == 'xhtml'):?> - id == 'name' || $field->id == 'id' || $field->id == 'pri' || $field->id == 'status') - { - $this->task->printCell($field, $task, $users, $browseType, $branchGroups, $modulePairs, $useDatatable ? 'datatable' : 'table'); - } - }?> - - task->printCell($field, $task, $users, $browseType, $branchGroups, $modulePairs, $useDatatable ? 'datatable' : 'table', false, $showBranch);?> - - - children)):?> - - children as $key => $child):?> - - children)) ? ' table-child-bottom' : '';?> - - app->getViewType() == 'xhtml'):?> - id == 'name' || $field->id == 'id' || $field->id == 'pri' || $field->id == 'status') - $this->task->printCell($field, $child, $users, $browseType, $branchGroups, $modulePairs, $useDatatable ? 'datatable' : 'table', true); - }?> - - task->printCell($field, $child, $users, $browseType, $branchGroups, $modulePairs, $useDatatable ? 'datatable' : 'table', true, $showBranch);?> - - - - - - - -
      - ';?> - -
      - - - - diff --git a/module/execution/view/team.html.php b/module/execution/view/team.html.php deleted file mode 100644 index 9e28b069e9..0000000000 --- a/module/execution/view/team.html.php +++ /dev/null @@ -1,112 +0,0 @@ - - * @package execution - * @version $Id: team.html.php 4143 2013-01-18 07:01:06Z wyd621@gmail.com $ - * @link https://www.zentao.net - */ -?> - -execution->confirmUnlinkMember)?> -user->error->noAccess)?> - -
      - -
      -

      - execution->noMembers;?> - user->admin) or empty($app->user->rights['rights']['my']['limited'])) && common::hasPriv('execution', 'manageMembers')):?> - createLink('execution', 'manageMembers', "executionID=$execution->id"), " " . $lang->execution->manageMembers, '', "class='btn btn-info'");?> - -

      -
      - -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      team->account;?>team->role;?>team->join;?>team->days;?>team->hours;?>team->totalHours;?>team->limited;?>actions;?>
      - userID]) ? $this->createLink('user', 'view', "userID={$member->userID}") : "javascript:checkUserDept();"; - echo html::a($link, $member->realname, '', 'data-app="system"'); - } - else - { - echo $member->realname; - } - $memberHours = $member->days * $member->hours; - $totalHours += $memberHours; - ?> - role;?>join;?>days . $lang->execution->day;?>hours . $lang->execution->workHour;?>execution->workHour;?>team->limitedList[$member->limited];?> - id, $member->userID)", '', '', "class='btn' title='{$lang->execution->unlinkMember}'"); - } - ?> -
      - -
      - -
      - diff --git a/module/execution/view/testcase.html.php b/module/execution/view/testcase.html.php deleted file mode 100644 index 462271a2d2..0000000000 --- a/module/execution/view/testcase.html.php +++ /dev/null @@ -1,126 +0,0 @@ - - -
      - -
      - -
      -

      - testcase->noCase;?> - - id", '', '', '', true), " " . $lang->testcase->create, '', "class='btn btn-info' data-app='{$this->app->tab}'");?> - -

      -
      - -
      - - recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?> - - - - - - - - - - - - - - - - - case : $case->id; - $runID = $type == 'assigntome' ? $case->id : 0; - ?> - - - version";?> - task";?> - auto == 'auto' ? " " : '';?> - - - - - - - - - - - - -
      idAB);?> testcase->title);?> priAB);?> testcase->type);?>statusAB);?> testcase->openedByAB);?> testtask->lastRunAccount);?> testtask->lastRunTime);?>testtask->lastRunResult);?>actions;?>
      - id); ?> - createLink('testcase', 'view', $params, '', '', $case->project), $case->title . $autoIcon, null, "style='color: $case->color' data-app='{$this->app->tab}'");?>pri?>' title='testcase->priList, $case->pri, $case->pri);?>'>testcase->priList, $case->pri, $case->pri)?>testcase->typeList, $case->type);?> - needconfirm) - { - echo "{$this->lang->story->changed}"; - } - elseif(isset($case->fromCaseVersion) and $case->fromCaseVersion > $case->version and !$case->needconfirm) - { - echo "{$this->lang->testcase->changed}"; - } - else - { - echo "" . $this->processStatus('testcase', $case) . ""; - } - ?> - openedBy);?>lastRunner);?>lastRunDate)) echo substr($case->lastRunDate, 5, 11);?>lastRunResult ? $lang->testcase->resultList[$case->lastRunResult] : $lang->testcase->unexecuted;?> - browseType = $type; - echo $this->testcase->buildOperateMenu($case, 'browse'); - ?> -
      - -
      - -
      -
      - - - diff --git a/module/execution/view/testtask.html.php b/module/execution/view/testtask.html.php deleted file mode 100644 index 56d374ac7b..0000000000 --- a/module/execution/view/testtask.html.php +++ /dev/null @@ -1,158 +0,0 @@ - - * @package testtask - * @version $Id: browse.html.php 1914 2011-06-24 10:11:25Z yidong@cnezsoft.com $ - * @link https://www.zentao.net - */ -?> - -testtask->confirmDelete)?> -hasProduct) and $project->hasProduct == '0');?> - - - - - -
      - -
      -

      - testtask->noTesttask;?> - - createLink('testtask', 'create', "product=0&executionID=$executionID&build=0&projectID=$execution->project"), " " . $lang->testtask->create, '', "class='btn btn-info' data-app='execution'");?> - -

      -
      - -
      - - - recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?> - - '> - - - - - - - - - - - - - $productTasks):?> - - - status == 'wait') $waitCount ++;?> - status == 'doing') $testingCount ++;?> - status == 'blocked') $blockedCount ++;?> - status == 'done') $doneCount ++;?> - data-status='status;?>'> - - - - - - - processStatus('testtask', $task);?> - - - - - - - - - - - - - -
      '>testtask->product);?> - -
      - -
      - - idAB);?> -
      testtask->name);?>testtask->build);?>statusAB);?>testtask->owner);?>testtask->begin);?>testtask->end);?>actions;?>
      '> - -
      testtask->allTasks;?>
      -
      - - id => sprintf('%03d', $task->id)));?> - - id);?> - - createLink('testtask', 'cases', "taskID=$task->id"), $task->name, '', "data-app='execution'");?>build == 'trunk' || empty($task->buildName)) ? $lang->trunk : html::a($this->createLink('build', 'view', "buildID=$task->build"), $task->buildName);?> - - owner);?>begin?>end?> - id", $task, 'list', 'sitemap'); - common::printIcon('testtask', 'linkCase', "taskID=$task->id", $task, 'list', 'link'); - common::printIcon('execution', 'testreport', "executionID=$executionID&objectType=execution&extra=$task->id", '', 'list', 'summary', '', '', false, "data-app='execution'", $this->lang->testreport->common); - common::printIcon('testtask', 'edit', "taskID=$task->id", $task, 'list'); - common::printIcon('testtask', 'delete', "taskID=$task->id", $task, 'list', 'trash', 'hiddenwin'); - } - ?> -
      - -
      - -
      -testtask->allSummary, $total, $waitCount, $testingCount, $blockedCount, $doneCount));?> -testtask->checkedAllSummary);?> - diff --git a/module/execution/view/tips.html.php b/module/execution/view/tips.html.php deleted file mode 100644 index 6e2220f2f3..0000000000 --- a/module/execution/view/tips.html.php +++ /dev/null @@ -1,25 +0,0 @@ -
      '> -

      execution->afterInfo;?>

      -
      - createLink('execution', 'team', "executionID=$executionID"), $lang->execution->setTeam, '', "class='btn' data-app='execution'");?> - lifetime != 'ops') echo html::a($this->createLink('execution', 'linkstory', "executionID=$executionID"), $lang->execution->linkStory, '', "class='btn' data-app='execution'");?> - createLink('task', 'create', "execution=$executionID"), $lang->execution->createTask, '', "class='btn' data-app='execution'");?> - createLink('execution', 'task', "executionID=$executionID"), $lang->execution->goback, '', "class='btn' data-app='execution'");?> - execution->gobackExecution, '', "class='btn' onclick='closeTipsModal($projectID)' data-app='project'");?> -
      -
      - diff --git a/module/execution/view/tree.html.php b/module/execution/view/tree.html.php deleted file mode 100644 index 2b871116c0..0000000000 --- a/module/execution/view/tree.html.php +++ /dev/null @@ -1,101 +0,0 @@ - - * @package execution - * @version $Id: tree.html.php 4894 2013-06-25 01:28:39Z wyd621@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - - -
      - -
      -

      - task->noTask;?> - - createLink('task', 'create', "execution=$executionID" . (isset($moduleID) ? "&storyID=&moduleID=$moduleID" : '')), " " . $lang->task->create, '', "class='btn btn-info'");?> - -

      -
      - -
      -
      -
        - -
      -
      -
      -
      -
      -
      -
      -
      - -
      - - - - diff --git a/module/execution/view/treestory.html.php b/module/execution/view/treestory.html.php deleted file mode 100644 index 93aa82d346..0000000000 --- a/module/execution/view/treestory.html.php +++ /dev/null @@ -1,358 +0,0 @@ - -
      -

      id?> processStatus('story', $story);?> title;?>

      -
      -
      - story->stage;?> story->stageList[$story->stage];?> -
      -
      - story->estimate;?> estimate;?> -
      -
      - id}"; - common::printIcon('story', 'change', $vars, $story, 'list', 'alter', '', 'btn btn-info btn-icon'); - common::printIcon('story', 'delete', $vars, $story, 'list', 'trash', 'hiddenwin', 'btn btn-info btn-icon'); - common::printIcon('story', 'review', $vars, $story, 'list', 'search', '', 'btn btn-info btn-icon'); - common::printIcon('story', 'close', $vars, $story, 'list', 'off', '', 'btn btn-info btn-icon iframe', true); - common::printIcon('story', 'edit', $vars, $story, 'list', '', '', 'btn btn-info btn-icon'); - common::printIcon('story', 'createCase', "productID=$story->product&branch=$story->branch&module=0&from=¶m=0&$vars", $story, 'list', 'sitemap', '', 'btn btn-info btn-icon'); - ?> -
      -
      -
      -
      -
      story->legendSpec;?>
      -
      - spec) ? $story->spec : "
      " . $lang->noData . '
      ';?> -
      -
      -config->vision != 'lite'):?> -
      -
      story->legendVerify;?>
      -
      - verify) ? $story->verify : "
      " . $lang->noData . '
      ';?> -
      -
      - -fetch('file', 'printFiles', array('files' => $story->files, 'fieldset' => 'true', 'object' => $story));?> - -
      - story->legendBasicInfo;?> -
      - - - config->vision != 'lite' and empty($product->shadow)):?> - - - - - - type != 'normal'):?> - - - - - - config->vision != 'lite'):?> - - - $module) - { - $moduleTitle .= $module->name; - if(!common::printLink('product', 'browse', "productID=$story->product&branch=$story->branch&browseType=byModule¶m=$module->id", $module->name, '', "data-app='product'")) echo $module->name; - if(isset($modulePath[$key + 1])) - { - $moduleTitle .= '/'; - echo $lang->arrow; - } - } - } - $printModule = ob_get_contents(); - ob_end_clean(); - ?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      story->product;?>createLink('product', 'view', "productID=$story->product"), $product->name, '', "data-app='product'");?>
      product->branch, zget($lang->product->branchName, $product->type));?>product&branch=$story->branch", $branches[$story->branch], '', "data-app='product'");?>
      story->module;?>
      story->plan;?> - planTitle)) - { - foreach($story->planTitle as $planID => $planTitle) - { - if(!common::printLink('productplan', 'view', "planID=$planID", $planTitle)) echo $planTitle; - echo '
      '; - } - } - else - { - echo $lang->noData; - } - ?> -
      story->source;?>source ? $lang->story->sourceList[$story->source] : $lang->noData;?>
      story->sourceNote;?>sourceNote ? $story->sourceNote : $lang->noData;?>
      story->status;?> processStatus('story', $story);?>
      story->stage;?> - stages and $branches) - { - foreach($story->stages as $branch => $stage) if(isset($branches[$branch])) echo $branches[$branch] . ' : ' . $lang->story->stageList[$stage] . '
      '; - } - else - { - echo $lang->story->stageList[$story->stage]; - } - ?> -
      story->pri;?> - pri):?> - pri;?>' title='story->priList, $story->pri)?>'>story->priList, $story->pri)?> - - noData;?> - -
      story->estimate;?>estimate;?>
      story->keywords;?>keywords ? $story->keywords : $lang->noData;?>
      story->legendMailto;?> - mailto); - if(empty($mainto)) - { - echo $lang->noData; - } - else - { - foreach($mailto as $account) - { - if(empty($account)) continue; echo "" . zget($users, trim($account)) . '  '; - } - } - ?> -
      -
      -
      - -
      - story->legendProjectAndTask;?> -
      -
        - tasks as $executionTasks) - { - foreach($executionTasks as $task) - { - if(!isset($executions[$task->execution])) continue; - $executionName = $executions[$task->execution]; - echo "
      • " . html::a($this->createLink('task', 'view', "taskID=$task->id", '', true), "#$task->id $task->name", '', "class='iframe' data-width='80%'"); - echo html::a($this->createLink('execution', 'browse', "executionID=$task->execution"), $executionName, '', "class='text-muted'") . '
      • '; - } - } - if(count($story->tasks) == 0) - { - foreach($story->executions as $executionID => $execution) - { - echo "
      • " . html::a($this->createLink('execution', 'browse', "executionID=$executionID"), $execution->name, '', "class='text-muted'") . '
      • '; - } - } - ?> -
      -
      -
      - -
      - story->legendRelated;?> -
      - - - config->vision != 'lite'):?> - - - - - - - - - - - - - - - - - - - - - - - - -
      story->legendFromBug;?> -
        - id $fromBug->title'>" . html::a($this->createLink('bug', 'view', "bugID=$fromBug->id"), "#$fromBug->id $fromBug->title") . '';?> -
      -
      story->legendBugs;?> - - noData;?> - -
        - id $bug->title'>" . html::a($this->createLink('bug', 'view', "bugID=$bug->id"), "#$bug->id $bug->title") . ''; - } - ?> -
      - -
      story->legendCases;?> - - noData;?> - -
        - id $case->title'>" . html::a($this->createLink('testcase', 'view', "caseID=$case->id"), "#$case->id $case->title") . ''; - } - ?> -
      - -
      story->legendLinkStories;?> - linkStories);?> - - noData;?> - -
        - extraStories[$linkStoryID])) echo '
      • ' . html::a($this->createLink('execution', 'storyView', "storyID=$linkStoryID"), "#$linkStoryID " . $story->extraStories[$linkStoryID]) . '
      • '; - } - ?> -
      - -
      story->legendChildStories;?> - childStories);?> - - noData;?> - -
        - extraStories[$childStoryID])) echo '
      • ' . html::a($this->createLink('execution', 'storyView', "storyID=$childStoryID"), "#$childStoryID " . $story->extraStories[$childStoryID]) . '
      • '; - } - ?> -
      - -
      -
      -
      - -
      - story->legendLifeTime;?> -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      story->openedBy;?>openedBy) . $lang->at . $story->openedDate;?>
      story->assignedTo;?>assignedTo ? zget($users, $story->assignedTo) . $lang->at . $story->assignedDate : $lang->noData;?>
      story->reviewedBy;?> - reviewedBy); - if(count($reviewedBy) < 2) - { - echo $lang->noData; - } - else - { - foreach($reviewedBy as $account) echo ' ' . zget($users, trim($account)); - } - ?> -
      story->reviewedDate;?>reviewedBy ? $story->reviewedDate : $lang->noData;?>
      story->closedBy;?>closedBy ? zget($users, $story->closedBy) . $lang->at . $story->closedDate : $lang->noData;?>
      story->closedReason;?> - closedReason ? $lang->story->reasonList[$story->closedReason] : $lang->noData; - if(isset($story->extraStories[$story->duplicateStory])) - { - echo html::a(inlink('view', "storyID=$story->duplicateStory"), '#' . $story->duplicateStory . ' ' . $story->extraStories[$story->duplicateStory]); - } - ?> -
      story->lastEditedBy;?>lastEditedBy ? zget($users, $story->lastEditedBy) . $lang->at . $story->lastEditedDate : $lang->noData;?>
      -
      -
      -createLink('action', 'comment', "objectType=story&objectID=$story->id"); -?> - - diff --git a/module/execution/view/treetask.html.php b/module/execution/view/treetask.html.php deleted file mode 100644 index 47a613cd67..0000000000 --- a/module/execution/view/treetask.html.php +++ /dev/null @@ -1,92 +0,0 @@ - -
      -

      - id?> - status}";?>">processStatus('task', $task);?> - - parent > 0) echo '' . $this->lang->task->childrenAB . '';?> - team)) echo '' . $this->lang->task->multipleAB . '';?> - parentName) ? $task->parentName . '/' : '';?>name;?> - -

      -
      -
      - task->estimate;?> estimate . ' ' . $lang->workingHour;?> - task->consumedAB;?> consumed, 2) . ' ' . $lang->workingHour;?> - task->leftAB;?> left . ' ' . $lang->workingHour;?> -
      -
      - task->type;?> task->typeList[$task->type];?> -
      -
      - task->deadline;?> deadline; if(isset($task->delay)) printf($lang->task->delayWarning, $task->delay);?> -
      -
      - status == 'wait') common::printIcon('task', 'finish', "taskID=$task->id", $task, 'list', '', '', 'btn btn-info btn-icon iframe', true); - if($task->status == 'wait') common::printIcon('task', 'start', "taskID=$task->id", $task, 'list', '', '', 'btn btn-info btn-icon iframe', true); - if($task->status == 'pause') common::printIcon('task', 'restart', "taskID=$task->id", $task, 'list', '', '', 'btn btn-info btn-icon iframe', true); - if($task->status == 'done' or $task->status == 'cancel' or $task->status == 'closed') common::printIcon('task', 'close', "taskID=$task->id", $task, 'list', 'off', '', 'btn btn-info btn-icon iframe', true); - if($task->status == 'doing') common::printIcon('task', 'finish', "taskID=$task->id", $task, 'list', '', '', 'btn btn-info btn-icon iframe', true); - - common::printIcon('task', 'recordWorkhour', "taskID=$task->id", $task, 'list', 'time', '', 'btn btn-info btn-icon iframe', true); - common::printIcon('task', 'edit', "taskID=$task->id", $task, 'list', '', '', 'btn btn-info btn-icon'); - if(empty($task->team) or empty($task->children)) - { - common::printIcon('task', 'batchCreate', "execution=$task->execution&storyID=$task->story&moduleID=$task->module&taskID=$task->id&ifame=0", $task, 'list', 'split', '', 'btn btn-info btn-icon', '', '', $lang->task->children); - } - ?> -
      -
      -
      -
      -
      task->legendDesc;?>
      -
      - desc) ? $task->desc : "
      " . $lang->noData . '
      ';?> -
      -
      -lifetime != 'ops'):?> -fromBug != 0):?> -
      -
      bug->steps;?>
      -
      - bugSteps) ? $task->bugSteps : "
      " . $lang->noData . '
      ';?> -
      -
      -story):?> -
      -
      task->storySpec;?>
      -
      - storySpec) || !empty($task->storyFiles)) ? $task->storySpec : "
      " . $lang->noData . '
      ';?> -
      - fetch('file', 'printFiles', array('files' => $task->storyFiles, 'fieldset' => 'false', 'object' => $task));?> -
      -config->vision != 'lite'):?> -
      -
      task->storyVerify;?>
      -
      - storyVerify) ? $task->storyVerify : "
      " . $lang->noData . '
      ';?> -
      -
      - - -cases) and $task->cases):?> -
      -
      task->case;?>
      -
      -
        - cases as $caseID => $case) echo '
      • ' . html::a($this->createLink('testcase', 'view', "caseID=$caseID"), "#$caseID " . $case) . '
      • ';?> -
      -
      -
      - - -fetch('file', 'printFiles', array('files' => $task->files, 'fieldset' => 'true', 'object' => $task));?> -createLink('action', 'comment', "objectType=task&objectID=$task->id"); -?> - - diff --git a/module/execution/view/view.html.php b/module/execution/view/view.html.php deleted file mode 100644 index 1e2720eb71..0000000000 --- a/module/execution/view/view.html.php +++ /dev/null @@ -1,636 +0,0 @@ - - * @package execution - * @version $Id: view.html.php 4594 2013-03-13 06:16:02Z wyd621@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -config->webRoot . 'js/echarts/echarts.common.min.js'); ?> - - -execution->count); ?> - -
      > -
      -
      - type) and $execution->type != 'kanban'):?> -
      -
      -
      -
      name . $lang->execution->burn;?> - delay)):?> - execution->delayed;?> - -
      - - - -
      -
      - -
      -
      - -
      -
      (execution->workHour;?>)
      -
      -
      execution->charts->burn->graph->reference;?>
      -
      execution->charts->burn->graph->actuality;?>
      - delay)):?> -
      execution->charts->burn->graph->delay;?>
      - -
      -
      - -
      -
      -
      -
      -
      -
      -
      execution->latestDynamic;?>
      - - - -
      -
      -
        - -
      • major) echo "class='active'";?>> -
        - date;?> - actor) . ' ' . "{$action->actionLabel}" . $action->objectLabel . ' ' . html::a($action->objectLink, $action->objectName, '', "title='$action->objectName'");?> -
        -
      • - -
      -
      -
      -
      -
      -
      -
      -
      execution->relatedMember;?>
      - - - -
      -
      -
      - - PM):?> - - PM]);?> -
      PM);?> (execution->PM;?>)
      - - PO):?> - - PO]);?> -
      PO);?> (execution->PO;?>)
      - - QD):?> - - QD]);?> -
      QD);?> (execution->QD;?>)
      - - RD):?> - - RD]);?> -
      RD);?> (execution->RD;?>)
      - - - - $i) break;?> -
      account);?>
      - - -
      - id", "  " . $lang->execution->manageMembers, '', "class='text-muted'");?> -
      -
      -
      -
      -
      -
      -
      -
      -
      execution->doclib;?>
      - - - -
      -
      -
      - - - $docLib):?> - 8) break;?> -
      - - createLink('doc', 'showFiles', "type=execution&objectID=$execution->id"), " " . $docLib->name);?> - - createLink('execution', 'doc', "objectID={$execution->id}&libID=$libID"), " " . $docLib->name, '', "data-app='execution' title='$docLib->name'");?> - -
      - - -
      - id", "  " . $lang->doc->createLib, '', "class='text-muted iframe' data-width='1000px'");?> -
      - -
      -
      -
      -
      - -
      -
      -
      -
      name . $lang->execution->CFD;?>
      - - - -
      -
      - - -
      -
      -
      - -
      -

      execution->noPrintData;?>

      -
      - - -
      -
      -
      -
      -
      -
      -
      execution->relatedMember;?>
      - - - -
      -
      -
      - - PM):?> - - PM]);?> -
      PM);?> (execution->PM;?>)
      - - PO):?> - - PO]);?> -
      PO);?> (execution->PO;?>)
      - - QD):?> - - QD]);?> -
      QD);?> (execution->QD;?>)
      - - RD):?> - - RD]);?> -
      RD);?> (execution->RD;?>)
      - - - - $i) break;?> -
      account);?>
      - - -
      - id", "  " . $lang->execution->manageMembers, '', "class='text-muted'");?> -
      -
      -
      -
      -
      -
      -
      -
      -
      execution->latestDynamic;?>
      -
      -
      -
        - -
      • major) echo "class='active'";?>> -
        - date;?> - actor) . ' ' . "{$action->actionLabel}" . $action->objectLabel . ' ' . html::a($action->objectLink, $action->objectName, '', "title='$action->objectName'");?> -
        -
      • - -
      -
      -
      -
      - - printExtendFields($execution, 'div', "position=left&inForm=0");?> -
      - - createLink('action', 'comment', "objectType=execution&objectID=$execution->id");?> - -
      -
      -
      -
      - session->executionList ? $this->session->executionList : inlink('browse', "executionID=$execution->id");?> - - execution->buildOperateMenu($execution, 'view');?> -
      -
      -
      -
      -
      -
      -
      -
      - setCode) or $config->setCode == 0) ? 'hidden' : '';?> -

      id;?> code;?> name;?>

      -
      -
      -

      - deleted):?> - execution->deleted;?> - - lifetime) and $execution->type != 'kanban' and $project->model != 'waterfall' and $project->model != 'waterfallplus'):?> - execution->lifeTimeList, $execution->lifetime);?> - - delay)):?> - execution->delayed;?> - - processStatus('execution', $execution);?> - -

      -
      -
      - config->systemMode == 'ALM'):?> -
      -
      - project->parent;?> -
      -
      -
      -
      - projectInfo->grade > 1):?> - - $name) - { - $names .= common::hasPriv('program', 'product') ? html::a($this->createLink('program', 'product', "programID=$id"), $name) . '/ ' : $name . '/ '; - } - echo rtrim($names, '/ '); - ?> - -
      -
      -
      -
      - -
      -
      - project->project;?> -
      -
      -
      -
      - - createLink('project', 'index', "projectID=$execution->project", '', '', $execution->project), $execution->projectInfo->name) : $execution->projectInfo->name;?> -
      -
      -
      -
      - projectInfo->hasProduct): ?> -
      -
      - execution->manageProducts;?> - type != 'stage' and $project->model != 'waterfallplus') common::printLink('execution', 'manageproducts', "executionID=$execution->id", '', '', "class='btn btn-link pull-right muted'");?> -
      -
      -
      - $product):?> - branches as $branchID):?> - -
      - createLink('product', 'browse', "productID=$productID&branch=$branchID"), " " . $product->name . $branchName);?> -
      - - -
      -
      -
      - - -
      -
      execution->linkPlan;?>
      -
      -
      - $product) - { - foreach($product->plans as $planIDList) - { - $planIDList = explode(',', $planIDList); - foreach($planIDList as $planID) - { - if(isset($planGroups[$productID][$planID])) echo '
      ' . " " . html::a($this->createLink('productplan', 'view', "planID={$planID}"), $product->name . '/' . $planGroups[$productID][$planID]) . '
      '; - } - } - } - ?> -
      -
      -
      - -
      -
      execution->lblStats;?>
      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      - totalConsumed + $execution->totalLeft) ? floor($execution->totalConsumed / ($execution->totalConsumed + $execution->totalLeft) * 1000) / 1000 * 100 : 0;?> - execution->progress;?> percent;?>   -
      -
      -
      -
      execution->begin;?>begin;?>execution->realBeganAB;?>realBegan == '0000-00-00' ? '' : $execution->realBegan;?>
      execution->end;?>end;?>execution->realEndAB;?>realEnd == '0000-00-00' ? '' : $execution->realEnd;?>
      execution->totalEstimate;?>totalEstimate . $lang->execution->workHour;?>execution->totalDays;?>days . $lang->execution->day;?>
      execution->totalConsumed;?>totalConsumed . $lang->execution->workHour;?>execution->totalHours;?>totalHours . $lang->execution->workHour;?>
      execution->totalLeft;?>totalLeft . $lang->execution->workHour;?>
      -
      -
      -
      -
      execution->basicInfo;?>
      -
      - - - - - - - - - - - - - - - -
      story->common;?>storyCount;?>task->common;?>taskCount;?>bug->common;?>bugCount;?>
      -
      -
      -
      -
      execution->acl;?>
      -
      -

      execution->aclList[$execution->acl];?>

      -
      -
      - printExtendFields($execution, 'div', "position=right&inForm=0&inCell=1");?> -
      -
      -
      -
      -
      -
      - -
      - - - diff --git a/module/execution/zen.php b/module/execution/zen.php index 04825d8342..34d4878245 100644 --- a/module/execution/zen.php +++ b/module/execution/zen.php @@ -510,8 +510,10 @@ class executionZen extends execution } /* Get linked branches. */ - $products = $this->loadModel('product')->getProducts($executionID); - $linkedBranches = array(); + $branches = $this->project->getBranchesByProject($executionID); + $linkedProductIdList = empty($branches) ? '' : array_keys($branches); + $products = $this->loadModel('product')->getProducts($executionID, 'all', '', true, $linkedProductIdList, false); + $linkedBranches = array(); foreach($products as $product) { if(isset($product->branches)) diff --git a/module/extension/view/activate.html.php b/module/extension/view/activate.html.php deleted file mode 100644 index daf49ea6a5..0000000000 --- a/module/extension/view/activate.html.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @package extension - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
      -
      -
      -

      - icons['extension']) . $this->lang->extension->activate;?> -

      -
      - -
      -
      -
      - -
      -
      -

      -
      -

      extension->viewInstalled, 'onclick=parent.location.href="' . inlink('browse', 'type=installed') . '"');?>

      -
      -
      - -
      -
      - - diff --git a/module/extension/view/browse.html.php b/module/extension/view/browse.html.php deleted file mode 100644 index 2fc886df5b..0000000000 --- a/module/extension/view/browse.html.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @package extension - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
      -
      - -
      -
      name;?>
      -
      desc;?>
      -
      -
      -
      - code"), $lang->extension->structure, '', "class='btn iframe'"); - $deactivateCode = html::a(inlink('deactivate', "extension=$extension->code"), $lang->extension->deactivate, '', "class='btn iframe'"); - $activateCode = html::a(inlink('activate', "extension=$extension->code"), $lang->extension->activate, '', "class='btn iframe'"); - $uninstallCode = html::a(inlink('uninstall', "extension=$extension->code"), $lang->extension->uninstall, '', "class='btn iframe'"); - $installCode = html::a(inlink('install', "extension=$extension->code"), $lang->extension->install, '', "class='btn iframe'"); - $eraseCode = html::a(inlink('erase', "extension=$extension->code"), $lang->extension->erase, '', "class='btn iframe'"); - - if(isset($extension->viewLink)) - { - echo html::a($extension->viewLink, $lang->extension->view, '', "class='btn extension'"); - } - if($extension->status == 'installed') - { - echo $structureCode; - } - if($extension->status == 'installed' and !empty($extension->upgradeLink)) - { - echo html::a($extension->upgradeLink, $lang->extension->upgrade, '', "class='btn iframe' data-height='500px'"); - } - - if($extension->type != 'patch') - { - if($extension->status == 'installed') echo $deactivateCode . $uninstallCode; - if($extension->status == 'deactivated') echo $activateCode . $uninstallCode; - if($extension->status == 'available') echo $installCode . $eraseCode; - } - echo html::a($extension->site, $lang->extension->site, '_blank', 'class=btn'); - ?> -
      -
      - extension->version}: {$extension->version} "; - echo "{$lang->extension->author}: {$extension->author} "; - $expiredDate = $this->extension->getExpireDate($extension); - if(!empty($expiredDate)) - { - echo $lang->extension->expiredDate . ': '; - echo $expiredDate != 'life' ? "{$expiredDate}" : "{$lang->extension->life}"; - } - ?> -
      -
      - -
      -
      - diff --git a/module/extension/view/deactivate.html.php b/module/extension/view/deactivate.html.php deleted file mode 100644 index 00223f26ba..0000000000 --- a/module/extension/view/deactivate.html.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @package extension - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
      -
      -
      -

      - icons['extension']);?> -

      -
      -
      -

      - -
      -

      extension->unremovedFiles;?>

      - ', $removeCommands);?> -
      - -
      -

      extension->viewDeactivated, 'onclick=parent.location.href="' . inlink('browse', 'type=deactivated') . '"');?>

      -
      -
      -
      - - diff --git a/module/extension/view/erase.html.php b/module/extension/view/erase.html.php deleted file mode 100644 index e1c3a2fb01..0000000000 --- a/module/extension/view/erase.html.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @package extension - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
      -
      -
      -

      - icons['extension']);?> - - extension->erase;?> -

      -
      -
      - -
      -

      - -

      extension->unremovedFiles;?>

      -

      ', $removeCommands);?>

      - -

      extension->viewAvailable, 'onclick=parent.location.href="' . inlink('browse', 'type=available') . '"');?>

      -
      -
      -
      -
      - - diff --git a/module/extension/view/install.html.php b/module/extension/view/install.html.php deleted file mode 100644 index 68c1d4b280..0000000000 --- a/module/extension/view/install.html.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @package extension - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
      -
      -
      -

      - - - - extension->upgradeVersion, $this->post->installedVersion, $this->post->upgradeVersion); - ?> - -

      -
      - -
      -
      -
      extension->installFailed, $installType);?>
      -

      -
      -
      - extension->refreshPage, 'onclick=location.href=location.href', 'btn btn-primary');?> -
      - -
      -
      -
      extension->license;?>
      -

      - extension->agreeLicense, '', "class='btn btn-primary'");?> -
      -
      - -
      -
      extension->installFinished, $installType);?>
      -
      - extension->viewInstalled, 'onclick=parent.location.href="' . inlink('browse') . '" class="btn btn-success"');?> -
      -
      -
      - {$lang->extension->successDownloadedPackage}"; - echo "
      {$lang->extension->successCopiedFiles}
      "; - echo '
        '; - foreach($files as $fileName => $md5) - { - echo "
      • $fileName
      • "; - } - echo '
      '; - echo "
      {$lang->extension->successInstallDB}
      "; - ?> -
      -
      - -
      -
      - - diff --git a/module/extension/view/obtain.html.php b/module/extension/view/obtain.html.php deleted file mode 100644 index 33ce02c85a..0000000000 --- a/module/extension/view/obtain.html.php +++ /dev/null @@ -1,144 +0,0 @@ - - * @package extension - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
      - -
      -
      - -
      - - currentRelease; - $latestRelease = isset($extension->latestRelease) ? $extension->latestRelease : ''; - ?> -
      -
      - - releaseVersion != $currentRelease->releaseVersion) - { - printf($lang->extension->latest, $latestRelease->viewLink, $latestRelease->releaseVersion, $latestRelease->zentaoCompatible); - }?> - -
      - name . "($currentRelease->releaseVersion)";?> - '>extension->obtainOfficial[$extension->offcial];?> -
      -
      -
      abstract;?>
      -
      -
      - extension->author}: {$extension->author} "; - echo "{$lang->extension->downloads}: {$extension->downloads} "; - echo "{$lang->extension->compatible}: {$lang->extension->compatibleList[$currentRelease->compatible]} "; - - echo " {$lang->extension->depends}: "; - if(!empty($currentRelease->depends)) - { - foreach(json_decode($currentRelease->depends, true) as $code => $limit) - { - echo $code; - if($limit != 'all') - { - echo '('; - if(!empty($limit['min'])) echo '>= v' . $limit['min']; - if(!empty($limit['max'])) echo '<= v' . $limit['min']; - echo ')'; - } - echo ' '; - } - } - ?> -
      - extension->grade}: ", html::printStars($extension->stars); - ?> -
      -
      - viewLink, $lang->extension->view, '', 'class="btn extension"'); - if($currentRelease->public) - { - if($extension->type != 'computer' and $extension->type != 'mobile') - { - if(isset($installeds[$extension->code])) - { - if($installeds[$extension->code]->version != $extension->latestRelease->releaseVersion and $this->extension->checkVersion($extension->latestRelease->zentaoCompatible)) - { - $upgradeLink = inlink('upgrade', "extension=$extension->code&downLink=" . helper::safe64Encode($currentRelease->downLink) . "&md5=$currentRelease->md5&type=$extension->type"); - echo html::a($upgradeLink, $lang->extension->upgrade, '', 'class="iframe btn"'); - } - else - { - echo html::commonButton(" " . $lang->extension->installed, "disabled='disabled'", 'btn text-success'); - } - } - } - } - echo html::a($currentRelease->downLink, $lang->extension->downloadAB, '_blank', 'class="btn"'); - echo html::a($extension->site, $lang->extension->site, '_blank', 'class=btn'); - ?> -
      -
      -
      -
      - -
      - - - - -
      - -
      -

      extension->errorOccurs;?>

      -
      extension->errorGetExtensions;?>
      -
      -
      - -
      -
      -
      - - diff --git a/module/extension/view/safe.html.php b/module/extension/view/safe.html.php deleted file mode 100644 index fa0008b2fe..0000000000 --- a/module/extension/view/safe.html.php +++ /dev/null @@ -1,18 +0,0 @@ - - * @package extension - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
      - - extension->refreshPage, 'onclick=location.href=location.href', 'btn btn-primary');?> -
      - diff --git a/module/extension/view/structure.html.php b/module/extension/view/structure.html.php deleted file mode 100644 index 1961ad3319..0000000000 --- a/module/extension/view/structure.html.php +++ /dev/null @@ -1,31 +0,0 @@ - - * @package extension - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
      -
      -
      -

      - icons['extension']);?> - name . '[' . $extension->code . '] ' .$lang->extension->structure . ':';?> -

      -
      -
      -
      app->getAppRoot();
      -      $files   = json_decode($extension->files);
      -      foreach($files as $file => $md5) echo $appRoot . $file . "\n";
      -      ?>
      -
      -
      -
      - diff --git a/module/extension/view/uninstall.html.php b/module/extension/view/uninstall.html.php deleted file mode 100644 index b51ad2efac..0000000000 --- a/module/extension/view/uninstall.html.php +++ /dev/null @@ -1,64 +0,0 @@ - - * @package extension - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
      -
      -
      -

      - icons['extension']);?> - - extension->uninstall;?> -

      -
      - -
      - -
      - {$lang->extension->confirmUninstall}"; - echo html::a(inlink('uninstall', "extension=$code&confirm=yes"), $lang->extension->uninstall, '', "class='btn'"); - echo "

      "; - ?> -
      -
      - -
      - -
      - " . $lang->extension->uninstallFailed . ""; - echo "

      $error

      "; - ?> -
      -
      - -
      - -
      - {$title}"; - if(!empty($backupFile)) echo "

      " . sprintf($lang->extension->backDBFile, $backupFile) . '

      '; - if($removeCommands) - { - echo "

      {$lang->extension->unremovedFiles}

      "; - echo join('
      ', $removeCommands); - } - echo "

      " . html::commonButton($lang->extension->viewAvailable, 'onclick=parent.location.href="' . inlink('browse', 'type=available') . '"') . '

      '; - ?> -
      -
      - -
      -
      - - diff --git a/module/extension/view/upload.html.php b/module/extension/view/upload.html.php deleted file mode 100644 index 1f33c4b6dc..0000000000 --- a/module/extension/view/upload.html.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @package extension - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
      -
      -
      -

      extension->upload;?>

      -
      - -
      -
      -

      - extension->refreshPage, 'onclick=location.href=location.href', 'btn btn-primary');?> -
      -
      - -
      -
      - - extension->install, '', 'btn btn-primary');?> -
      -
      - -
      -
      - diff --git a/module/file/model.php b/module/file/model.php index c2ee2dec9b..4a6b5e0846 100755 --- a/module/file/model.php +++ b/module/file/model.php @@ -1465,7 +1465,6 @@ class fileModel extends model } } - $this->updateObjectID($this->post->uid, $oldObject->id, $objectType); $addedFiles = $this->saveUpload($objectType, $oldObject->id, $extra, $filesName, $labelsName); if(!isset($oldObject->{$filesName})) $oldObject->{$filesName} = array(); diff --git a/module/file/test/model/processfilediffsforobject.php b/module/file/test/model/processfilediffsforobject.php old mode 100644 new mode 100755 index e9e89ce827..d6faba54e5 --- a/module/file/test/model/processfilediffsforobject.php +++ b/module/file/test/model/processfilediffsforobject.php @@ -4,6 +4,7 @@ /** title=测试 fileModel->processFileDiffsForObject(); +timeout=0 cid=0 - 传入空对象。属性count @added:;delete:;rename:; @@ -12,6 +13,8 @@ cid=0 - 有重命名文件字段。 @added:;delete:文件标题3;rename:文件标题3,11,文件标题4,22; +- 有重命名文件字段。 @added:;delete:文件标题1;rename:文件标题1,11; + */ include dirname(__FILE__, 5) . '/test/lib/init.php'; include dirname(__FILE__, 2) . '/lib/file.unittest.class.php'; @@ -46,4 +49,9 @@ $newObject->deleteFiles = array(3); $newObject->renameFiles = array(3 => '11', 4 => '22'); r($file->processFileDiffsForObjectTest('story', $oldObject, $newObject)) && p() && e('added:;delete:文件标题3;rename:文件标题3,11,文件标题4,22;'); //有重命名文件字段。 -$config->debug = $debug; +$oldObject->files = $oldFiles; +$newObject->deleteFiles = array(1); +$newObject->renameFiles = array(1 => '11'); +r($file->processFileDiffsForObjectTest('story', $oldObject, $newObject)) && p() && e('added:;delete:文件标题1;rename:文件标题1,11;'); //有重命名文件字段。 + +$config->debug = $debug; \ No newline at end of file diff --git a/module/git/view/cat.html.php b/module/git/view/cat.html.php deleted file mode 100644 index a2bbb7497e..0000000000 --- a/module/git/view/cat.html.php +++ /dev/null @@ -1,18 +0,0 @@ - - * @package file - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
      -
      -
      <?php echo $code;?>
      -
      - diff --git a/module/git/view/diff.html.php b/module/git/view/diff.html.php deleted file mode 100644 index cdb3fc9553..0000000000 --- a/module/git/view/diff.html.php +++ /dev/null @@ -1,19 +0,0 @@ - - * @package file - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -loadModel('repo')->buildURL('cat', $path, $revision);?> -
      -
      -
      <?php echo $diff;?>
      -
      - diff --git a/module/gitea/view/binduser.html.php b/module/gitea/view/binduser.html.php deleted file mode 100644 index 289379fecf..0000000000 --- a/module/gitea/view/binduser.html.php +++ /dev/null @@ -1,99 +0,0 @@ - - * @package gitea - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -createLink('gitea', 'browse', ""); ?> - -
      -
      - ' . $lang->goback, $browseLink, 'self', "data-app='{$app->tab}'", 'btn btn-secondary'); - - $allLink = $this->createLink('gitea', 'binduser', "giteaID={$giteaID}&type=all"); - $bindedLink = $this->createLink('gitea', 'binduser', "giteaID={$giteaID}&type=binded"); - $notBindLink = $this->createLink('gitea', 'binduser', "giteaID={$giteaID}&type=notBind"); - if($type == 'all') - { - echo html::linkButton('' . $lang->gitea->all . "" . count($giteaUsers) . "", $allLink, 'self', "data-app='{$app->tab}'", 'btn btn-info active'); - echo html::linkButton('' . $lang->gitea->notBind, $notBindLink, 'self', "data-app='{$app->tab}'", 'btn btn-info'); - echo html::linkButton('' . $lang->gitea->binded, $bindedLink, 'self', "data-app='{$app->tab}'", 'btn btn-info'); - } - else if($type == 'binded') - { - echo html::linkButton('' . $lang->gitea->all, $allLink, 'self', "data-app='{$app->tab}'", 'btn btn-info'); - echo html::linkButton('' . $lang->gitea->notBind, $notBindLink, 'self', "data-app='{$app->tab}'", 'btn btn-info'); - echo html::linkButton('' . $lang->gitea->binded . "" . count($giteaUsers) . "", $bindedLink, 'self', "data-app='{$app->tab}'", 'btn btn-info active'); - } - else - { - echo html::linkButton('' . $lang->gitea->all, $allLink, 'self', "data-app='{$app->tab}'", 'btn btn-info'); - echo html::linkButton('' . $lang->gitea->notBind . "" . count($giteaUsers) . "", $notBindLink, 'self', "data-app='{$app->tab}'", 'btn btn-info active'); - echo html::linkButton('' . $lang->gitea->binded, $bindedLink, 'self', "data-app='{$app->tab}'", 'btn btn-info'); - } - ?> -
      -
      -
      - - - - - - - - - - - - - id]", $giteaUser->realname);?> - - - - - - - - - - - - - - -
      gitea->giteaAccount;?>gitea->giteaEmail;?>gitea->zentaoEmail;?>gitea->zentaoAccount;?> gitea->bindingStatus;?>
      - avatar, "height=20 width=20 class='img-circle'");?> - realname . '@' . $giteaUser->account;?> - email;?>id]", $giteaUser->zentaoUsers, $giteaUser->zentaoAccount, "class='form-control select chosen gitea-user-bind'" );?> - binded === 1):?> - gitea->binded;?> - binded === 2):?> - ' . $lang->gitea->bindedError . '';?> - - ' . $lang->gitea->notBind . '';?> - -
      - - createLink('space', 'browse'), $lang->goback, '', 'class="btn btn-wide"');?> -
      -
      -
      -
      - - diff --git a/module/gitea/view/browse.html.php b/module/gitea/view/browse.html.php deleted file mode 100644 index 044408342e..0000000000 --- a/module/gitea/view/browse.html.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @package gitea - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - - -
      -

      - noData;?> - - createLink('gitea', 'create'), " " . $lang->gitea->create, '', "class='btn btn-info'");?> - -

      -
      - -
      -
      - - - - recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?> - - - - - - - - $gitea): ?> - - - - - - - - -
      gitea->id);?>gitea->name);?>gitea->url);?>actions;?>
      - - ">name;?> - - name;?> - - url, $gitea->url, '_target');?> - isBindUser); - common::printIcon('gitea', 'delete', "giteaID=$id", '', 'list', 'trash', 'hiddenwin'); - ?> -
      - - - -
      -
      - - diff --git a/module/gitea/view/create.html.php b/module/gitea/view/create.html.php deleted file mode 100644 index 5e0cb86150..0000000000 --- a/module/gitea/view/create.html.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @package gitea - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
      -
      -
      -
      -

      gitea->lblCreate;?>

      -
      -
      - - - - - - - - - - - - - - - - -
      gitea->name;?>
      gitea->url;?>
      gitea->token;?>
      - -
      -
      -
      -
      -
      - diff --git a/module/gitea/view/edit.html.php b/module/gitea/view/edit.html.php deleted file mode 100644 index 8a884e548a..0000000000 --- a/module/gitea/view/edit.html.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @package gitea - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
      -
      -
      -
      -

      gitea->edit;?>

      -
      -
      - - - - - - - - - - - - - - - - - -
      gitea->name;?>name) ? $gitea->name : '', "class='form-control'");?>
      gitea->url;?>url) ? $gitea->url : '', "class='form-control'");?>
      gitea->token;?>token) ? $gitea->token : '', "class='form-control'");?>
      - -
      -
      -
      -
      -
      - diff --git a/module/gitea/view/view.html.php b/module/gitea/view/view.html.php deleted file mode 100644 index 898d95e375..0000000000 --- a/module/gitea/view/view.html.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @package GitLab - * @version $Id: view.html.php 4728 2013-05-03 06:14:34Z david18810279601@gmail.com $ - * @link https://www.zentao.net - * */ -?> - - - -
      -
      -
      -
      -
      gitea->url;?>
      -
      url, $gitea->url, '_target');?>
      -
      -
      -
      -
      -
      - diff --git a/module/gitlab/view/binduser.html.php b/module/gitlab/view/binduser.html.php deleted file mode 100644 index 8e976ebe44..0000000000 --- a/module/gitlab/view/binduser.html.php +++ /dev/null @@ -1,99 +0,0 @@ - - * @package story - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -createLink('gitlab', 'browse', ""); ?> - -
      -
      - ' . $lang->goback, $browseLink, 'self', "data-app='{$app->tab}'", 'btn btn-secondary'); - - $allLink = $this->createLink('gitlab', 'binduser', "gitlabID={$gitlabID}&type=all"); - $bindedLink = $this->createLink('gitlab', 'binduser', "gitlabID={$gitlabID}&type=binded"); - $notBindLink = $this->createLink('gitlab', 'binduser', "gitlabID={$gitlabID}&type=notBind"); - if($type == 'all') - { - echo html::linkButton('' . $lang->gitlab->all . "" . count($gitlabUsers) . "", $allLink, 'self', "data-app='{$app->tab}'", 'btn btn-info active'); - echo html::linkButton('' . $lang->gitlab->notBind, $notBindLink, 'self', "data-app='{$app->tab}'", 'btn btn-info'); - echo html::linkButton('' . $lang->gitlab->binded, $bindedLink, 'self', "data-app='{$app->tab}'", 'btn btn-info'); - } - else if($type == 'binded') - { - echo html::linkButton('' . $lang->gitlab->all, $allLink, 'self', "data-app='{$app->tab}'", 'btn btn-info'); - echo html::linkButton('' . $lang->gitlab->notBind, $notBindLink, 'self', "data-app='{$app->tab}'", 'btn btn-info'); - echo html::linkButton('' . $lang->gitlab->binded . "" . count($gitlabUsers) . "", $bindedLink, 'self', "data-app='{$app->tab}'", 'btn btn-info active'); - } - else - { - echo html::linkButton('' . $lang->gitlab->all, $allLink, 'self', "data-app='{$app->tab}'", 'btn btn-info'); - echo html::linkButton('' . $lang->gitlab->notBind . "" . count($gitlabUsers) . "", $notBindLink, 'self', "data-app='{$app->tab}'", 'btn btn-info active'); - echo html::linkButton('' . $lang->gitlab->binded, $bindedLink, 'self', "data-app='{$app->tab}'", 'btn btn-info'); - } - ?> -
      -
      -
      - - - - - - - - - - - - - id]", $gitlabUser->realname);?> - - - - - - - - - - - - - - -
      gitlab->gitlabAccount;?>gitlab->gitlabEmail;?>gitlab->zentaoEmail;?>gitlab->zentaoAccount;?> gitlab->bindingStatus;?>
      - avatar, "height=20 width=20 class='img-circle'");?> - realname . '@' . $gitlabUser->account;?> - email;?>id]", $gitlabUser->zentaoUsers, $gitlabUser->zentaoAccount, "class='form-control select chosen gitlab-user-bind'" );?> - binded === 1):?> - gitlab->binded;?> - binded === 2):?> - ' . $lang->gitlab->bindedError . '';?> - - ' . $lang->gitlab->notBind . '';?> - -
      - - goback, '', 'class="btn btn-wide"');?> -
      -
      -
      -
      - - diff --git a/module/gitlab/view/browse.html.php b/module/gitlab/view/browse.html.php deleted file mode 100644 index 8bd5876f5b..0000000000 --- a/module/gitlab/view/browse.html.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @package gitlab - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - - -
      -

      - noData;?> - - createLink('gitlab', 'create'), " " . $lang->gitlab->create, '', "class='btn btn-info'");?> - -

      -
      - -
      -
      - - - - recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?> - - - - - - - - $gitlab): ?> - - - - - - - - -
      gitlab->id);?>gitlab->name);?>gitlab->url);?>actions;?>
      - - ">name;?> - - name;?> - - url, $gitlab->url, '_target');?> - -
      - - - -
      -
      - - diff --git a/module/gitlab/view/browsebranch.html.php b/module/gitlab/view/browsebranch.html.php deleted file mode 100644 index 44fd5b4769..0000000000 --- a/module/gitlab/view/browsebranch.html.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @package gitlab - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -recTotal}&recPerPage={$pager->recPerPage}&pageID=1")?> - - - -
      -

      - noData;?> - - createLink('gitlab', 'createBranch', "gitlabID=$gitlabID&projectID=$projectID"), " " . $lang->gitlab->createBranch, '', "class='btn btn-info'");?> - -

      -
      - -
      -
      - - recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?> - - - - - - - - - $gitlabBranch): ?> - - - - - - - -
      gitlab->branch->name);?>gitlab->branch->lastCommitter;?>gitlab->branch->lastCommittedDate);?>
      name;?>lastCommitter;?>lastCommittedDate?>
      - - - -
      -
      - - diff --git a/module/gitlab/view/browsegroup.html.php b/module/gitlab/view/browsegroup.html.php deleted file mode 100644 index c9108fc4e4..0000000000 --- a/module/gitlab/view/browsegroup.html.php +++ /dev/null @@ -1,75 +0,0 @@ - - * @package gitlab - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - - -
      -

      - noData;?> - - createLink('gitlab', 'createGroup', "gitlabID=$gitlabID"), " " . $lang->gitlab->group->create, '', "class='btn btn-info'");?> - -

      -
      - -
      -
      - - - - - - - - - - - - - $gitlabGroup): ?> - - - - - - - - - -
      gitlab->group->id);?>gitlab->group->name);?>gitlab->group->path);?>gitlab->group->createOn;?>actions;?>
      id;?> - name))); ?> - $gitlabGroup->avatar_url, 'account' => $groupName), 20); ?> - full_name;?> - url . '/' . $gitlabGroup->full_path, $gitlabGroup->full_path, '_target');?>created_at, 0, 10);?> - user->admin or in_array($gitlabGroup->id, $adminGroupIDList)) ? true : false; - if($this->gitlab->isDisplay($gitlab, 'manageGroupMembers')) common::printLink('gitlab', 'manageGroupMembers', "gitlabID=$gitlabID&groupID=$gitlabGroup->id", " ", '',"title='{$lang->gitlab->group->manageMembers}' class='btn'"); - if($this->gitlab->isDisplay($gitlab, 'editGroup')) echo common::buildIconButton('gitlab', 'editGroup', "gitlabID=$gitlabID&groupID=$gitlabGroup->id", '', 'list', 'edit', '', '', false, '', '', 0, $isAdmin); - if($this->gitlab->isDisplay($gitlab, 'deleteGroup')) echo common::buildIconButton('gitlab', 'deleteGroup', "gitlabID=$gitlabID&groupID=$gitlabGroup->id", '', 'list', 'trash', 'hiddenwin', '', false, '', '', 0, $isAdmin); - ?> -
      -
      -
      - - diff --git a/module/gitlab/view/browseproject.html.php b/module/gitlab/view/browseproject.html.php deleted file mode 100644 index 3c7e2725c7..0000000000 --- a/module/gitlab/view/browseproject.html.php +++ /dev/null @@ -1,89 +0,0 @@ - - * @package gitlab - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -recTotal}&recPerPage={$pager->recPerPage}&pageID=1")?> - - - -
      -

      - noData;?> - - createLink('gitlab', 'createProject', "gitlabID=$gitlabID"), " " . $lang->gitlab->project->create, '', "class='btn btn-info'");?> - -

      -
      - -
      -
      - - recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?> - - - - - - - - - - - $gitlabProject): ?> - - - - - - - - - -
      gitlab->id);?>gitlab->project->name);?>gitlab->lastUpdate;?>actions;?>
      id;?>name_with_namespace;?> - star_count;?> - forks_count;?> - last_activity_at, 0, 10);?> - id]) ? '' : 'disabled'; - $maintainerClass = $gitlabProject->isMaintainer ? '' : 'disabled'; - $developerClass = $gitlabProject->isDeveloper ? '' : 'disabled'; - - $defaultBranchClass = $gitlabProject->adminer || $gitlabProject->isMaintainer ? '' : 'disabled'; - if($this->gitlab->isDisplay($gitlab, 'browseBranch')) echo common::printIcon('gitlab', 'browseBranch', "gitlabID=$gitlabID&projectID=$gitlabProject->id", '', 'list', 'treemap', '', $developerClass, false, '', $this->lang->gitlab->browseBranch); - if($this->gitlab->isDisplay($gitlab, 'browseTag')) echo common::printIcon('gitlab', 'browseTag', "gitlabID=$gitlabID&projectID=$gitlabProject->id", '', 'list', 'tag', '', $developerClass, false, '', $this->lang->gitlab->browseTag); - if($this->gitlab->isDisplay($gitlab, 'manageBranchPriv')) echo common::printIcon('gitlab', 'manageBranchPriv', "gitlabID=$gitlabID&projectID=$gitlabProject->id", '', 'list', 'branch-lock', '', $defaultBranchClass, false, '', $this->lang->gitlab->browseBranchPriv); - if($this->gitlab->isDisplay($gitlab, 'manageTagPriv')) echo common::printIcon('gitlab', 'manageTagPriv', "gitlabID=$gitlabID&projectID=$gitlabProject->id", '', 'list', 'tag-lock', '', $defaultBranchClass, false, '', $this->lang->gitlab->browseTagPriv); - if($this->gitlab->isDisplay($gitlab, 'manageProjectMembers')) echo common::printIcon('gitlab', 'manageProjectMembers', 'repoID=' . zget($repoPairs, $gitlabProject->id), '', 'list', 'team', '', $hasRepoClass); - if($this->gitlab->isDisplay($gitlab, 'createWebhook')) echo common::printIcon('gitlab', 'createWebhook', 'repoID=' . zget($repoPairs, $gitlabProject->id), '', 'list', 'change', 'hiddenwin', $hasRepoClass); - if($this->gitlab->isDisplay($gitlab, 'importIssue')) echo common::printIcon('gitlab', 'importIssue', "gitlabID=$gitlabID&projectID=$gitlabProject->id", '', 'list', 'link'); - if($this->gitlab->isDisplay($gitlab, 'editProject')) echo common::printIcon('gitlab', 'editProject', "gitlabID=$gitlabID&projectID=$gitlabProject->id", '', 'list', 'edit', '', $defaultBranchClass); - if($this->gitlab->isDisplay($gitlab, 'deleteProject')) echo common::printIcon('gitlab', 'deleteProject', "gitlabID=$gitlabID&projectID=$gitlabProject->id", '', 'list', 'trash', 'hiddenwin', $defaultBranchClass); - ?> -
      - - - -
      -
      - - diff --git a/module/gitlab/view/browsetag.html.php b/module/gitlab/view/browsetag.html.php deleted file mode 100644 index 2733313891..0000000000 --- a/module/gitlab/view/browsetag.html.php +++ /dev/null @@ -1,86 +0,0 @@ - - * @package gitlab - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -recTotal}&recPerPage={$pager->recPerPage}&pageID=1")?> - - - -
      -

      - noData;?> - - createLink('gitlab', 'createTag', "gitlabID=$gitlabID&projectID=$projectID"), " " . $lang->gitlab->createTag, '', "class='btn btn-info'");?> - -

      -
      - -
      -
      - - recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?> - - - - - - - - - - $gitlabTag): ?> - - - - - - - - -
      gitlab->tag->name);?>gitlab->tag->lastCommitter;?>gitlab->tag->lastCommittedDate);?>actions;?>
      -
      - name;?> - protected) echo '' . $lang->gitlab->tag->protected . '';?> -
      -
      lastCommitter;?>updated?> - name)); - $isDisabled = $gitlabTag->protected ? 'disabled' : ''; - common::printLink('gitlab', 'deleteTag', "gitlabID=$gitlabID&projectID={$projectID}&tag_name=$tagName", " ", '', "title='{$lang->gitlab->deleteTag}' class='btn' target='hiddenwin' $isDisabled"); - ?> -
      - - - -
      -
      - - diff --git a/module/gitlab/view/browseuser.html.php b/module/gitlab/view/browseuser.html.php deleted file mode 100644 index 1367d9d5c3..0000000000 --- a/module/gitlab/view/browseuser.html.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @package gitlab - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - - -
      -

      - noData;?> - createLink('gitlab', 'createProject', "gitlabID=$gitlabID"), " " . $lang->gitlab->user->create, '', "class='btn btn-info'");?> -

      -
      - -
      -
      - - - - - - - - - - - - - - $gitlabUser): ?> - - - - - - - - - - -
      gitlab->user->id);?>gitlab->user->name);?>gitlab->user->createOn;?>gitlab->user->lastActivity;?>actions;?>
      id;?>avatar, "height=40");?> - realname;?> - account . " <" . $gitlabUser->email . ">";?> - createdAt, 0, 10);?>lastActivityOn, 0, 10);?> - id", '', 'list', 'edit', '', '', false, '', '', 0, $isAdmin); - echo common::buildIconButton('gitlab', 'deleteUser', "gitlabID=$gitlabID&userID=$gitlabUser->id", '', 'list', 'trash', 'hiddenwin', '', false, '', '', 0, $isAdmin); - ?> -
      -
      -
      - - diff --git a/module/gitlab/view/create.html.php b/module/gitlab/view/create.html.php deleted file mode 100644 index a8eb11983e..0000000000 --- a/module/gitlab/view/create.html.php +++ /dev/null @@ -1,46 +0,0 @@ - - * @package gitlab - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -
      -
      -
      -
      -

      gitlab->lblCreate;?>

      -
      -
      - - - - - - - - - - - - - - - - -
      gitlab->name;?>gitlab->placeholder->name}'");?>
      gitlab->url;?>gitlab->placeholder->url}'");?>
      gitlab->token;?>gitlab->placeholder->token}'");?>
      - - goback, '', 'class="btn btn-wide"');?> -
      -
      -
      -
      -
      - diff --git a/module/gitlab/view/createbranch.html.php b/module/gitlab/view/createbranch.html.php deleted file mode 100644 index 63e332b3ea..0000000000 --- a/module/gitlab/view/createbranch.html.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @package gitlab - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
      -
      -
      -
      -

      gitlab->createBranch;?>

      -
      -
      - - - - - - - - - - - - - - -
      gitlab->branch->name;?>
      gitlab->branch->from;?>
      - - session->gitlabBranchList ? $this->session->gitlabBranchList : inlink('browseBranch', "gitlibID=$gitlabID&projectID=$projectID");?> - goback, '', 'class="btn btn-wide"');?> -
      -
      -
      -
      -
      - diff --git a/module/gitlab/view/creategroup.html.php b/module/gitlab/view/creategroup.html.php deleted file mode 100644 index 8a4e68d23e..0000000000 --- a/module/gitlab/view/creategroup.html.php +++ /dev/null @@ -1,82 +0,0 @@ - - * @package gitlab - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -" . $lang->gitlab->group->publicTip . '';?> - -
      -
      -
      -
      -

      gitlab->group->create;?>

      -
      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      gitlab->group->name;?>gitlab->group->name}'");?>
      gitlab->group->path;?> -
      - url . '/';?> - gitlab->group->path}'");?> -
      -
      gitlab->group->description;?>gitlab->group->description}'");?>
      gitlab->group->visibility;?>gitlab->group->visibilityList, 'private', "", 'block'));?>
      gitlab->group->permission;?> -
      - -
      -
      gitlab->group->lfsEnabled;?> -
      - -
      -
      gitlab->group->projectCreationLevel;?>gitlab->group->projectCreationLevelList, 'developer', "class='form-control'");?>
      gitlab->group->subgroupCreationLevel;?>gitlab->group->subgroupCreationLevelList, 'maintainer', "class='form-control'");?>
      - - goback, '', 'class="btn btn-wide"');?> -
      -
      -
      -
      -
      - diff --git a/module/gitlab/view/createproject.html.php b/module/gitlab/view/createproject.html.php deleted file mode 100644 index ed5f37fd72..0000000000 --- a/module/gitlab/view/createproject.html.php +++ /dev/null @@ -1,65 +0,0 @@ - - * @package gitlab - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -" . $lang->gitlab->project->publicTip . '';?> - -
      -
      -
      -
      -

      gitlab->project->create;?>

      -
      -
      - - - - - - - - - - - - - - - - - - - - - - - - - -
      gitlab->project->name;?>gitlab->project->name}'");?>
      gitlab->project->url;?> -
      - - url . '/' . $user->username . '/', "class='form-control' disabled");?> - - url . '/';?> - username, "class='form-control'");?> - -
      -
      gitlab->project->path;?>gitlab->placeholder->projectPath}'");?>
      gitlab->project->description;?>gitlab->project->description}'");?>
      gitlab->project->visibility;?>gitlab->project->visibilityList, 'private', "", 'block'));?>
      - - goback, '', 'class="btn btn-wide"');?> -
      -
      -
      -
      -
      - diff --git a/module/gitlab/view/createtag.html.php b/module/gitlab/view/createtag.html.php deleted file mode 100644 index 34d2a82b1b..0000000000 --- a/module/gitlab/view/createtag.html.php +++ /dev/null @@ -1,46 +0,0 @@ - - * @package gitlab - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
      -
      -
      -
      -

      gitlab->createTag;?>

      -
      -
      - - - - - - - - - - - - - - - - - -
      gitlab->tag->name;?>
      gitlab->tag->ref;?>
      gitlab->tag->message;?>
      - - goback, '', 'class="btn btn-wide"');?> -
      -
      -
      -
      -
      - diff --git a/module/gitlab/view/createuser.html.php b/module/gitlab/view/createuser.html.php deleted file mode 100644 index 54a9f6c1a1..0000000000 --- a/module/gitlab/view/createuser.html.php +++ /dev/null @@ -1,94 +0,0 @@ - - * @package gitlab - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -
      -
      -
      -
      -

      gitlab->user->create;?>

      -
      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      gitlab->user->bind;?>
      gitlab->user->name;?>gitlab->user->name}'");?>
      gitlab->user->username;?>gitlab->user->username}'");?>
      gitlab->user->email;?>gitlab->user->email}'");?>
      gitlab->user->password;?>gitlab->user->password}'");?>
      gitlab->user->passwordRepeat;?>gitlab->user->passwordRepeat}'");?>
      gitlab->user->canCreateGroup;?> -
      - -
      -
      gitlab->user->external;?> -
      - -
      -
      gitlab->user->avatar;?> -
      - $defaultTheme . 'images/repo/avatar.jpeg', 'account'=>''), 50); ?> - - ', '', "class='btn-avatar' id='avatarUploadBtn' data-toggle='tooltip' data-container='body' data-placement='bottom' title='{$lang->gitlab->user->avatar}'");?> -
      -
      - - goback, '', 'class="btn btn-wide"');?> -
      -
      -
      -
      -
      - diff --git a/module/gitlab/view/edit.html.php b/module/gitlab/view/edit.html.php deleted file mode 100644 index f97de0c63f..0000000000 --- a/module/gitlab/view/edit.html.php +++ /dev/null @@ -1,46 +0,0 @@ - - * @package gitlab - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
      -
      -
      -
      -

      gitlab->edit;?>

      -
      -
      - - - - - - - - - - - - - - - - - -
      gitlab->name;?>name) ? $gitlab->name : '', "class='form-control' placeholder='{$lang->gitlab->placeholder->name}'");?>
      gitlab->url;?>url) ? $gitlab->url : '', "class='form-control' placeholder='{$lang->gitlab->placeholder->url}'");?>
      gitlab->token;?>token) ? $gitlab->token : '', "class='form-control' placeholder='{$lang->gitlab->placeholder->token}'");?>
      - - goback, '', 'class="btn btn-wide"');?> -
      -
      -
      -
      -
      - diff --git a/module/gitlab/view/editgroup.html.php b/module/gitlab/view/editgroup.html.php deleted file mode 100644 index 3c699d392b..0000000000 --- a/module/gitlab/view/editgroup.html.php +++ /dev/null @@ -1,85 +0,0 @@ - - * @package gitlab - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -" . $lang->gitlab->group->publicTip . '';?> - -visibility);?> -
      -
      -
      -
      -

      gitlab->group->edit;?>

      -
      -
      - id);?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      gitlab->group->name;?>name, "class='form-control' placeholder='{$lang->gitlab->group->name}'");?>
      gitlab->group->path;?> -
      - url . '/';?> - path, "readonly class='form-control' placeholder='{$lang->gitlab->group->path}'");?> -
      - -
      gitlab->group->description;?>description, "rows='4' class='form-control' placeholder='{$lang->gitlab->group->description}'");?>
      gitlab->group->visibility;?>gitlab->group->visibilityList, $group->visibility, "", 'block'));?>
      -
      - request_access_enabled) echo 'checked';?> /> -
      -
      gitlab->group->lfsEnabled;?> -
      - lfs_enabled) echo 'checked';?> /> -
      -
      gitlab->group->projectCreationLevel;?>gitlab->group->projectCreationLevelList, $group->project_creation_level, "class='form-control'");?>
      gitlab->group->subgroupCreationLevel;?>gitlab->group->subgroupCreationLevelList, $group->subgroup_creation_level, "class='form-control'");?>
      - - goback, '', 'class="btn btn-wide"');?> -
      -
      -
      -
      -
      - diff --git a/module/gitlab/view/editproject.html.php b/module/gitlab/view/editproject.html.php deleted file mode 100644 index dec7d95b16..0000000000 --- a/module/gitlab/view/editproject.html.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @package gitlab - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -" . $lang->gitlab->project->publicTip . '';?> - -visibility);?> -
      -
      -
      -
      -

      gitlab->project->edit;?>

      -
      -
      - - - - - - - - - - - - - - - - - - - - - -
      gitlab->project->id;?>id, "class='form-control' readonly placeholder='{$lang->gitlab->project->id}'");?>
      gitlab->project->name;?>name, "class='form-control' placeholder='{$lang->gitlab->project->name}'");?>
      gitlab->project->description;?>description, "rows='10' class='form-control' placeholder='{$lang->gitlab->project->description}'");?>
      gitlab->project->visibility;?>gitlab->project->visibilityList, $project->visibility, "", 'block'));?>
      - - goback, '', 'class="btn btn-wide"');?> -
      -
      -
      -
      -
      - diff --git a/module/gitlab/view/edituser.html.php b/module/gitlab/view/edituser.html.php deleted file mode 100644 index e7f075e3b7..0000000000 --- a/module/gitlab/view/edituser.html.php +++ /dev/null @@ -1,94 +0,0 @@ - - * @package gitlab - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
      -
      -
      -
      -

      gitlab->user->edit;?>

      -
      -
      - id);?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      gitlab->user->bind;?>
      gitlab->user->name;?>name, "class='form-control' placeholder='{$lang->gitlab->user->name}'");?>
      gitlab->user->username;?>username, "readonly class='form-control' placeholder='{$lang->gitlab->user->username}'");?>
      gitlab->user->email;?>email, "class='form-control' placeholder='{$lang->gitlab->user->email}'");?>
      gitlab->user->password;?>gitlab->user->password}'");?>
      gitlab->user->passwordRepeat;?>gitlab->user->passwordRepeat}'");?>
      gitlab->user->canCreateGroup;?> -
      - can_create_group) echo 'checked';?> /> -
      -
      gitlab->user->external;?> -
      - external) echo 'checked';?> /> -
      -
      gitlab->user->avatar;?> -
      - $user->avatar_url ? $user->avatar_url : $defaultTheme . 'images/repo/avatar.jpeg', 'account'=>''), 50); ?> - - ', '', "class='btn-avatar' id='avatarUploadBtn' data-toggle='tooltip' data-container='body' data-placement='bottom' title='{$lang->gitlab->user->avatar}'");?> -
      -
      - - goback, '', 'class="btn btn-wide"');?> -
      -
      -
      -
      -
      - diff --git a/module/gitlab/view/importissue.html.php b/module/gitlab/view/importissue.html.php deleted file mode 100644 index 5bf04a6fb3..0000000000 --- a/module/gitlab/view/importissue.html.php +++ /dev/null @@ -1,65 +0,0 @@ - - * @package story - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -
      -
      -

      gitlab->importIssue;?>

      - -
      - goback, "data-app='{$app->tab}'", 'btn btn-primary');?> -
      - -
      - -
      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - -
      gitlab->gitlabIssue;?>gitlab->objectType;?>productCommon;?>execution->common;?>
      web_url}' target='_blank'>$issue->title";?>iid}]", $objectTypes, '', "class='form-control select chosen'" );?>iid}]", $products, '', "class='form-control select chosen'" );?>iid}]", '', '', "class='form-control select chosen'" );?>
      - save);?> - goback, "data-app='{$app->tab}'", 'btn btn-wide');?> -
      -
      -
      - - gitlab->noImportableIssues;?> - -
      - diff --git a/module/gitlab/view/managebranchpriv.html.php b/module/gitlab/view/managebranchpriv.html.php deleted file mode 100644 index 52ea2da2e4..0000000000 --- a/module/gitlab/view/managebranchpriv.html.php +++ /dev/null @@ -1,82 +0,0 @@ - - -
      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      gitlab->branch->name;?>gitlab->branch->mergeAllowed;?>gitlab->branch->pushAllowed;?>actions;?>
      name, "class='form-control' readonly");?>gitlab->branch->branchCreationLevelList, $branch->mergeAccess, "class='form-control user-picker'");?> - gitlab->branch->branchCreationLevelList, $branch->pushAccess, "class='form-control user-picker'");?> - name);?> - - ", '', "onclick='addItem(this)' class='btn btn-link'");?> - ", '', "onclick='deleteItem(this)' class='btn btn-link'");?> -
      '') + $noAccessBranches, '', "class='form-control user-picker'");?>gitlab->branch->branchCreationLevelList, 40, "class='form-control user-picker'");?>gitlab->branch->branchCreationLevelList, 40, "class='form-control user-picker'");?> - ", '', "onclick='addItem(this)' class='btn btn-link'");?> - ", '', "onclick='deleteItem(this)' class='btn btn-link'");?> -
      - save, 'onclick="savePriv()" id="saveBtn"', 'btn btn-wide btn-primary'); - echo html::backButton(); - ?> -
      - -
      -
      -
      - - - - - - - - - -
      - diff --git a/module/gitlab/view/managegroupmembers.html.php b/module/gitlab/view/managegroupmembers.html.php deleted file mode 100644 index 08d5891c51..0000000000 --- a/module/gitlab/view/managegroupmembers.html.php +++ /dev/null @@ -1,88 +0,0 @@ - - - -
      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      gitlab->group->memberName;?>gitlab->group->memberAccessLevel;?>gitlab->group->memberExpiresAt;?>actions;?>
      name, "class='form-control' readonly");?>'') + $this->lang->gitlab->accessLevels, $member->access_level, "class='form-control chosen'");?> - access_level == $ownerLevel):?> - - expires_at, "class='form-control form-date hidden'");?> - - expires_at, "class='form-control form-date'");?> - - id);?> - - ", '', "onclick='addItem(this)' class='btn btn-link'");?> - ", '', "onclick='deleteItem(this)' class='btn btn-link" . ($member->access_level == $ownerLevel ? ' disabled' : '') . "'");?> -
      '') + $this->lang->gitlab->accessLevels, '', "class='form-control chosen'");?> - ", '', "onclick='addItem(this)' class='btn btn-link'");?> - ", '', "onclick='deleteItem(this)' class='btn btn-link'");?> -
      - save, 'onclick="saveMembers()" id="saveBtn"', 'btn btn-wide btn-primary'); - - echo html::backButton(); - ?> -
      - -
      -
      -
      - - - - - - - - - -
      - diff --git a/module/gitlab/view/manageprojectmembers.html.php b/module/gitlab/view/manageprojectmembers.html.php deleted file mode 100644 index 5834907a8a..0000000000 --- a/module/gitlab/view/manageprojectmembers.html.php +++ /dev/null @@ -1,85 +0,0 @@ - - -
      -
      - - - - - - - - - - - - - - acl->users)):?> - acl->users as $user):?> - - - - - - - - - - - - - - - - - - - - - - - - - -
      gitlab->group->memberName;?>gitlab->group->memberAccessLevel;?>gitlab->group->memberExpiresAt;?>actions;?>
      '') + $this->lang->gitlab->accessLevels, isset($userAccessData[$user]) ? $userAccessData[$user]->access_level : '', "class='form-control chosen'");?> - expires_at : '', "class='form-control form-date'");?> - - - ", '', "onclick='addItem(this)' class='btn btn-link'");?> - ", '', "onclick='deleteItem(this)' class='btn btn-link'");?> -
      '') +$users, '', "class='form-control chosen'");?>'') + $this->lang->gitlab->accessLevels, '', "class='form-control chosen'");?> - ", '', "onclick='addItem(this)' class='btn btn-link'");?> - ", '', "onclick='deleteItem(this)' class='btn btn-link'");?> -
      - save, 'onclick="saveMembers()" id="saveBtn"', 'btn btn-wide btn-primary'); - - echo html::backButton(); - ?> -
      - -
      -
      -
      - - - - - - - - - -
      - diff --git a/module/gitlab/view/managetagpriv.html.php b/module/gitlab/view/managetagpriv.html.php deleted file mode 100644 index 58a3c63c96..0000000000 --- a/module/gitlab/view/managetagpriv.html.php +++ /dev/null @@ -1,76 +0,0 @@ - - -
      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      gitlab->tag->name;?>gitlab->tag->accessLevel;?>actions;?>
      name, "class='form-control' readonly");?>gitlab->branch->branchCreationLevelList, $tag->createAccess, "class='form-control user-picker'");?> - name);?> - ", '', "onclick='addItem(this)' class='btn btn-link'");?> - ", '', "onclick='deleteItem(this)' class='btn btn-link'");?> -
      '') + $noAccessTags, '', "class='form-control user-picker'");?>gitlab->branch->branchCreationLevelList, 40, "class='form-control user-picker'");?> - ", '', "onclick='addItem(this)' class='btn btn-link'");?> - ", '', "onclick='deleteItem(this)' class='btn btn-link'");?> -
      - save, 'onclick="savePriv()" id="saveBtn"', 'btn btn-wide btn-primary'); - echo html::backButton(); - ?> -
      - -
      -
      -
      - - - - - - - - -
      - diff --git a/module/gitlab/view/view.html.php b/module/gitlab/view/view.html.php deleted file mode 100644 index d5918290a7..0000000000 --- a/module/gitlab/view/view.html.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @package GitLab - * @version $Id: view.html.php 4728 2013-05-03 06:14:34Z david18810279601@gmail.com $ - * @link https://www.zentao.net - * */ -?> - - - - -
      -
      -
      -
      -
      gitlab->url;?>
      -
      url, $gitlab->url, '_target');?>
      -
      -
      -
      -
      -
      - diff --git a/module/gogs/view/binduser.html.php b/module/gogs/view/binduser.html.php deleted file mode 100644 index e1b13cc4a5..0000000000 --- a/module/gogs/view/binduser.html.php +++ /dev/null @@ -1,99 +0,0 @@ - - * @package gogs - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -createLink('gogs', 'browse', ""); ?> - -
      -
      - ' . $lang->goback, $browseLink, 'self', "data-app='{$app->tab}'", 'btn btn-secondary'); - - $allLink = $this->createLink('gogs', 'binduser', "gogsID={$gogsID}&type=all"); - $bindedLink = $this->createLink('gogs', 'binduser', "gogsID={$gogsID}&type=binded"); - $notBindLink = $this->createLink('gogs', 'binduser', "gogsID={$gogsID}&type=notBind"); - if($type == 'all') - { - echo html::linkButton('' . $lang->gogs->all . "" . count($gogsUsers) . "", $allLink, 'self', "data-app='{$app->tab}'", 'btn btn-info active'); - echo html::linkButton('' . $lang->gogs->notBind, $notBindLink, 'self', "data-app='{$app->tab}'", 'btn btn-info'); - echo html::linkButton('' . $lang->gogs->binded, $bindedLink, 'self', "data-app='{$app->tab}'", 'btn btn-info'); - } - else if($type == 'binded') - { - echo html::linkButton('' . $lang->gogs->all, $allLink, 'self', "data-app='{$app->tab}'", 'btn btn-info'); - echo html::linkButton('' . $lang->gogs->notBind, $notBindLink, 'self', "data-app='{$app->tab}'", 'btn btn-info'); - echo html::linkButton('' . $lang->gogs->binded . "" . count($gogsUsers) . "", $bindedLink, 'self', "data-app='{$app->tab}'", 'btn btn-info active'); - } - else - { - echo html::linkButton('' . $lang->gogs->all, $allLink, 'self', "data-app='{$app->tab}'", 'btn btn-info'); - echo html::linkButton('' . $lang->gogs->notBind . "" . count($gogsUsers) . "", $notBindLink, 'self', "data-app='{$app->tab}'", 'btn btn-info active'); - echo html::linkButton('' . $lang->gogs->binded, $bindedLink, 'self', "data-app='{$app->tab}'", 'btn btn-info'); - } - ?> -
      -
      -
      - - - - - - - - - - - - - id]", $gogsUser->realname);?> - - - - - - - - - - - - - - -
      gogs->gogsAccount;?>gogs->gogsEmail;?>gogs->zentaoEmail;?>gogs->zentaoAccount;?> gogs->bindingStatus;?>
      - avatar, "height=20 width=20 class='img-circle'");?> - realname . '@' . $gogsUser->account;?> - email;?>id]", $gogsUser->zentaoUsers, $gogsUser->zentaoAccount, "class='form-control select chosen gogs-user-bind'" );?> - binded === 1):?> - gogs->binded;?> - binded === 2):?> - ' . $lang->gogs->bindedError . '';?> - - ' . $lang->gogs->notBind . '';?> - -
      - - createLink('space', 'browse'), $lang->goback, '', 'class="btn btn-wide"');?> -
      -
      -
      -
      - - diff --git a/module/gogs/view/browse.html.php b/module/gogs/view/browse.html.php deleted file mode 100644 index 9ac83d4ccf..0000000000 --- a/module/gogs/view/browse.html.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @package gogs - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - - -
      -

      - noData;?> - - createLink('gogs', 'create'), " " . $lang->gogs->create, '', "class='btn btn-info'");?> - -

      -
      - -
      -
      - - - - recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?> - - - - - - - - $gogs): ?> - - - - - - - - -
      gogs->id);?>gogs->name);?>gogs->url);?>actions;?>
      - - ">name;?> - - name;?> - - url, $gogs->url, '_target');?> - isBindUser); - common::printIcon('gogs', 'delete', "gogsID=$id", '', 'list', 'trash', 'hiddenwin'); - ?> -
      - - - -
      -
      - - diff --git a/module/gogs/view/create.html.php b/module/gogs/view/create.html.php deleted file mode 100644 index 36481017b9..0000000000 --- a/module/gogs/view/create.html.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @package gogs - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
      -
      -
      -
      -

      gogs->lblCreate;?>

      -
      -
      - - - - - - - - - - - - - - - - -
      gogs->name;?>
      gogs->url;?>
      gogs->token;?>
      - -
      -
      -
      -
      -
      - diff --git a/module/gogs/view/edit.html.php b/module/gogs/view/edit.html.php deleted file mode 100644 index 2488764482..0000000000 --- a/module/gogs/view/edit.html.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @package gogs - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
      -
      -
      -
      -

      gogs->edit;?>

      -
      -
      - - - - - - - - - - - - - - - - - -
      gogs->name;?>name) ? $gogs->name : '', "class='form-control'");?>
      gogs->url;?>url) ? $gogs->url : '', "class='form-control'");?>
      gogs->token;?>token) ? $gogs->token : '', "class='form-control'");?>
      - -
      -
      -
      -
      -
      - diff --git a/module/gogs/view/view.html.php b/module/gogs/view/view.html.php deleted file mode 100644 index 1c2e526b39..0000000000 --- a/module/gogs/view/view.html.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @package GitLab - * @version $Id: view.html.php 4728 2013-05-03 06:14:34Z david18810279601@gmail.com $ - * @link https://www.zentao.net - * */ -?> - - - -
      -
      -
      -
      -
      gogs->url;?>
      -
      url, $gogs->url, '_target');?>
      -
      -
      -
      -
      -
      - diff --git a/module/group/packagemanager.php b/module/group/packagemanager.php index 306688b082..12f139bbae 100644 --- a/module/group/packagemanager.php +++ b/module/group/packagemanager.php @@ -237,13 +237,13 @@ $config->group->subset->testreport = new stdclass(); $config->group->subset->testreport->order = 710; $config->group->subset->testreport->nav = 'qa'; -$config->group->subset->autotest = new stdclass(); -$config->group->subset->autotest->order = 715; -$config->group->subset->autotest->nav = 'qa'; - $config->group->subset->caselib = new stdclass(); -$config->group->subset->caselib->order = 740; -$config->group->subset->caselib->nav = 'assetlib'; +$config->group->subset->caselib->order = 715; +$config->group->subset->caselib->nav = 'qa'; + +$config->group->subset->autotest = new stdclass(); +$config->group->subset->autotest->order = 720; +$config->group->subset->autotest->nav = 'qa'; $config->group->subset->storylib = new stdclass(); $config->group->subset->storylib->order = 760; @@ -3660,7 +3660,7 @@ $config->group->package->manageDoc->privs['doc-createSpace'] = array('edition' $config->group->package->manageDoc->privs['doc-createLib'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd,lite,or', 'order' => 0, 'depend' => array('doc-index'), 'recommend' => array('doc-editLib', 'doc-moveLib', 'doc-sortDoclib')); $config->group->package->manageDoc->privs['doc-editSpace'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd,lite,or', 'order' => 1, 'depend' => array('doc-index'), 'recommend' => array('doc-createSpace', 'doc-deleteSpace')); $config->group->package->manageDoc->privs['doc-editLib'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd,lite,or', 'order' => 1, 'depend' => array('doc-index'), 'recommend' => array('doc-createLib', 'doc-moveLib', 'doc-sortDoclib')); -$config->group->package->manageDoc->privs['doc-create'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd,lite,or', 'order' => 3, 'depend' => array('doc-index'), 'recommend' => array('doc-edit', 'doc-moveDoc', 'doc-sortDoc')); +$config->group->package->manageDoc->privs['doc-create'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd,lite,or', 'order' => 3, 'depend' => array('doc-index', 'doc-edit'), 'recommend' => array('doc-moveDoc', 'doc-sortDoc')); $config->group->package->manageDoc->privs['doc-edit'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd,lite,or', 'order' => 4, 'depend' => array('doc-index'), 'recommend' => array('doc-create', 'doc-moveDoc', 'doc-sortDoc')); $config->group->package->manageDoc->privs['doc-collect'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd,lite,or', 'order' => 8, 'depend' => array('doc-index'), 'recommend' => array('doc-create', 'doc-edit')); $config->group->package->manageDoc->privs['doc-showFiles'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd,lite,or', 'order' => 2, 'depend' => array('doc-index'), 'recommend' => array('doc-createLib', 'doc-editLib')); diff --git a/module/group/view/browse.html.php b/module/group/view/browse.html.php deleted file mode 100644 index eac40f2bc3..0000000000 --- a/module/group/view/browse.html.php +++ /dev/null @@ -1,83 +0,0 @@ - - * @package group - * @version $Id: browse.html.php 4769 2013-05-05 07:24:21Z wwccss $ - * @link https://www.zentao.net - */ -?> - - -group->confirmDelete);?> - -
      - - - - - - - - - - - - - id]);?> - - - - - - - - - -
      group->id;?>group->name;?>group->desc;?>group->users;?>actions;?>
      id;?>name;?>desc;?> - group->managepriv = $lang->group->managePrivByGroup;?> - group->managemember = $lang->group->manageMember;?> - role == 'projectAdmin';?> - - ";?> - ";?> - id", $group, 'list', 'persons');?> - ";?> - ";?> - - id", $group, 'list', 'eye');?> - id", $group, 'list', 'lock');?> - id", $group, 'list', 'persons', '', "iframe", true, "data-width='90%'");?> - id", $group, 'list', '', '', "iframe", true, "data-width='550'");?> - id", $group, 'list', '', '', "iframe", true, "data-width='550'");?> - - "; - } - else - { - $deleteURL = $this->createLink('group', 'delete', "groupID=$group->id&confirm=yes"); - $confirmDelete = htmlspecialchars(sprintf($lang->group->confirmDelete, $group->name)); - echo html::a("javascript:ajaxDelete(\"$deleteURL\", \"groupList\", \"$confirmDelete\")", '', '', "title='{$lang->group->delete}' class='btn'"); - } - } - ?> -
      -
      - diff --git a/module/group/view/copy.html.php b/module/group/view/copy.html.php deleted file mode 100644 index ddaafa5b46..0000000000 --- a/module/group/view/copy.html.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @package group - * @version $Id: copy.html.php 4129 2013-01-18 01:58:14Z wwccss $ - * @link https://www.zentao.net - */ -?> - -
      -
      -

      group->copy;?>

      -
      -
      - - - - - - - - - - - - - - - - -
      group->name;?>name, "class='form-control'");?>
      group->desc;?>desc, "rows='5' class='form-control'");?>
      group->option;?>group->copyOptions, '', '', 'inline');?>
      -
      -
      - diff --git a/module/group/view/create.html.php b/module/group/view/create.html.php deleted file mode 100644 index 2dce06320c..0000000000 --- a/module/group/view/create.html.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @package group - * @version $Id: create.html.php 4129 2013-01-18 01:58:14Z wwccss $ - * @link https://www.zentao.net - */ -?> - -
      -
      -

      group->create;?>

      -
      -
      - - - - - - - - - - app->tab != 'project'):?> - - - - - - - - -
      group->name;?>
      group->desc;?>
      group->limited;?>
      -
      -
      - diff --git a/module/group/view/edit.html.php b/module/group/view/edit.html.php deleted file mode 100644 index 6b7b2d5086..0000000000 --- a/module/group/view/edit.html.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @package group - * @version $Id: edit.html.php 4129 2013-01-18 01:58:14Z wwccss $ - * @link https://www.zentao.net - */ -?> - -
      -
      -

      - id;?> - name;?> - arrow . $lang->group->edit;?> -

      -
      -
      - - - - - - - - - - - - -
      group->name;?>name, "class='form-control'");?>
      group->desc;?>desc, "rows='5' class='form-control'");?>
      -
      -
      - diff --git a/module/group/view/managemember.html.php b/module/group/view/managemember.html.php deleted file mode 100644 index 417caf9f02..0000000000 --- a/module/group/view/managemember.html.php +++ /dev/null @@ -1,90 +0,0 @@ - - * @package group - * @version $Id: managemember.html.php 4627 2013-04-10 05:42:20Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - -
      -
      -

      - id;?> - name;?> -

      -
      -
      -
      -
      -
      -
      dept->common;?>
      - -
      -
      -
      -
      -
      - - - - - - - - - - - - - - - - - - - - -
      -
      - - -
      -
      - $realname):?> -
      $realname), $account);?>
      - -
      -
      - - -
      -
      - $realname):?> -
      $realname), '');?>
      - -
      -
      - - -
      -
      - $realname):?> -
      $realname), '');?>
      - -
      - goback, $this->createLink('group', 'browse')); - echo html::hidden('foo'); // Just a var, to make sure $_POST is not empty. - ?> -
      -
      -
      -
      -
      - diff --git a/module/group/view/managepriv.html.php b/module/group/view/managepriv.html.php deleted file mode 100644 index ca23217693..0000000000 --- a/module/group/view/managepriv.html.php +++ /dev/null @@ -1,18 +0,0 @@ - - * @package group - * @version $Id: managepriv.html.php 4129 2013-01-18 01:58:14Z wwccss $ - * @link https://www.zentao.net - */ -?> - - * @package group - * @version $Id: managemember.html.php 4627 2013-04-10 05:42:20Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - - -
      - -
      -
      -
      - - - - - - - - systemMode == 'ALM' ? '' : 'hidden';?> - systemMode == 'ALM' ? 4 : 3;?> - - $group):?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      group->inside;?>group->object;?>group->allCheck . " ";?>actions;?>
      -
      group][]", $allUsers, $account, "class='form-control picker-select' multiple");?>
      -
      -
      - programs == 'all' ? "disabled='disabled'" : '';?> - group->manageProgram;?> - group][]", $programs, $group->programs == 'all' ? '' : $group->programs, "class='form-control picker-select' multiple $disabled");?> -
      -
      - group]", array(1 => ''), $group->programs == 'all' ? 1 : '', "onchange=toggleDisabled(this);");?> - -
      - projects == 'all' ? "disabled='disabled'" : '';?> - group->manageProject;?> - group][]", $projects, $group->projects == 'all' ? '' : $group->projects, "class='form-control picker-select' multiple $disabled");?> -
      -
      - group]", array(1 => ''), $group->projects == 'all' ? 1 : '', "onchange=toggleDisabled(this);");?> - - - - -
      -
      - projects == 'all' ? "disabled='disabled'" : '';?> - group->manageProject;?> - group][]", $projects, $group->projects == 'all' ? '' : $group->projects, "class='form-control picker-select' multiple $disabled");?> -
      -
      - group]", array(1 => ''), $group->projects == 'all' ? 1 : '', "onchange=toggleDisabled(this);");?> -
      -
      - products == 'all' ? "disabled='disabled'" : '';?> - group->manageProduct;?> - group][]", $products, $group->products == 'all' ? '' : $group->products, "class='form-control picker-select' multiple $disabled");?> -
      -
      - group]", array(1 => ''), $group->products == 'all' ? 1 : '', "onchange=toggleDisabled(this);");?> -
      -
      - executions == 'all' ? "disabled='disabled'" : '';?> - group->manageExecution;?> - group][]", $executions, $group->executions == 'all' ? '' : $group->executions, "class='form-control picker-select' multiple $disabled");?> -
      -
      - group]", array(1 => ''), $group->executions == 'all' ? 1 : '', "onchange=toggleDisabled(this);");?> -
      -
      -
      -
      - group->manageProgram;?> - -
      -
      - ''), '', "onchange=toggleDisabled(this);");?> - -
      - group->manageProject;?> - -
      -
      - ''), '', "onchange=toggleDisabled(this);");?> - - - -
      -
      - group->manageProject;?> - -
      -
      - ''), '', "onchange=toggleDisabled(this);");?> -
      -
      - group->manageProduct;?> - -
      -
      - ''), '', "onchange=toggleDisabled(this);");?> -
      -
      - group->manageExecution;?> - -
      -
      - ''), '', "onchange=toggleDisabled(this);");?> -
      - goback, $this->createLink('group', 'browse'), 'self', '', 'btn btn-wide'); - echo html::hidden('foo'); // Just a var, to make sure $_POST is not empty. - ?> -
      -
      -
      -
      -
      - - - diff --git a/module/group/view/manageview.html.php b/module/group/view/manageview.html.php deleted file mode 100644 index e1ff583103..0000000000 --- a/module/group/view/manageview.html.php +++ /dev/null @@ -1,181 +0,0 @@ - - * @package group - * @version $Id: managepriv.html.php 1517 2011-03-07 10:02:57Z wwccss $ - * @link https://www.zentao.net - */ -?> - -
      -
      -

      - name;?> - arrow . $lang->group->manageView;?> -

      -
      -
      - - - - - - config->systemMode == 'ALM'):?> - - - - - - - - - - - - - - - - - - - - - - - - -
      group->viewList;?> - mainNav as $menuKey => $menu):?> - - - - -
      -
      - acl['views'][$menuKey]) or empty($group->acl['views'])) echo "checked";?> /> - -
      -
      - -
      -
      - acl['views'])) echo "checked";?> /> - -
      -
      -
      group->dynamic?> - - mainNav as $module => $title):?> - - action->dynamicAction->$module)) $isNullActions = false; - if(isset($navGroup[$module]) and $isNullActions) - { - foreach($navGroup[$module] as $subModule) - { - if(isset($lang->action->dynamicAction->$subModule)) - { - $isNullActions = false; - break; - } - } - } - if($isNullActions) continue; - ?> - - - - - -
      -
      -
      - - -
      -
      -
      - action->dynamicAction->$module)):?> -
      - action->dynamicAction->$module as $action => $actionTitle):?> -
      -
      - acl['actions'][$module][$action]) or !isset($group->acl['actions'])) echo "checked";?> /> - -
      -
      - -
      - - - - action->dynamicAction->$subModule)):?> -
      - action->dynamicAction->$subModule as $action => $actionTitle):?> -
      -
      - acl['actions'][$subModule][$action]) or !isset($group->acl['actions'])) echo "checked";?> /> - -
      -
      - -
      - - - -
      -
      - - - -
      -
      -
      - diff --git a/module/group/view/privbygroup.html.php b/module/group/view/privbygroup.html.php deleted file mode 100644 index 933e00c058..0000000000 --- a/module/group/view/privbygroup.html.php +++ /dev/null @@ -1,274 +0,0 @@ - - * @package group - * @version $Id: managepriv.html.php 1517 2011-03-07 10:02:57Z wwccss $ - * @link https://www.zentao.net - */ -?> -role == 'limited'):?> - -
      -
      - - - - - - - - '> - - - - - - - -
      group->module;?>group->method;?>
      my->common;?> -
      - /> - -
      -
      - - inlink('browse'), $lang->cancel, '', "class='btn btn-back btn-wide'");?> - -
      -
      -
      - - -
      -
      -
      -
      - ", '', "class='btn btn-icon switchBtn'");?> - ", '', "class='btn btn-icon switchBtn text-primary'");?> -
      - - - - - - - - - - $packages):?> - - - $privs):?> - '> - - - - - - $moduleName->menus)):?> - $moduleName->menus); - $menusSelect = count(array_intersect(array_keys($lang->$moduleName->menus), array_keys(zget($groupPrivs, $moduleName, array())))); - ?> - - - - - - - - -
      group->module;?>privpackage->common;?>group->method;?>
      -
      - > - $moduleName->common;?> - $moduleName->manage;?> - -
      -
      text-middle text-left package' data-module='' data-package='' all-privs='' select-privs=''> -
      - > - -
      -
      - $priv):?> - $moduleName->menus) and ($priv->method == 'browse' or in_array($priv->method, array_keys($lang->$moduleName->menus)))) continue;?> -
      '> -
      - module]", array($priv->method => $priv->name), isset($groupPrivs[$priv->module][$priv->method]) ? $priv->method : '', "title='{$priv->name}' id='actions[$priv->module]$priv->method' data-id='$priv->action'");?> -
      -
      - -
      -
      -
      -
      -
      - group->dependentPrivs;?> - -
      -
      - -
      -

      noData;?>

      -
      -
      -
      -
      -
      - group->recommendPrivs;?> - -
      -
      - -
      -

      noData;?>

      -
      -
      -
      -
      -
      - -
      - - - - - - - - diff --git a/module/group/view/privbymodule.html.php b/module/group/view/privbymodule.html.php deleted file mode 100644 index 3c04d25fc7..0000000000 --- a/module/group/view/privbymodule.html.php +++ /dev/null @@ -1,58 +0,0 @@ - - * @package group - * @version $Id: managepriv.html.php 1517 2011-03-07 10:02:57Z wwccss $ - * @link https://www.zentao.net - */ -?> -
      -
      -

      - group->managePriv ;?> - group->byModuleTips; ?> -

      -
      - -
      - - - - - - - - - - - - - - - - -
      group->module;?>privpackage->common;?>group->method;?>group->common;?>
      - $modulePackages) - { - echo html::select('packages[]', $modulePackages, '', "onclick='setActions()' multiple='multiple' class='form-control $hiddenClass' data-module='$module'"); - $hiddenClass = 'hidden'; - } - ?> - - -
      - - - -
      -
      -
      - - - diff --git a/module/group/view/privbypackage.html.php b/module/group/view/privbypackage.html.php deleted file mode 100644 index 264eeed71b..0000000000 --- a/module/group/view/privbypackage.html.php +++ /dev/null @@ -1,213 +0,0 @@ - - * @package group - * @version $Id: managepriv.html.php 1517 2011-03-07 10:02:57Z wwccss $ - * @link https://www.zentao.net - */ -?> -role == 'limited'):?> - -
      -
      - - - - - - - - '> - - - - - - - -
      group->module;?>group->method;?>
      my->common;?> -
      - /> - -
      -
      - - inlink('browse'), $lang->cancel, '', "class='btn btn-back btn-wide'");?> - -
      -
      -
      - - -
      -
      -
      -
      - ", '', "class='btn btn-icon switchBtn text-primary'");?> - ", '', "class='btn btn-icon switchBtn'");?> -
      - - - - - - - - - $packages):?> - - - '> - - - - - -
      group->module;?>privpackage->common;?>
      -
      - > - $moduleName->common;?> - $moduleName->manage;?> - -
      -
      - $privs):?> - -
      -
      - > - -
      - -
      - - -
      -
      -
      -
      -
      - group->dependentPrivs;?> - -
      -
      - -
      -

      noData;?>

      -
      -
      -
      -
      -
      - group->recommendPrivs;?> - -
      -
      - -
      -

      noData;?>

      -
      -
      -
      -
      -
      - -
      - - - - - - - diff --git a/module/holiday/view/browse.html.php b/module/holiday/view/browse.html.php deleted file mode 100644 index af1264a258..0000000000 --- a/module/holiday/view/browse.html.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @package holiday - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
      - -
      - - - > - - - - - - - - - - - - - - - - - - - -
      holiday->name;?>holiday->holiday;?>holiday->type;?>holiday->desc;?>actions;?>
      name;?>begin, DT_DATE1) . ' ~ ' . formatTime($holiday->end, DT_DATE1);?>holiday->typeList, $holiday->type);?>

      desc;?>

      - id", $holiday, 'list', '', '', 'iframe', 'yes');?> - id", $holiday, 'list', '', 'hiddenwin');?> -
      - = date('Y')):?> - - -
      -
      - diff --git a/module/holiday/view/create.html.php b/module/holiday/view/create.html.php deleted file mode 100644 index b53bee97b3..0000000000 --- a/module/holiday/view/create.html.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @package holiday - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -
      -
      -
      -

      - holiday->create;?> -

      -
      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      holiday->type;?>holiday->typeList, 'holiday');?>
      holiday->begin;?>
      holiday->end;?>
      holiday->name;?>
      holiday->desc?>
      -
      -
      -
      - diff --git a/module/holiday/view/edit.html.php b/module/holiday/view/edit.html.php deleted file mode 100644 index c546bb5e1b..0000000000 --- a/module/holiday/view/edit.html.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @package holiday - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -
      -
      -
      -

      - holiday->edit;?> -

      -
      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      holiday->type;?>holiday->typeList, $holiday->type);?>
      holiday->begin?>begin, "class='form-control form-date' required")?>
      holiday->end?>end, "class='form-control form-date' required")?>
      holiday->name?>name, "class='form-control' required")?>
      holiday->desc?>desc, "class='form-control'")?>
      -
      -
      -
      - diff --git a/module/holiday/view/import.html.php b/module/holiday/view/import.html.php deleted file mode 100644 index b00a85b26b..0000000000 --- a/module/holiday/view/import.html.php +++ /dev/null @@ -1,66 +0,0 @@ - - * @package holiday - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -
      -
      - -
      - - - - - - - - - - - - - - - -
      holiday->name;?>holiday->holiday;?>
      name;?>begin, DT_DATE1) . ' ~ ' . formatTime($holiday->end, DT_DATE1);?>
      - -
      - -
      -

      - holiday->emptyTip;?> -

      -
      - -
      -
      - - - - - diff --git a/module/host/view/browse.html.php b/module/host/view/browse.html.php deleted file mode 100644 index e8d252eee5..0000000000 --- a/module/host/view/browse.html.php +++ /dev/null @@ -1,126 +0,0 @@ - - * @package host - * @version $Id$ - * @link https://www.zentao.net - */ -?> -getModuleRoot() . 'common/view/header.html.php';?> -host->confirmDelete)?> - - -
      ' data-module='host'>
      - -
      - - -
      - -
      -

      - host->empty;?> - ' . $lang->host->create, '', 'class="btn btn-info"');?> -

      -
      - - - - - recTotal}&recPerPage={$pager->recPerPage}";?> - - - - - - - - - - - - - - - - - - - - - admin, "");?> - - - serverRoom, "");?> - - - - - - - - - -
      idAB);?> host->group);?>host->name);?>host->admin);?>host->serverRoom);?> host->intranet);?> host->extranet);?> host->osVersion);?> host->status);?> actions?>
      id);?>inlink('view', "id=$host->id", 'html', true), $host->name, '', "class='iframe'");?>createLink('account', 'view', "id=$host->admin", 'html', true), $accountName, '', "class='iframe'") : ''?>createLink('serverroom', 'view', "id=$host->serverRoom", 'html', true), $serverRoomName, '', "class='iframe'") : ''?>intranet;?>extranet;?> - status == 'offline' ? '' : ''; - $title = $host->status == 'offline' ? $lang->host->online : $lang->host->offline; - if (common::hasPriv('host', 'changeStatus', $host)) echo html::a($this->inlink('changeStatus', "id={$host->id}&hostID={$host->id}&status=$host->status", 'html', true), $icon, '', "class='btn iframe' title='{$title}'"); - - common::printIcon('host','edit',"id=$host->id", $host, '', 'edit'); - if(common::hasPriv('host', 'delete', $host)) - { - $deleteURL = $this->createLink('host', 'delete', "id=$host->id&confirm=yes"); - echo html::a("javascript:ajaxDelete(\"$deleteURL\",\"hostList\",confirmDelete)", '', '', "class='btn' title='{$lang->host->delete}'"); - } - ?> -
      - - -
      -
      - -getModuleRoot() . 'common/view/footer.html.php';?> diff --git a/module/host/view/browseimage.html.php b/module/host/view/browseimage.html.php deleted file mode 100644 index 70a16ff5f8..0000000000 --- a/module/host/view/browseimage.html.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @package zahost - * @version $Id$ - * @link https://www.zentao.net - */ -?> -getModuleRoot() . 'common/view/header.html.php';?> - - -
      ' data-module='vmTemplate'>
      -
      - recTotal}&recPerPage={$pager->recPerPage}";?> - -
      -

      - zahost->image->imageEmpty;?> -

      -
      - - - - - - - - - - - - - - - - status == 'completed' ? zget($image, 'path', '') : '';?> - - - - - - - - - -
      zahost->image->name);?>zahost->image->os);?>zahost->status;?>zahost->image->path;?>zahost->image->progress;?>actions;?>
      name;?>osName;?>'>zahost->image->statusList, $image->status, '');?>'> - createLink('zahost', 'downloadImage', "hostID={$hostID}&imageID={$image->id}"), '', 'hiddenwin', zget($image, 'downloadMisc', ''));?> - createLink('zahost', 'cancelDownload', "id={$image->id}"), '', 'hiddenwin', zget($image, 'cancelMisc', ''));?> -
      - - -
      -getModuleRoot() . 'common/view/footer.html.php';?> diff --git a/module/host/view/changestatus.html.php b/module/host/view/changestatus.html.php deleted file mode 100644 index 2bbeb8eed6..0000000000 --- a/module/host/view/changestatus.html.php +++ /dev/null @@ -1,20 +0,0 @@ -getModuleRoot() . 'common/view/header.html.php';?> -getModuleRoot() . 'common/view/kindeditor.html.php';?> -
      -
      -

      host->reason;?>

      -
      -
      - - - - - - - -
      - -
      -
      -
      -getModuleRoot() . 'common/view/footer.html.php';?> diff --git a/module/host/view/create.html.php b/module/host/view/create.html.php deleted file mode 100644 index 5df4629f0a..0000000000 --- a/module/host/view/create.html.php +++ /dev/null @@ -1,99 +0,0 @@ - - * @package host - * @version $Id$ - * @link https://www.zentao.net - */ -?> -getModuleRoot() . 'common/view/header.html.php';?> -
      -
      -

      host->create?>

      -
      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      host->name;?>host->admin;?>
      host->cpuBrand;?>host->cpuBrandList, '', "class='form-control chosen'");?>host->cpuModel;?>
      host->cpuNumber;?>host->cpuCores;?>
      host->memory;?> -
      - - host->unitList['GB'];?> -
      -
      host->diskSize;?> -
      - - host->unitList['GB'];?> -
      -
      host->group;?>host->serverRoom;?>
      host->serverModel;?>host->hostType;?>host->hostTypeList, 'virtual', "class='form-control chosen'");?>
      host->osName;?>host->osNameList, 'linux', "class='form-control chosen'");?>host->osVersion;?>host->linuxList, '', "class='form-control chosen'");?>
      host->zap?>host->tags?>host->tagsList, '', "class='form-control chosen'");?>
      host->intranet;?>host->extranet;?>
      host->provider?>host->providerList, '', "class='form-control chosen'");?>host->status;?>host->statusList, 'online');?>
      - - -
      -
      -
      -getModuleRoot() . 'common/view/footer.html.php';?> diff --git a/module/host/view/edit.html.php b/module/host/view/edit.html.php deleted file mode 100644 index 0ddb0abceb..0000000000 --- a/module/host/view/edit.html.php +++ /dev/null @@ -1,100 +0,0 @@ - - * @package host - * @version $Id$ - * @link https://www.zentao.net - */ -?> -getModuleRoot() . 'common/view/header.html.php';?> -
      -
      -

      host->editAction;?>

      -
      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      host->name;?>name, "class='form-control'");?>host->admin;?>admin, "class='form-control chosen'");?>
      host->cpuBrand;?>host->cpuBrandList, $host->cpuBrand, "class='form-control chosen'");?>host->cpuModel;?>cpuModel, "class='form-control'");?>
      host->cpuNumber;?>cpuNumber, "class='form-control'");?>host->cpuCores;?>cpuCores, "class='form-control'");?>
      host->memory;?> -
      - memory, "class='form-control'");?> - host->unitList['GB'];?> -
      -
      host->diskSize;?> -
      - diskSize, "class='form-control'");?> - host->unitList['GB'];?> -
      -
      host->group;?>group, "class='form-control chosen'");?>host->serverRoom;?>serverRoom, 'class="form-control chosen" data-max_drop_width="150"');?>
      host->serverModel;?>serverModel, "class='form-control'");?>host->hostType;?>host->hostTypeList, $host->hostType, "class='form-control'");?>
      host->osName;?>host->osNameList, $host->osName, "class='form-control chosen'");?>host->osVersion;?>host->{$host->osName . 'List'}) ? '' : $lang->host->{$host->osName . 'List'}, $host->osVersion, "class='form-control chosen'");?>
      host->zap?>zap, "class='form-control'");?>host->tags?>host->tagsList, $host->vsoft, "class='form-control chosen'");?>
      host->intranet;?>intranet, "class='form-control'");?>host->extranet;?>extranet, "class='form-control'");?>
      host->provider?>host->providerList, $host->provider, "class='form-control chosen'");?>
      - status);?> - - -
      -
      -
      -getModuleRoot() . 'common/view/footer.html.php';?> diff --git a/module/host/view/treemap.html.php b/module/host/view/treemap.html.php deleted file mode 100644 index d272b7d6b0..0000000000 --- a/module/host/view/treemap.html.php +++ /dev/null @@ -1,64 +0,0 @@ - - * @package host - * @version $Id$ - * @link https://www.zentao.net - */ -?> -getModuleRoot() . 'common/view/header.html.php';?> - - - - - -
      -
      -
      - -
      -
      - -getModuleRoot() . 'common/view/footer.html.php';?> diff --git a/module/host/view/view.html.php b/module/host/view/view.html.php deleted file mode 100644 index ad2483d991..0000000000 --- a/module/host/view/view.html.php +++ /dev/null @@ -1,90 +0,0 @@ - - * @package host - * @version $Id$ - * @link https://www.zentao.net - */ -?> -getModuleRoot() . 'common/view/header.html.php';?> -
      -
      -

      host->view;?>

      -
      -
      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      host->name;?>name;?>
      host->group;?>group];?>host->serverRoom;?>serverRoom, "")?>
      host->serverModel;?>serverModel;?>host->hostType;?>host->hostTypeList[$host->hostType];?>
      host->cpuBrand;?>cpuBrand;?>host->cpuModel;?>cpuModel;?>
      host->cpuNumber;?>cpuNumber;?>host->cpuCores;?>cpuCores;?>
      host->memory;?>memory) echo $host->memory . ' GB';?>host->diskSize;?>diskSize) echo $host->diskSize . ' GB';?>
      host->intranet;?>intranet;?>host->extranet;?>extranet;?>
      host->osName;?>osName;?>host->osVersion;?>host->{$host->osName.'List'}[$host->osVersion];?> -
      host->status;?>host->statusList[$host->status];?>
      -
      - getModuleRoot() . 'common/view/action.html.php'?> -
      -
      - -
      - deleted == 0) - { - common::printLink('host', 'edit', "id=$host->hostID&hostID=$host->hostID", " " . $lang->edit, '', "class='btn'", '', '', $host); - common::printLink('host', 'delete', "id=$host->hostID", " " . $lang->delete, 'hiddenwin', "class='btn'", '', '', $host); - } - if(!isonlybody()) echo html::backButton(' ' . $lang->goback, '', 'btn btn-secondary'); - ?> -
      -
      -
      -getModuleRoot() . 'common/view/footer.html.php';?> diff --git a/module/index/js/index.ui.js b/module/index/js/index.ui.js index c00681d8ec..a3d156a443 100644 --- a/module/index/js/index.ui.js +++ b/module/index/js/index.ui.js @@ -168,9 +168,13 @@ function openApp(url, code, options) } else { - iframe.contentWindow.document.open(); - iframe.contentWindow.document.write(apps.frameContent.replace('window.defaultAppUrl = ""', `window.defaultAppUrl = "${url}"`)); - iframe.contentWindow.document.close(); + const writeToDoc = () => { + iframe.contentDocument.open(); + const html = apps.frameContent.replace('window.defaultAppUrl = ""', `window.defaultAppUrl = "${url}"`); + iframe.contentDocument.write(html); + iframe.contentDocument.close(); + }; + if(!iframe.contentDocument.body.children.length) setTimeout(() => writeToDoc(), 500); } iframe.onload = iframe.onreadystatechange = function(e) { diff --git a/module/index/view/changelog.html.php b/module/index/view/changelog.html.php deleted file mode 100644 index 094d324e03..0000000000 --- a/module/index/view/changelog.html.php +++ /dev/null @@ -1,22 +0,0 @@ - -
      -
      -
      -
      -
      -
      -

      explain;?>

      -
      -
      -
      - log):?> -
      - index->detailed;?> -
      log;?>
      -
      - -
      -
      -
      -
      - diff --git a/module/index/view/index.html.php b/module/index/view/index.html.php deleted file mode 100644 index 4fccbe27ed..0000000000 --- a/module/index/view/index.html.php +++ /dev/null @@ -1,165 +0,0 @@ - - * @package ZenTaoPMS - * @version $Id: index.html.php 1947 2011-06-29 11:58:03Z wwccss $ - */ -?> -app->loadConfig('sso'); -if(!empty($config->sso->redirect)) js::set('ssoRedirect', $config->sso->redirect); - -js::set('vision', $config->vision); -js::set('navGroup', $lang->navGroup); -js::set('appsLang', $lang->index->dock); -js::set('appsMenuItems', commonModel::getMainNavList($app->rawModule)); -js::set('defaultOpen', (isset($open) and !empty($open)) ? $open : ''); -js::set('manualText', $lang->manual); -js::set('manualUrl', ((!empty($config->isINT)) ? $config->manualUrl['int'] : $config->manualUrl['home']) . '&theme=' . $_COOKIE['theme']); -js::set('isAdminUser', $this->app->user->admin); -js::set('isIntranet', helper::isIntranet()); -?> - - - - -
      -
      -
      - -
      - -
      -
      - -

      - index->upgradeVersion;?> -

      -
      - -
      -
      -
      -searchAB);?> -searchObjects)) . ',');?> -index->search);?> - - - - diff --git a/module/install/view/index.html.php b/module/install/view/index.html.php deleted file mode 100644 index 36ac78a18d..0000000000 --- a/module/install/view/index.html.php +++ /dev/null @@ -1,70 +0,0 @@ - - * @package ZenTaoPMS - * @version $Id: index.html.php 4129 2013-01-18 01:58:14Z wwccss $ - */ -?> - -
      - -
      - diff --git a/module/install/view/license.html.php b/module/install/view/license.html.php deleted file mode 100644 index f56b92986d..0000000000 --- a/module/install/view/license.html.php +++ /dev/null @@ -1,29 +0,0 @@ - - * @package install - * @version $Id$ - */ -?> - -
      - -
      - diff --git a/module/install/view/step1.html.php b/module/install/view/step1.html.php deleted file mode 100644 index 46b9984795..0000000000 --- a/module/install/view/step1.html.php +++ /dev/null @@ -1,174 +0,0 @@ - - * @package ZenTaoPMS - * @version $Id: step1.html.php 4129 2013-01-18 01:58:14Z wwccss $ - */ -?> - -
      - -
      - - diff --git a/module/install/view/step2.html.php b/module/install/view/step2.html.php deleted file mode 100644 index ff9d721762..0000000000 --- a/module/install/view/step2.html.php +++ /dev/null @@ -1,82 +0,0 @@ - - * @package ZenTaoPMS - * @version $Id: step2.html.php 4972 2013-07-02 06:50:10Z zhujinyonging@gmail.com $ - */ -?> - -
      - -
      - diff --git a/module/install/view/step3.html.php b/module/install/view/step3.html.php deleted file mode 100644 index c49e0a8efe..0000000000 --- a/module/install/view/step3.html.php +++ /dev/null @@ -1,85 +0,0 @@ - - * @package ZenTaoPMS - * @version $Id: step3.html.php 4297 2013-01-27 07:51:45Z wwccss $ - */ -?> - -installed = true; -\$config->debug = false; -\$config->requestType = '$requestType'; -\$config->timezone = '$timezone'; -\$config->db->driver = '$dbDriver'; -\$config->db->host = '$dbHost'; -\$config->db->port = '$dbPort'; -\$config->db->name = '$dbName'; -\$config->db->user = '$dbUser'; -\$config->db->encoding = '$dbEncoding'; -\$config->db->password = '$dbPassword'; -\$config->db->prefix = '$dbPrefix'; -\$config->webRoot = getWebRoot(); -\$config->default->lang = '$defaultLang'; -EOT; - if($customSession) $configContent .= "\n\$config->customSession = true;"; -} -?> -
      - -
      - diff --git a/module/install/view/step4.html.php b/module/install/view/step4.html.php deleted file mode 100644 index 24b40007ba..0000000000 --- a/module/install/view/step4.html.php +++ /dev/null @@ -1,86 +0,0 @@ - - * @package install - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
      - - - -
      -
      -

      -
      -
      - - - - - - - - - - - - - - - - - - - - - - - - custom->allFeatures as $feature):?> - - - - - - - - - - - - - - - - - - - -
      lang->custom->mode;?>lang->custom->modeList['light'];?>lang->custom->modeList['ALM'];?>
      custom->usage;?>custom->modeIntroductionList['light'];?>custom->modeIntroductionList['ALM'];?>
      lang->custom->scrum->common, implode($lang->comma, $disabledScrumFeatures)) : $this->lang->custom->features[$feature];?>
      lang->custom->scrum->common, implode($lang->comma, $enabledScrumFeatures)) : $this->lang->custom->features[$feature];?>
      lang->custom->selectUsage;?>custom->useLight, "id='useLight'", 'btn btn-wide');?>custom->useALM, "id='useALM'", 'btn btn-wide');?>
      lang->upgrade->remark;?>lang->upgrade->remarkDesc;?>
      -
      -
      -
      -
      - -
      - diff --git a/module/install/view/step5.html.php b/module/install/view/step5.html.php deleted file mode 100644 index 4c24ec49fb..0000000000 --- a/module/install/view/step5.html.php +++ /dev/null @@ -1,78 +0,0 @@ - - * @package ZenTaoPMS - * @version $Id: step4.html.php 4129 2013-01-18 01:58:14Z wwccss $ - */ -?> - -install->errorEmpty);?> - -
      - -
      - diff --git a/module/install/view/step6.html.php b/module/install/view/step6.html.php deleted file mode 100644 index 51708673de..0000000000 --- a/module/install/view/step6.html.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @package ZenTaoPMS - * @version $Id: step5.html.php 2568 2012-02-18 15:53:35Z zhujinyong@cnezsoft.com$ - */ -?> - -
      - -
      - diff --git a/module/instance/view/upgrade.html.php b/module/instance/view/upgrade.html.php deleted file mode 100644 index cf6e323d99..0000000000 --- a/module/instance/view/upgrade.html.php +++ /dev/null @@ -1,32 +0,0 @@ - - * @package instance - * @version $Id$ - * @link https://www.zentao.net - */ -?> -app->getModuleRoot() . '/common/view/header.html.php';?> -instance->notices);?> -
      -
      -

      instance->upgrade} : {$instance->name}";?>

      -
      -
      - latestVersion)):?> - - - - -
      - - instance->upgrade);?> -
      - -
      -
      -app->getModuleRoot() . '/common/view/footer.html.php';?> diff --git a/module/instance/view/view.html.php b/module/instance/view/view.html.php deleted file mode 100644 index c9ad6bbecd..0000000000 --- a/module/instance/view/view.html.php +++ /dev/null @@ -1,50 +0,0 @@ - - * @package instance - * @version $Id$ - * @link https://www.zentao.net - */ -?> -app->getModuleRoot() . '/common/view/header.html.php';?> -instance->notices);?> -id));?> -demoAppLife);?> - - -app->getModuleRoot() . '/common/view/footer.html.php';?> diff --git a/module/jenkins/view/edit.html.php b/module/jenkins/view/edit.html.php deleted file mode 100644 index a0f2234107..0000000000 --- a/module/jenkins/view/edit.html.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @package jenkins - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
      -
      -
      -
      -

      jenkins->edit; ?>

      -
      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      jenkins->name; ?>name, "class='form-control'"); ?>
      jenkins->url; ?>url, "class='form-control'"); ?>
      jenkins->account;?>account, "class='form-control'");?>
      jenkins->token;?>token, "class='form-control'");?>jenkins->tokenFirst;?>
      jenkins->password;?>password, "class='form-control'");?>jenkins->tips;?>
      - - goback, '', 'class="btn btn-wide"');?> -
      -
      -
      -
      -
      - diff --git a/module/job/view/browse.html.php b/module/job/view/browse.html.php deleted file mode 100644 index d5e0d01798..0000000000 --- a/module/job/view/browse.html.php +++ /dev/null @@ -1,97 +0,0 @@ - - * @package job - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - - -
      -

      - noData;?> - - createLink('job', 'create'), " " . $lang->job->create, '', "class='btn btn-info'");?> - -

      -
      - -
      -
      - - - - recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?> - - - - - - - - - - - - - - $job):?> - engine) == 'gitlab') - { - $pipeline = json_decode($job->pipeline); - if(is_numeric($job->pipeline)) $job->pipeline = $this->loadModel('gitlab')->getProjectName($job->server, $job->pipeline); - if(isset($pipeline->reference)) $job->pipeline = $this->loadModel('gitlab')->getProjectName($job->server, $pipeline->project); - } - ?> - - - - - - - pipeline) . '@' . $job->jenkinsName;?> - - job->getTriggerConfig($job);?> - - - - - - - -
      job->id);?>job->name);?>job->repo);?>job->engine);?>job->frame);?>job->buildSpec);?>job->triggerType;?>job->lastStatus);?>job->lastExec);?>actions;?>
      createLink('job', 'view', "jobID={$job->id}", 'html', true), $job->name, '', "class='iframe' data-width='90%'") : $job->name;?>repoName;?>job->engineList, $job->engine);?>job->frameList, $job->frame);?>lastStatus) echo zget($lang->compile->statusList, $job->lastStatus);?>lastStatus) echo $job->lastExec;?> - repo}&jobID=$id", '', 'list', 'history'); - common::printIcon('job', 'edit', "jobID=$id", '', 'list', 'edit'); - common::printIcon('job', 'exec', "jobID=$id", '', 'list', 'play', '', $job->canExec ? '' : 'disabled'); - if(common::hasPriv('job', 'delete')) echo html::a($this->createLink('job', 'delete', "jobID=$id"), '', 'hiddenwin', "title='{$lang->job->delete}' class='btn'"); - ?> -
      - - - -
      -
      - - diff --git a/module/job/view/create.html.php b/module/job/view/create.html.php deleted file mode 100644 index 9bbd73fe2b..0000000000 --- a/module/job/view/create.html.php +++ /dev/null @@ -1,157 +0,0 @@ - - * @package job - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - - - -job->dirChange);?> -job->buildTag);?> -job->frameList);?> - -
      -
      -
      -
      -

      job->create; ?>

      -
      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      job->name; ?>
      job->engine; ?> -
      -
      job->engineList, '', "class='form-control chosen'"); ?>
      -
      - -
      - job->engineTips->success;?> -
      job->repo; ?>
      job->product; ?>
      job->frame; ?> -
      - ''), '', "class='form-control chosen'"); ?> -
      -
      job->triggerType; ?>job->triggerTypeList, '', "class='form-control chosen'");?>
      job->svnDir;?> -
      - ''), '', "class='form-control chosen'");?> -
      -
      job->sonarqubeServer;?>
      job->projectKey;?> -
      - ''), '', "class='form-control chosen'");?> -
      -
      job->comment;?>job->commitEx;?>
      datepicker->dayNames, '', '', 'inline');?>
      -
      - job->atTime;?> - -
      -
      job->jkHost; ?> -
      -
      -
      -
      - job->pipeline;?> - -
      -
      -
      -
      job->customParam;?> -
      - '>job->paramName; ?> - - '>job->paramValue; ?> - job->paramValueList, '', "class='form-control' onchange='setParamName(this)'"); ?> - - -
      - - -
      -
      - - -
      -
      - - goback, '', 'class="btn btn-wide"');?> - -
      -
      -
      -
      -
      - diff --git a/module/job/view/edit.html.php b/module/job/view/edit.html.php deleted file mode 100644 index 5626878366..0000000000 --- a/module/job/view/edit.html.php +++ /dev/null @@ -1,206 +0,0 @@ - - * @package job - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - - -triggerType);?> -pipeline);?> -job->dirChange);?> -job->buildTag);?> -pipeline);?> - -job->frameList);?> -engine == 'jenkins' ? $job->pipeline : '');?> - -
      -
      -
      -
      -

      job->edit;?>

      -
      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - job->triggerTypeList['tag'] = $lang->job->dirChange;?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - engine == 'jenkins'):?> - - - - - - - - - - - - -
      job->name;?>name, "class='form-control'");?>
      job->engine;?>job->engineList, $job->engine, '') . html::hidden('engine', $job->engine);?> -
      job->repo; ?>repo, "class='form-control chosen'"); ?>
      job->repo; ?> repo, "class='chosen form-control'");?> reference) ? $job->reference : '', "class='chosen form-control'");?>
      job->product;?>product, "class='form-control chosen'");?>
      job->frame;?> -
      - ''), '', "class='form-control chosen'"); ?> -
      -
      job->triggerType;?>job->triggerTypeList, $job->triggerType, "class='form-control chosen'");?>
      job->svnDir;?> -
      - svnDir) - { - $path = ''; - $svnDirs = trim($job->svnDir, '/'); - $svnDirs = empty($svnDirs) ? '' : $job->svnDir; - $svnDirs = explode('/', $svnDirs); - foreach($svnDirs as $i => $svnDir) - { - $path .= '/' . $svnDir; - $tags = $this->loadModel('svn')->getRepoTags($repo, $path); - if(empty($tags)) continue; - - $selected = isset($svnDirs[$i + 1]) ? $path . $svnDirs[$i + 1] : '/'; - echo ""; - } - } - ?> -
      -
      job->sonarqubeServer;?>sonarqubeServer, "class='form-control chosen' required");?>
      job->projectKey;?> -
      - ''), '', "class='form-control chosen'");?> -
      -
      job->comment;?>comment, "class='form-control'");?>job->commitEx;?>
      datepicker->dayNames, $job->atDay, '', 'inline');?>
      -
      - job->atTime;?> - atTime, "class='form-control form-time'");?> -
      -
      job->server;?> -
      -
      server, "class='form-control chosen'"); ?>
      -
      -
      - job->pipeline;?> - -
      -
      -
      -
      job->customParam;?> - customParam):?> - customParam) as $paramName => $paramValue):?> -
      - job->paramName;?> - - job->paramValue;?> - job->paramValueList, $paramValue, '') ? false : true;?> - - - job->paramValueList, '', "class='form-control hidden' onchange='setParamName(this)' disabled");?> - - - job->paramValueList, $paramValue, "class='form-control' onchange='setParamName(this)'");?> - - -
      - /> - -
      -
      - - -
      - - -
      - '>job->paramName; ?> - - '>job->paramValue; ?> - job->paramValueList, '', "class='form-control' onchange='setParamName(this)'");?> - - -
      - - -
      -
      - - -
      -
      - - repo}"), $lang->goback, '', 'class="btn btn-wide"');?> - repo, 'Git'));?> -
      -
      -
      -
      -
      - diff --git a/module/job/view/view.html.php b/module/job/view/view.html.php deleted file mode 100644 index bf6a6c715d..0000000000 --- a/module/job/view/view.html.php +++ /dev/null @@ -1,127 +0,0 @@ - - * @package job - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -
      - testtask));?> - logs));?> -
      - -
      -
      '> - - - - - - - - - - - - - - - - - - - - engine) == 'gitlab') $job->pipeline = $this->loadModel('gitlab')->getProjectName($job->server, $job->pipeline);?> - - - - - - - - - - - - - - - - - - -
      job->engine;?>job->engineList, $job->engine);?>
      job->repo;?>name;?>
      job->product;?>name;?>
      job->frame;?>job->frameList, $job->frame);?>
      job->server;?>pipeline) . '@' . $jenkins->name;?>
      job->triggerType;?>job->getTriggerConfig($job);?>
      compile->status;?> - status) - { - echo zget($lang->compile->statusList, $compile->status); - } - elseif($job->lastStatus) - { - echo zget($lang->compile->statusList, $job->lastStatus); - } - ?> -
      compile->time;?> - status) - { - echo zget($lang->compile->statusList, $compile->updateDate); - } - elseif($job->lastStatus) - { - echo zget($lang->compile->statusList, $job->lastExec); - } - ?> -
      job->customParam;?> - customParam):?> - customParam) as $paramName => $paramValue):?> - job->paramValueList, $paramValue). '(' . $this->config->version . ')', $paramValue); - $paramValue = str_replace('$zentao_account', zget($lang->job->paramValueList, $paramValue). '(' . $this->app->user->account . ')', $paramValue); - $paramValue = str_replace('$zentao_product', zget($lang->job->paramValueList, $paramValue). '(' . $job->product . ')', $paramValue); - $paramValue = str_replace('$zentao_repopath', zget($lang->job->paramValueList, $paramValue). '(' . $repo->path . ')', $paramValue); - ?> -
      - - -
      -
      - -
      - app->getModuleRoot() . 'testtask/view/unitgroup.html.php';?> -
      - - -
      '> -
      logs);?>
      -
      - -
      -
      -
      - - diff --git a/module/kanban/test/lib/view.ui.class.php b/module/kanban/test/lib/view.ui.class.php index 89c7e22a5f..a0d29c9adf 100755 --- a/module/kanban/test/lib/view.ui.class.php +++ b/module/kanban/test/lib/view.ui.class.php @@ -7,7 +7,7 @@ class viewTester extends tester * set Column * * @param $kanbanurl - * @param $column + * @param $columnName * @return mixed */ public function setColumn($kanbanurl, $columnName) @@ -32,4 +32,63 @@ class viewTester extends tester ? $this->success('看板列设置成功') : $this->failed('看板列设置失败'); } -} \ No newline at end of file + + /* + * 修改泳道名 + * Edit LaneName + * + * @param $kanbanurl + * @param $laneName + * @return mixed + */ + public function editLaneName($kanbanurl, $laneName) + { + $form = $this->initForm('kanban', 'view', $kanbanurl, 'appIframe-kanban'); + $form->dom->laneMoreBtn->click(); + $form->wait(2); + $form->dom->editLaneNameBtn->click(); + $form->wait(2); + if (isset($laneName)) $form->dom->name->setValue($laneName); + $form->dom->btn($this->lang->save)->click(); + $form->wait(2); + if ($form->dom->zin_kanban_editlanename_form) + { + $nameTip = sprintf($this->lang->error->notempty, $this->lang->kanban->laneName); + return ($form->dom->nameTip->getText() == $nameTip) + ? $this->success('泳道名称必填提示信息正确') + : $this->failed('泳道名称必填提示信息不正确'); + } + return ($form->dom->firLaneName->getText() == $laneName) + ? $this->success('泳道名称修改成功') + : $this->failed('泳道名称修改失败'); + } + + /* + * 修改泳道背景色 + * Edit Lane Color + * + * @param $kanbanurl + * @return mixed + */ + public function editLaneColor($kanbanurl) + { + $form = $this->initForm('kanban', 'view', $kanbanurl, 'appIframe-kanban'); + $form->dom->laneMoreBtn->click(); + $form->wait(2); + $form->dom->editLaneColorBtn->click(); + $form->wait(2); + $form->dom->firColor->click(); + $form->dom->btn($this->lang->save)->click(); + $form->wait(2); + if ($form->dom->zin_kanban_editlanecolor_form) + { + return $this->failed('修改泳道背景色失败'); + } + $style = $form->dom->firLane->attr('style'); + preg_match('/--kanban-lane-color:\s*([^;]+)/', $style, $matches); + $colorValue = isset($matches[1]) ? trim($matches[1]) : null; + return ($colorValue == '#3C4353') + ? $this->success('泳道背景色修改成功') + : $this->failed('泳道背景色修改失败'); + } +} diff --git a/module/kanban/test/ui/editlanecolor.php b/module/kanban/test/ui/editlanecolor.php new file mode 100755 index 0000000000..4730dc3c40 --- /dev/null +++ b/module/kanban/test/ui/editlanecolor.php @@ -0,0 +1,96 @@ +#!/usr/bin/env php +id->range('1'); +$kanbanspace->name->range('协作空间-A'); +$kanbanspace->type->range('cooperation'); +$kanbanspace->owner->range('admin'); +$kanbanspace->team->range(',admin'); +$kanbanspace->acl->range('open'); +$kanbanspace->status->range('active'); +$kanbanspace->createdBy->range('admin'); +$kanbanspace->gen(1); + +$kanban = zenData('kanban'); +$kanban->id->range('1'); +$kanban->space->range('1'); +$kanban->name->range('看板-01'); +$kanban->owner->range('admin'); +$kanban->team->range(',admin'); +$kanban->acl->range('open'); +$kanban->archived->range('1'); +$kanban->performable->range('1'); +$kanban->status->range('active'); +$kanban->order->range('1'); +$kanban->object->range('`plans,releases,builds,executions,cards`'); +$kanban->gen(1); + +$kanbanregion = zenData('kanbanregion'); +$kanbanregion->id->range('1'); +$kanbanregion->space->range('1'); +$kanbanregion->name->range('区域AAA'); +$kanbanregion->order->range('1'); +$kanbanregion->gen(1); + +$kanbanlane = zenData('kanbanlane'); +$kanbanlane->id->range('1'); +$kanbanlane->execution->range('0'); +$kanbanlane->type->range('common'); +$kanbanlane->region->range('1'); +$kanbanlane->group->range('1'); +$kanbanlane->groupby->range(''); +$kanbanlane->name->range('默认泳道'); +$kanbanlane->color->range('#7ec5ff'); +$kanbanlane->order->range('1'); +$kanbanlane->gen(1); + +$kanbancell = zenData('kanbancell'); +$kanbancell->id->range('1-4'); +$kanbancell->kanban->range('1'); +$kanbancell->lane->range('1'); +$kanbancell->column->range('1-4'); +$kanbancell->type->range('common'); +$kanbancell->gen(4); + +$kanbancolumn = zenData('kanbancolumn'); +$kanbancolumn->id->range('1-4'); +$kanbancolumn->parent->range('0'); +$kanbancolumn->type->range('column1,column2,column3,column4'); +$kanbancolumn->region->range('1'); +$kanbancolumn->group->range('1'); +$kanbancolumn->name->range('未开始,进行中,已完成,已关闭'); +$kanbancolumn->color->range('#333'); +$kanbancolumn->limit->range('100'); +$kanbancolumn->order->range('1-4'); +$kanbancolumn->archived->range('0'); +$kanbancolumn->gen(4); + +$kanbangroup = zenData('kanbangroup'); +$kanbangroup->id->range('1'); +$kanbangroup->kanban->range('1'); +$kanbangroup->region->range('1'); +$kanbangroup->order->range('1'); +$kanbangroup->gen(1); + +$tester = new viewTester(); +$tester->login(); + +$kanbanurl['kanbanID'] = 1; +r($tester->editLaneColor($kanbanurl)) && p('message,status') && e('泳道背景色修改成功,SUCCESS');//修改泳道背景色 + +$tester->closeBrowser(); diff --git a/module/kanban/test/ui/editlanename.php b/module/kanban/test/ui/editlanename.php new file mode 100755 index 0000000000..85ccbeb81a --- /dev/null +++ b/module/kanban/test/ui/editlanename.php @@ -0,0 +1,100 @@ +#!/usr/bin/env php +id->range('1'); +$kanbanspace->name->range('协作空间-A'); +$kanbanspace->type->range('cooperation'); +$kanbanspace->owner->range('admin'); +$kanbanspace->team->range(',admin'); +$kanbanspace->acl->range('open'); +$kanbanspace->status->range('active'); +$kanbanspace->createdBy->range('admin'); +$kanbanspace->gen(1); + +$kanban = zenData('kanban'); +$kanban->id->range('1'); +$kanban->space->range('1'); +$kanban->name->range('看板-01'); +$kanban->owner->range('admin'); +$kanban->team->range(',admin'); +$kanban->acl->range('open'); +$kanban->archived->range('1'); +$kanban->performable->range('1'); +$kanban->status->range('active'); +$kanban->order->range('1'); +$kanban->object->range('`plans,releases,builds,executions,cards`'); +$kanban->gen(1); + +$kanbanregion = zenData('kanbanregion'); +$kanbanregion->id->range('1'); +$kanbanregion->space->range('1'); +$kanbanregion->name->range('区域AAA'); +$kanbanregion->order->range('1'); +$kanbanregion->gen(1); + +$kanbanlane = zenData('kanbanlane'); +$kanbanlane->id->range('1'); +$kanbanlane->execution->range('0'); +$kanbanlane->type->range('common'); +$kanbanlane->region->range('1'); +$kanbanlane->group->range('1'); +$kanbanlane->groupby->range(''); +$kanbanlane->name->range('默认泳道'); +$kanbanlane->color->range('#7ec5ff'); +$kanbanlane->order->range('1'); +$kanbanlane->gen(1); + +$kanbancell = zenData('kanbancell'); +$kanbancell->id->range('1-4'); +$kanbancell->kanban->range('1'); +$kanbancell->lane->range('1'); +$kanbancell->column->range('1-4'); +$kanbancell->type->range('common'); +$kanbancell->gen(4); + +$kanbancolumn = zenData('kanbancolumn'); +$kanbancolumn->id->range('1-4'); +$kanbancolumn->parent->range('0'); +$kanbancolumn->type->range('column1,column2,column3,column4'); +$kanbancolumn->region->range('1'); +$kanbancolumn->group->range('1'); +$kanbancolumn->name->range('未开始,进行中,已完成,已关闭'); +$kanbancolumn->color->range('#333'); +$kanbancolumn->limit->range('100'); +$kanbancolumn->order->range('1-4'); +$kanbancolumn->archived->range('0'); +$kanbancolumn->gen(4); + +$kanbangroup = zenData('kanbangroup'); +$kanbangroup->id->range('1'); +$kanbangroup->kanban->range('1'); +$kanbangroup->region->range('1'); +$kanbangroup->order->range('1'); +$kanbangroup->gen(1); + +$tester = new viewTester(); +$tester->login(); + +$kanbanurl['kanbanID'] = 1; +r($tester->editLaneName($kanbanurl, '')) && p('message,status') && e('泳道名称必填提示信息正确,SUCCESS');//泳道名称必填校验 +r($tester->editLaneName($kanbanurl, '泳道名称编辑测试')) && p('message,status') && e('泳道名称修改成功,SUCCESS');//修改泳道名称 + +$tester->closeBrowser(); diff --git a/module/kanban/test/ui/page/view.php b/module/kanban/test/ui/page/view.php old mode 100755 new mode 100644 index 6c9c317500..6723fb374b --- a/module/kanban/test/ui/page/view.php +++ b/module/kanban/test/ui/page/view.php @@ -5,6 +5,13 @@ class viewPage extends page { parent::__construct($webdriver); $xpath = array( + /*泳道*/ + 'laneMoreBtn' => '//*[@id="kanbanList"]/div/div/div/div[2]/div[2]/div[1]/div[1]/nav/button', + 'editLaneNameBtn' => '//*[@z-key-path="editLaneName"]', + 'editLaneColorBtn' => '//*[@z-key-path="editLaneColor"]', + 'firLane' => '//*[@id="kanbanList"]/div/div/div/div[2]/div[2]/div[1]', + 'firLaneName' => '//*[@id="kanbanList"]/div/div/div/div[2]/div[2]/div[1]/div[1]/div', + 'firColor' => '//*[@id="zin_kanban_editlanecolor_form"]/div[1]/div/div/div[1]', /*看板列*/ 'createBtn' => '//*[@id="kanbanList"]/div/div/div/div[2]/div[1]/div[2]/div[1]/div/nav/button[1]', 'columnMoreBtn' => '//*[@id="kanbanList"]/div/div/div/div[2]/div[1]/div[2]/div[1]/div/nav/button[2]', diff --git a/module/kanban/view/activate.html.php b/module/kanban/view/activate.html.php deleted file mode 100644 index 485aeb1b2c..0000000000 --- a/module/kanban/view/activate.html.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @package kanban - * @version $Id: activate.html.php 935 2022-05-25 13:18:24Z $ - * @link https://www.zentao.net - */ -?> - - -
      -
      -
      -

      - id;?> - name'>" . $kanban->name . '';?> -

      -
      -
      - - - - - - - - -
      comment;?>
      - kanban->activate);?> -
      -
      -
      -
      -
      -
      - diff --git a/module/kanban/view/activatecard.html.php b/module/kanban/view/activatecard.html.php deleted file mode 100644 index 8fd48ad3d5..0000000000 --- a/module/kanban/view/activatecard.html.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @package kanban - * @version $Id: close.html.php 935 2021-12-09 10:49:24Z $ - * @link https://www.zentao.net - */ -?> - - -
      -
      -
      -

      - id;?> - name'>" . $card->name . '';?> -

      -
      -
      - - - - - - - - - - - - -
      kanbancard->progress;?> -
      - - % -
      -
      comment;?>
      - kanban->activateCard);?> -
      -
      -
      -
      -
      -
      - diff --git a/module/kanban/view/activatespace.html.php b/module/kanban/view/activatespace.html.php deleted file mode 100644 index 08c5bed5a5..0000000000 --- a/module/kanban/view/activatespace.html.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @package kanban - * @version $Id: activatespace.html.php 935 2021-12-15 11:22:24Z $ - * @link https://www.zentao.net - */ -?> - - -
      -
      -
      -

      - id;?> - name'>" . $space->name . '';?> -

      -
      -
      - - - - - - - - -
      comment;?>
      - kanban->activateSpace);?> -
      -
      -
      -
      -
      -
      - diff --git a/module/kanban/view/batchcreatecard.html.php b/module/kanban/view/batchcreatecard.html.php deleted file mode 100644 index 5723524b8a..0000000000 --- a/module/kanban/view/batchcreatecard.html.php +++ /dev/null @@ -1,79 +0,0 @@ - - * @package kanban - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
      -
      -

      - kanban->batchCreateCard;?> -

      -
      -
      -
      - - - - - - - - - - - - - - - - - kanban->batchCreate; $i++):?> - - - - 0) $lanePairs['ditto'] = $this->lang->kanbancard->ditto;?> - - - - - - - - - - - - - - - -
      idAB;?>kanbancard->name?>kanbancard->lane;?>kanbancard->assignedTo;?>kanbancard->estimate;?>kanbancard->begin;?>kanbancard->end;?>kanbancard->desc;?>kanbancard->pri;?>
      0 ? 'ditto' : key($lanePairs), "class='form-control chosen'")?>user->account, "class='form-control chosen' multiple");?> -
      - 0 ? "checked" : '') . " /> {$lang->kanbancard->ditto}"; - ?> -
      -
      -
      - 0 ? "checked" : '') . " /> {$lang->kanbancard->ditto}"; - ?> -
      -
      kanbancard->priList, $pri, 'class=form-control');?>
      - - -
      -
      -
      -
      - diff --git a/module/kanban/view/close.html.php b/module/kanban/view/close.html.php deleted file mode 100644 index feb96674b4..0000000000 --- a/module/kanban/view/close.html.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @package kanban - * @version $Id: close.html.php 935 2021-12-09 10:49:24Z $ - * @link https://www.zentao.net - */ -?> - - -
      -
      -
      -

      - id;?> - name'>" . $kanban->name . '';?> -

      -
      -
      - - - - - - - - -
      comment;?>
      - kanban->close);?> -
      -
      -
      -
      -
      -
      - diff --git a/module/kanban/view/closespace.html.php b/module/kanban/view/closespace.html.php deleted file mode 100644 index 1bad4ba9ed..0000000000 --- a/module/kanban/view/closespace.html.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @package kanban - * @version $Id: closespace.html.php 935 2021-12-15 11:22:24Z $ - * @link https://www.zentao.net - */ -?> - - -
      -
      -
      -

      - id;?> - name'>" . $space->name . '';?> -

      -
      -
      - - - - - - - - -
      comment;?>
      - kanban->closeSpace);?> -
      -
      -
      -
      -
      -
      - diff --git a/module/kanban/view/create.html.php b/module/kanban/view/create.html.php deleted file mode 100644 index 06036ab32e..0000000000 --- a/module/kanban/view/create.html.php +++ /dev/null @@ -1,162 +0,0 @@ - - * @package kanban - * @version $Id: create.html.php 935 2021-12-09 13:48:24Z $ - * @link https://www.zentao.net - */ -?> - - - - - -config->vision);?> -
      -
      -

      kanban->create;?>

      -
      - -
      -
      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      kanbanspace->type;?>
      kanban->WIPCount;?>kanban->showWIPList, isset($copyKanban->showWIP) ? $copyKanban->showWIP : 1);?>
      kanban->space;?>space) ? $copyKanban->space : $spaceID, "onchange='loadUsers(this.value)' class='form-control chosen'");?>
      kanban->name;?>name) ? $copyKanban->name : '', "class='form-control'");?>
      kanban->owner;?> -
      - owner) ? $copyKanban->owner : '', "class='form-control chosen' data-drop_direction='down'");?> - kanban->allUsers, "class='btn btn-default' onclick='loadAllUsers()' data-toggle='tooltip'");?> -
      -
      kanban->team;?> -
      - team) ? $copyKanban->team : '', "class='form-control picker-select' multiple data-dropDirection='bottom'");?> - fetch('my', 'buildContactLists', "dropdownName=team");?> -
      -
      kanban->columnWidth;?> -
      - $lang->kanbancolumn->fluidBoardList['0']), isset($copyKanban->fluidBoard) ? $copyKanban->fluidBoard : 0);?> - colWidth) ? $copyKanban->colWidth : $this->config->colWidth, "class='form-control inline-block setting-input' placeholder='{$this->config->colWidth}' autocomplete='off'");?>px -
      kanbancolumn->fixedTip;?>
      -
      -
      - $lang->kanbancolumn->fluidBoardList['1']), isset($copyKanban->fluidBoard) ? $copyKanban->fluidBoard : 0);?> - minColWidth) ? $copyKanban->minColWidth: $this->config->minColWidth, "class='form-control inline-block setting-input' placeholder='{$this->config->minColWidth}' autocomplete='off'");?>px - ~ - maxColWidth) ? $copyKanban->maxColWidth: $this->config->maxColWidth, "class='form-control inline-block setting-input' placeholder='{$this->config->maxColWidth}' autocomplete='off'");?>px -
      kanbancolumn->autoTip;?>
      -
      -
      kanban->import?>kanban->importList, $enableImport));?>
      kanban->importObjectList, $importObjects);?>
      kanban->archive;?>kanban->archiveList, isset($copyKanban->archived) ? $copyKanban->archived : '1'));?>
      kanban->manageProgress;?>kanban->enableList, isset($copyKanban->performable) ? $copyKanban->performable : '1'));?>
      kanban->alignment;?>kanban->alignmentList, isset($copyKanban->alignment) ? $copyKanban->alignment : 'center'));?>
      kanban->desc;?> - desc) ? $copyKanban->desc : '', "rows='10' class='form-control'");?> -
      whitelist;?> -
      - whitelist) ? $copyKanban->whitelist : '', 'class="form-control picker-select" multiple');?> - fetch('my', 'buildContactLists', "dropdownName=whitelist&attr=data-drop_direction='up'");?> -
      -
      - - - -
      -
      -
      - -getModuleRoot() . 'common/view/footer.html.php';?> diff --git a/module/kanban/view/createcard.html.php b/module/kanban/view/createcard.html.php deleted file mode 100644 index 5fd0b45e72..0000000000 --- a/module/kanban/view/createcard.html.php +++ /dev/null @@ -1,90 +0,0 @@ - - * @package kanban - * @version $Id: createcard.html.php 5090 2021-12-13 13:49:24Z tainshujie@cnezsoft.com $ - * @link https://www.zentao.net - */ -?> - - -
      -
      -
      -

      kanbancard->create;?>

      -
      -
      - - - - - - - - - - - - - - - - - - - - - - - - -
      kanbancard->name;?> -
      - - kanbancard->pri;?> -
      - - -
      -
      -
      - kanbancard->estimate;?> - kanbancard->lblHour}' autocomplete='off'");?> -
      -
      -
      -
      kanbanlane->common;?> - -
      kanbancard->assignedTo;?> - user->account, "class='form-control chosen' multiple");?> -
      kanbancard->beginAndEnd;?> -
      - kanbancard->begin}'");?> - ~ - kanbancard->end}'");?> -
      -
      kanbancard->desc;?>
      - - cancel, "data-dismiss='modal'", 'btn btn-wide');?> -
      -
      -
      -
      - - diff --git a/module/kanban/view/createcolumn.html.php b/module/kanban/view/createcolumn.html.php deleted file mode 100644 index 6daf609e96..0000000000 --- a/module/kanban/view/createcolumn.html.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @package kanban - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -kanban->columnColorList);?> -
      -
      -
      -

      kanban->createColumn;?>

      -
      -
      id&position=$position");?>' onsubmit='return setWIPLimit();'> - - - - - - - - - - - - - - - - -
      kanbancolumn->name;?> -
      - -
      kanban->WIPCount;?> -
      -
      - - - - - -
      -
      kanbancolumn->color;?> -
      - -
      - group);?> - parent > 0 ? $column->parent : 0);?> - - cancel, "data-dismiss='modal'", 'btn btn-wide');?> -
      -
      -
      -
      - diff --git a/module/kanban/view/createexeclane.html.php b/module/kanban/view/createexeclane.html.php deleted file mode 100644 index 764161c63b..0000000000 --- a/module/kanban/view/createexeclane.html.php +++ /dev/null @@ -1,110 +0,0 @@ - - * @package kanban - * @version $Id: createexeclane.html.php 935 2022-01-12 17:22:24Z $ - * @link https://www.zentao.net - */ -?> - - -kanban->laneColorList);?> - - - -
      -
      -

      - kanban->createLane;?> -

      -
      -
      - - - - - - - - - - - - - - - - - - - - - - - - -
      kanbanlane->name;?> -
      - -
      kanbanlane->WIPType;?>kanban->laneTypeList, 'story');?>
      kanbanlane->column;?>kanbanlane->modeList, $mode, '', 'block');?>>
      kanbanlane->color;?> -
      - -
      - - cancel, "data-dismiss='modal'", 'btn btn-wide');?> -
      -
      -
      - - diff --git a/module/kanban/view/createlane.html.php b/module/kanban/view/createlane.html.php deleted file mode 100644 index 30f0e49fba..0000000000 --- a/module/kanban/view/createlane.html.php +++ /dev/null @@ -1,46 +0,0 @@ - - -kanban->laneColorList);?> -
      -
      -

      - kanban->createLane;?> -

      -
      -
      - - - - - - - - - - - - - - - - - - - - - - -
      kanbanlane->name;?> -
      - -
      kanbanlane->column;?>kanbanlane->modeList, 'sameAsOther');?>
      kanbanlane->otherlane;?>
      kanbanlane->color;?> -
      - -
      - - cancel, "data-dismiss='modal'", 'btn btn-wide');?> -
      -
      -
      - - diff --git a/module/kanban/view/createregion.html.php b/module/kanban/view/createregion.html.php deleted file mode 100644 index bebbf955ad..0000000000 --- a/module/kanban/view/createregion.html.php +++ /dev/null @@ -1,39 +0,0 @@ - - * @package kanban - * @version $Id: createregion.html.php 935 2021-12-15 16:23:24Z $ - * @link https://www.zentao.net - */ -?> - -
      -
      -
      -

      kanban->createRegion;?>

      -
      -
      - - - - - - - - - - - - -
      kanbanregion->name;?>
      kanbanregion->style;?>
      - - cancel, "data-dismiss='modal'", 'btn btn-wide');?> -
      -
      -
      -
      - diff --git a/module/kanban/view/createspace.html.php b/module/kanban/view/createspace.html.php deleted file mode 100644 index d7e187570d..0000000000 --- a/module/kanban/view/createspace.html.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @package kanban - * @version $Id: createspace.html.php 935 2021-12-08 14:04:24Z $ - * @link https://www.zentao.net - */ -?> - - -
      -
      -

      kanban->createSpace;?>

      -
      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      kanbanspace->type;?>
      kanbanspace->name;?>
      kanbanspace->owner;?>
      kanbanspace->team;?> -
      - - fetch('my', 'buildContactLists', "dropdownName=team");?> -
      -
      kanbanspace->desc;?> - -
      whitelist;?>
      - -
      -
      -
      -getModuleRoot() . 'common/view/footer.html.php';?> diff --git a/module/kanban/view/edit.html.php b/module/kanban/view/edit.html.php deleted file mode 100644 index 8267aa5ed8..0000000000 --- a/module/kanban/view/edit.html.php +++ /dev/null @@ -1,75 +0,0 @@ - - * @package kanban - * @version $Id: edit.html.php 935 2021-12-09 16:15:24Z $ - * @link https://www.zentao.net - */ -?> - - -config->vision);?> -
      -
      -

      kanban->edit;?>

      -
      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      kanban->space;?>space, "class='form-control chosen' onchange='loadOwners(this.value)'");?>
      kanban->name;?>name, "class='form-control'");?>
      kanban->owner;?> -
      - owner, "class='form-control chosen' data-drop_direction='down'");?> - kanban->allUsers, "class='btn btn-default' onclick='loadAllUsers()' data-toggle='tooltip'");?> -
      -
      kanban->team;?> -
      - team, "class='form-control picker-select' multiple data-dropDirection='bottom'");?> - fetch('my', 'buildContactLists', 'dropdownName=team');?> -
      -
      kanban->desc;?> - desc, "rows='10' class='form-control'");?> -
      whitelist;?> -
      - whitelist, 'class="form-control picker-select" multiple');?> - fetch('my', 'buildContactLists', "dropdownName=whitelist&attr=data-drop_direction='up'");?> -
      -
      - -
      -
      -
      -getModuleRoot() . 'common/view/footer.html.php';?> diff --git a/module/kanban/view/editcard.html.php b/module/kanban/view/editcard.html.php deleted file mode 100644 index 22e5cf0f6c..0000000000 --- a/module/kanban/view/editcard.html.php +++ /dev/null @@ -1,93 +0,0 @@ - - * @package kanban - * @version $Id: editcard.html.php 4903 2021-12-13 14:25:59Z $ - * @link https://www.zentao.net - */ -?> - - -
      -
      -
      -

      kanbancard->edit;?>

      -
      -
      -
      -
      -
      -
      kanbancard->name;?>
      -
      -
      - name, 'class="form-control"');?> -
      -
      -
      -
      -
      kanbancard->desc;?>
      -
      - desc, "rows='5' class='form-control'");?> -
      -
      -
      - - cancel, "data-dismiss='modal'", 'btn btn-wide');?> -
      - -
      -
      -
      -
      -
      -
      kanbancard->legendBasicInfo;?>
      - - - - - - - - - - - - - - - - - - - - - - performable):?> - - - - - -
      kanbancard->assignedTo;?>assignedTo, "class='form-control chosen' multiple");?>
      kanbancard->begin;?>begin) ? '' : $card->begin, "class='form-control form-date'");?>
      kanbancard->end;?>end) ? '' : $card->end, "class='form-control form-date'");?>
      kanbancard->pri;?>kanbancard->priList, $card->pri, "class='form-control'");?>
      kanbancard->estimate;?> -
      - estimate, "class='form-control'");?> - h -
      -
      kanbancard->progress;?> -
      - progress, "class='form-control'");?> - % -
      -
      -
      -
      -
      -
      -
      - -
      - diff --git a/module/kanban/view/editlanecolor.html.php b/module/kanban/view/editlanecolor.html.php deleted file mode 100644 index f8db0cbd9e..0000000000 --- a/module/kanban/view/editlanecolor.html.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @package kanban - * @version $Id: setlane.html.php 935 2021-10-26 16:24:24Z liyuchun@easycorp.ltd $ - * @link https://www.zentao.net - */ -?> - -
      -
      -
      -

      - kanban->editLaneColor;?> -

      -
      -
      - - - - - - - - -
      kanban->laneColor;?> - color, "class='form-control'");?> - -
      - -
      -
      -
      -
      - diff --git a/module/kanban/view/editlanename.html.php b/module/kanban/view/editlanename.html.php deleted file mode 100644 index 68d52fdc1a..0000000000 --- a/module/kanban/view/editlanename.html.php +++ /dev/null @@ -1,47 +0,0 @@ - - * @package kanban - * @version $Id: setlane.html.php 935 2021-10-26 16:24:24Z liyuchun@easycorp.ltd $ - * @link https://www.zentao.net - */ -?> - -
      -
      -
      -

      - kanban->editLaneName;?> -

      -
      -
      - - - - - - - - - - - - - - - -
      kanban->laneName;?> - name, "class='form-control'");?> -
      kanban->WIPType;?> - kanban->laneTypeList, $lane->type), "class='form-control' disabled");?> -
      - -
      -
      -
      -
      - diff --git a/module/kanban/view/editregion.html.php b/module/kanban/view/editregion.html.php deleted file mode 100644 index 7a63eb1dc1..0000000000 --- a/module/kanban/view/editregion.html.php +++ /dev/null @@ -1,39 +0,0 @@ - - * @package kanban - * @version $Id: editregion.html.php 935 2021-10-26 16:24:24Z liumengyi@easycorp.ltd $ - * @link https://www.zentao.net - */ -?> - -
      -
      -
      -

      - kanban->editRegion;?> -

      -
      -
      - - - - - - - - -
      kanbanregion->name;?> - name, "class='form-control'");?> -
      - - cancel, "data-dismiss='modal'", 'btn btn-wide');?> -
      -
      -
      -
      - diff --git a/module/kanban/view/editspace.html.php b/module/kanban/view/editspace.html.php deleted file mode 100644 index 0e100780d2..0000000000 --- a/module/kanban/view/editspace.html.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @package kanban - * @version $Id: editspace.html.php 935 2021-12-08 15:46:24Z $ - * @link https://www.zentao.net - */ -?> - - -
      -
      -

      kanban->editSpace;?>

      -
      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      kanbanspace->type;?>
      kanbanspace->name;?>name, "class='form-control'");?>
      kanbanspace->owner;?>owner, "class='form-control chosen'");?>
      kanbanspace->team;?> -
      - - fetch('my', 'buildContactLists', "dropdownName=team");?> -
      -
      kanbanspace->desc;?> - desc, "rows='10' class='form-control'");?> -
      whitelist;?>whitelist, 'class="form-control picker-select" multiple data-drop-direction="top"');?>
      - -
      -
      -
      -getModuleRoot() . 'common/view/footer.html.php';?> diff --git a/module/kanban/view/importbuild.html.php b/module/kanban/view/importbuild.html.php deleted file mode 100644 index 3e8ba24588..0000000000 --- a/module/kanban/view/importbuild.html.php +++ /dev/null @@ -1,89 +0,0 @@ - - * @package kanban - * @version $Id: importbuild.html.php 5090 2022-01-19 14:19:24Z xieqiyu@cnezsoft.com $ - * @link https://www.zentao.net - */ -?> - - - - - -app->rawMethod);?> - - - -
      -
      -
      -

      kanban->importAB . $lang->kanban->importBuild;?>

      -
      -
      -
      - kanban->selectedProject;?> - - kanban->selectedLane;?> - -
      - -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      -
      - -
      - idAB;?> -
      build->product;?>build->name;?>execution->common;?>build->date;?>build->builder;?>
      -
      - - -
      - id);?> -
      productName;?> - name;?> - name;?>executionName;?>date;?>builder);?>
      - -
      - -
      noData;?>
      - -
      - - diff --git a/module/kanban/view/importcard.html.php b/module/kanban/view/importcard.html.php deleted file mode 100644 index d504ddadc2..0000000000 --- a/module/kanban/view/importcard.html.php +++ /dev/null @@ -1,89 +0,0 @@ - - * @package kanban - * @version $Id: importcard.html.php 5090 2022-01-19 14:19:24Z xieqiyu@cnezsoft.com $ - * @link https://www.zentao.net - */ -?> - - - - - -app->rawMethod);?> -
      -
      -
      -

      kanban->importCard;?>

      -
      -
      -
      - kanban->selectedKanban;?> - - kanban->selectedLane;?> - -
      - -
      - - - - - - - - - - - - - - - - - - - - - - - assignedTo); - foreach($assignedToList as $assignedTo) $assignedToName .= zget($users, $assignedTo) . ' '; - ?> - - - - - - -
      -
      - -
      - idAB;?> -
      kanban->name;?>pri;?>>priAB;?>kanbancard->name;?>kanbancard->assignedTo;?>kanbancard->end;?>
      -
      - - -
      - id);?> -
      kanban);?>pri?>' title='kanbancard->priList, $card->pri, $card->pri);?>'>kanbancard->priList, $card->pri, $card->pri);?>id", $card->name, '', "class='iframe'", true, true);?>name;?>end;?>'>end) ? '' : $card->end;?>
      - -
      - -
      noData;?>
      - -
      - - diff --git a/module/kanban/view/importexecution.html.php b/module/kanban/view/importexecution.html.php deleted file mode 100644 index 73fa2153ba..0000000000 --- a/module/kanban/view/importexecution.html.php +++ /dev/null @@ -1,105 +0,0 @@ - - * @package kanban - * @version $Id: importexecution.html.php 5090 2022-01-19 14:19:24Z xieqiyu@cnezsoft.com $ - * @link https://www.zentao.net - */ -?> - - - - - -app->rawMethod);?> - - - -
      -
      -
      -

      kanban->importAB . $lang->kanban->importExecution;?>

      -
      -
      -
      - kanban->selectedProject;?> - - kanban->selectedLane;?> - -
      - -
      - - - - - - - - - - - - - - - - - - - type == 'stage') $isClickable = $this->programplan->checkLeafStage($execution->id) ? true : false; - ?> - - - - - - - - - - - - - - -
      -
      - -
      - idAB;?> -
      execution->execName;?>execution->execStatus;?>execution->owner;?>execution->end;?>execution->totalEstimate;?>execution->totalConsumed;?>execution->totalLeft;?>
      -
      - - -
      - id);?> -
      - - name;?> - - name;?> - - name;?>execution->statusList, $execution->status);?>PM);?>end;?>hours->totalEstimate;?>hours->totalConsumed;?>hours->totalLeft;?>
      - -
      - -
      noData;?>
      - -
      -systemMode == 'light'):?> - - - - - diff --git a/module/kanban/view/importplan.html.php b/module/kanban/view/importplan.html.php deleted file mode 100644 index b24aa1f400..0000000000 --- a/module/kanban/view/importplan.html.php +++ /dev/null @@ -1,93 +0,0 @@ - - * @package kanban - * @version $Id: importplan.html.php 5090 2022-01-19 14:19:24Z xieqiyu@cnezsoft.com $ - * @link https://www.zentao.net - */ -?> - - - - - -app->rawMethod);?> - - - -
      -
      -
      -

      kanban->importAB . $lang->kanban->importPlan;?>

      -
      -
      -
      - kanban->selectedProduct;?> - - kanban->selectedLane;?> - -
      - -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      -
      - -
      - idAB;?> -
      productplan->title;?>productplan->begin;?>productplan->end;?>productplan->stories;?>productplan->bugs;?>productplan->hour;?>productplan->desc;?>
      -
      - - -
      - id);?> -
      - title;?> - title;?>begin == $config->productplan->future ? $lang->productplan->future : $plan->begin;?>end == $config->productplan->future ? $lang->productplan->future : $plan->end;?>stories;?>bugs;?>hour;?>desc));?>
      - -
      - -
      noData;?>
      - -
      - - diff --git a/module/kanban/view/importrelease.html.php b/module/kanban/view/importrelease.html.php deleted file mode 100644 index 485c87418b..0000000000 --- a/module/kanban/view/importrelease.html.php +++ /dev/null @@ -1,103 +0,0 @@ - - * @package kanban - * @version $Id: importrelease.html.php 5090 2022-01-19 14:19:24Z xieqiyu@cnezsoft.com $ - * @link https://www.zentao.net - */ -?> - - - - - -app->rawMethod);?> - - - -
      -
      -
      -

      kanban->importAB . $lang->kanban->importRelease;?>

      -
      -
      -
      - kanban->selectedProduct;?> - - kanban->selectedLane;?> - -
      - -
      - - - - - - - - - - - - - - builds) ? 1 : count($release->builds);?> - - - - builds) == 0):?> - - - - builds as $build):?> - 1):?> - - - - - - - - - - - - - - - - -
      -
      - -
      - idAB;?> -
      release->name;?>release->includedBuild;?>release->relatedProject;?>release->date;?>
      -
      - - -
      - id);?> -
      - - name;?> - - name;?> - -
      name;?>projectName;?>date;?>
      - -
      - -
      noData;?>
      - -
      - diff --git a/module/kanban/view/setcolumn.html.php b/module/kanban/view/setcolumn.html.php deleted file mode 100644 index c7b2574af4..0000000000 --- a/module/kanban/view/setcolumn.html.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @package kanban - * @version $Id: setcolumn.html.php 935 2021-10-26 16:24:24Z xiawenlong@easycorp.ltd $ - * @link https://www.zentao.net - */ -?> - -
      -
      -
      -

      - " . $title . '';?> -

      -
      -
      - - - - - - - - - - - - - -
      kanban->columnName;?> - name, "class='form-control'");?> -
      kanban->columnColor;?> - color, "class='form-control'");?> - -
      - -
      -
      -
      -
      - diff --git a/module/kanban/view/setlane.html.php b/module/kanban/view/setlane.html.php deleted file mode 100644 index 5a67a5a714..0000000000 --- a/module/kanban/view/setlane.html.php +++ /dev/null @@ -1,60 +0,0 @@ - - * @package kanban - * @version $Id: setlane.html.php 935 2021-10-26 16:24:24Z liyuchun@easycorp.ltd $ - * @link https://www.zentao.net - */ -?> - -
      -
      -
      -

      - kanban->setLane;?> -

      -
      -
      - - - - - - - - - - - - - - - - - - - -
      kanban->laneName;?> - name, "class='form-control'");?> -
      kanban->WIPType;?> - kanban->laneTypeList, $lane->type), "class='form-control' disabled");?> -
      kanban->laneColor;?> - color, "class='form-control'");?> - -
      - -
      -
      -
      -
      - diff --git a/module/kanban/view/setting.html.php b/module/kanban/view/setting.html.php deleted file mode 100644 index bb5afe055d..0000000000 --- a/module/kanban/view/setting.html.php +++ /dev/null @@ -1,83 +0,0 @@ - - * @package kanban - * @version $Id: edit.html.php 935 2021-12-09 16:15:24Z $ - * @link https://www.zentao.net - */ -?> - - - -config->vision);?> -
      -
      -

      kanban->settingKanban;?>

      -
      -
      - - - - - - - - - - - 1):?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      kanban->WIPCount;?>kanban->showWIPList, $kanban->showWIP);?>
      kanban->columnWidth;?> -
      - $lang->kanbancolumn->fluidBoardList['0']), $kanban->fluidBoard);?> - colWidth) ? $kanban->colWidth : $this->config->colWidth, "class='form-control inline-block setting-input' placeholder='{$this->config->colWidth}' autocomplete='off'");?>px -
      kanbancolumn->fixedTip;?>
      -
      -
      - $lang->kanbancolumn->fluidBoardList['1']), $kanban->fluidBoard);?> - minColWidth) ? $kanban->minColWidth : $this->config->minColWidth, "class='form-control inline-block setting-input' placeholder='{$this->config->minColWidth}' autocomplete='off'");?>px - ~ - maxColWidth) ? $kanban->maxColWidth : $this->config->maxColWidth, "class='form-control inline-block setting-input' placeholder='{$this->config->maxColWidth}' autocomplete='off'");?>px -
      kanbancolumn->autoTip;?>
      -
      -
      kanban->laneHeight;?>kanbanlane->heightTypeList, $heightType, "onclick='setCardCount(this.value);'"));?>
      kanban->import?>kanban->importList, $enableImport));?>
      kanban->importObjectList, $importObjects);?>
      kanban->archive;?>kanban->archiveList, $kanban->archived));?>
      kanban->manageProgress;?>kanban->enableList, $kanban->performable));?>
      kanban->alignment;?>kanban->alignmentList, $kanban->alignment));?>
      - -
      -
      -
      - diff --git a/module/kanban/view/setwip.html.php b/module/kanban/view/setwip.html.php deleted file mode 100644 index 0012554226..0000000000 --- a/module/kanban/view/setwip.html.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @package kanban - * @version $Id: setwip.html.php 935 2021-10-25 10:56:24Z liyuchun@easycorp.ltd $ - * @link https://www.zentao.net - */ -?> - - -
      -
      -
      -

      - " . $title . '';?> -

      -
      -
      - - parent != -1 and $from !='kanban'):?> - - - - - - laneType == 'story'):?> - - - - - - - - - - - - - -
      kanban->WIPStatus;?> - kanban->{$column->laneType . 'Column'}, $column->type, ''), "class='form-control' disabled");?> -
      kanban->WIPStage;?> - kanban->storyColumnStageList, $column->type);?> - story->stageList, $stage), "class='form-control' disabled");?> -
      kanban->WIPCount;?> -
      - limit == -1 ? 'disabled' : '';?> - limit != -1 ? $column->limit : '', "class='form-control' $attr");?> -
      -
      - limit, "class='form-control'");?> - -
      - limit == -1 ? 'checked' : '';?>/> - -
      -
      -
      -
      - -
      -
      -
      -
      - diff --git a/module/kanban/view/space.html.php b/module/kanban/view/space.html.php deleted file mode 100644 index eecc342289..0000000000 --- a/module/kanban/view/space.html.php +++ /dev/null @@ -1,196 +0,0 @@ - - * @package kanban - * @version $Id: space.html.php 935 2021-12-07 14:31:24Z $ - * @link https://www.zentao.net - */ -?> - - -
      - -
      -

      kanbanspace->empty;?>

      -
      - - - -
      -
      - - kanbans)):?> -
      - kanbans as $kanbanID => $kanban):?> -
      -
      '> -
      - type == 'cooperation' and $kanban->owner == $this->app->user->account):?> - kanban->mine;?> - -
      - status == 'closed'):?> - kanban->closed;?> - - name;?> -
      - status == 'active'); - $canActivate = (common::hasPriv('kanban', 'activate') and $kanban->status == 'closed'); - ?> - -
      - -
      - - -
      -
      - desc));?> - desc));?> -
      - -
      -
      -
      - -
      - -
      -

      kanban->empty;?>

      -
      - -
      -
      - - -
      - - - - diff --git a/module/kanban/view/splitcolumn.html.php b/module/kanban/view/splitcolumn.html.php deleted file mode 100644 index 190eefef5e..0000000000 --- a/module/kanban/view/splitcolumn.html.php +++ /dev/null @@ -1,132 +0,0 @@ - - * @package kanban - * @version $Id: splitcolumn.html.php 935 2021-12-16 10:24:24Z $ - * @link https://www.zentao.net - */ -?> - -
      -
      -
      -

      kanban->splitColumn;?>

      -
      -
      - - - - - - - - - - - - - - - - - - - - -
      kanbancolumn->childName;?> -
      - -
      - - - -
      -
      -
      kanban->WIPCount;?> -
      - -
      -
      - -
      - - -
      -
      -
      -
      kanbancolumn->childName;?> -
      - -
      - - - -
      -
      -
      kanban->WIPCount;?> -
      - -
      -
      - -
      - - -
      -
      -
      -
      - - -
      - - cancel, "data-dismiss='modal'", 'btn btn-wide');?> -
      - -
      -
      -
      -
      - - - - - - - - - - -
      - diff --git a/module/kanban/view/view.html.php b/module/kanban/view/view.html.php deleted file mode 100644 index 9cf2675f4f..0000000000 --- a/module/kanban/view/view.html.php +++ /dev/null @@ -1,133 +0,0 @@ - - * @package kanban - * @version $Id: view.html.php 935 2021-12-09 10:49:24Z $ - * @link https://www.zentao.net - */ -?> - - - -loadLang('execution'); -$app->loadLang('release'); -$app->loadLang('productplan'); -$laneCount = 0; -foreach($regions as $region) $laneCount += $region->laneCount; - -js::set('vision', $this->config->vision); -js::set('CRKanban', isset($this->config->CRKanban) ? $this->config->CRKanban : 1); -js::set('regions', $regions); -js::set('kanban', $kanban); -js::set('kanbanInfo', $kanban); -js::set('kanbanLang', $lang->kanban); -js::set('kanbanlaneLang', $lang->kanbanlane); -js::set('kanbancolumnLang', $lang->kanbancolumn); -js::set('kanbancardLang', $lang->kanbancard); -js::set('executionLang', $lang->execution); -js::set('releaseLang', $lang->release); -js::set('productplanLang', $lang->productplan); -js::set('kanbanID', $kanban->id); -js::set('laneCount', $laneCount); -js::set('userList', $userList); -js::set('noAssigned', $lang->kanbancard->noAssigned); -js::set('mode', $config->systemMode); -js::set('users', $users); -js::set('colorListLang', $lang->kanbancard->colorList); -js::set('colorList', $this->config->kanban->cardColorList); -js::set('displayCards', $kanban->displayCards); -js::set('fluidBoard', $kanban->fluidBoard); -js::set('minColWidth', $kanban->fluidBoard == '0' ? $kanban->colWidth : $kanban->minColWidth); -js::set('maxColWidth',$kanban->fluidBoard == '0' ? $kanban->colWidth : $kanban->maxColWidth); -js::set('alignment', $kanban->alignment); -js::set('defaultMinColWidth', $this->config->minColWidth); -js::set('defaultMaxColWidth', $this->config->maxColWidth); -js::set('priv', array('canAssignCard' => common::hasPriv('kanban', 'assigncard'))); - -$canSortRegion = commonModel::hasPriv('kanban', 'sortRegion') && count($regions) > 1; -$canEditRegion = commonModel::hasPriv('kanban', 'editRegion'); -$canCreateRegion = commonModel::hasPriv('kanban', 'createRegion'); -$canDeleteRegion = commonModel::hasPriv('kanban', 'deleteRegion'); -$canCreateLane = commonModel::hasPriv('kanban', 'createLane'); -$canViewArchivedCard = commonModel::hasPriv('kanban', 'viewArchivedCard'); -$canViewArchivedColumn = commonModel::hasPriv('kanban', 'viewArchivedColumn'); -?> - - -
      -
      - diff --git a/module/kanban/view/viewarchivedcard.html.php b/module/kanban/view/viewarchivedcard.html.php deleted file mode 100644 index a9ebd88faa..0000000000 --- a/module/kanban/view/viewarchivedcard.html.php +++ /dev/null @@ -1,242 +0,0 @@ - - * @package kanban - * @version $Id: viewarchivedcard.html.php 935 2021-12-22 15:44:24Z $ - * @link https://www.zentao.net - */ -?> - -loadLang('execution'); -$app->loadLang('release'); -$app->loadLang('build'); -$app->loadLang('productplan'); -if($this->config->edition != 'open') $app->loadLang('ticket'); -js::set('systemMode', $this->config->systemMode); -?> -
      -
      - kanban->archivedCard;?> - -
      -
      - -
      -

      kanbancard->empty;?>

      -
      - - -
      -
      - color == '#b10b0b') $color = 'has-color red'; - if($card->color == '#cfa227') $color = 'has-color yellow'; - if($card->color == '#2a5f29') $color = 'has-color green'; - ?> - status == 'done' and $card->color != '#2a5f29') $nameColor = 'green-name'; - ?> - color == '#2a5f29') $labelColor = 'background-color: #FFFFFF; color: #2a5f29'; - $finishLabel = $card->status == 'done' ? "
      {$lang->kanban->finished}
      " : ''; - ?> -
      - fromType)):?> - " . html::a($this->createLink('kanban', 'viewCard', "cardID=$card->id", '', true), $finishLabel . $card->name, '', "class='iframe' data-toggle='modal' data-width='80%' title='$card->name'") . '
      ';?> -
      - pri;?> - estimate and $card->estimate != 0) echo "{$card->estimate}h";?> - - name) ? $card->name : $card->title; - $title = isset($card->title) ? $card->title : $name; - $delayed = ''; - if($card->fromType == 'execution' or $card->fromType == 'ticket') - { - $delayed = (!empty($card->delay) or (!helper::isZeroDate($card->deadline) and helper::now() > $card->deadline)) ? "{$lang->execution->delayed}" : ''; - } - - if(common::hasPriv($card->fromType, 'view') and empty($card->children)) echo "
      " . html::a($this->createLink($card->fromType, 'view', "id=$card->fromID"), $name, '', " title='$title'") . "$delayed
      "; - if(!common::hasPriv($card->fromType, 'view') or !empty($card->children)) echo "
      $name
      $delayed
      "; - if($card->fromType == 'productplan' or $card->fromType == 'build') - { - echo "
      $card->desc
      "; - if(!empty($card->desc)) $class .= ' has-desc'; - } - echo "
      "; - if(isset($lang->{$card->fromType}->statusList[$card->objectStatus])) echo "" . $lang->{$card->fromType}->statusList[$card->objectStatus] . ''; - if(isset($card->date) and !helper::isZeroDate($card->date)) echo "" . date("Y-m-d", strtotime($card->date)) . "" - ?> - - end) and !helper::isZeroDate($card->begin) and $card->begin != '2030-01-01' and $card->end != '2030-01-01'):?> - begin)) . $lang->kanbancard->beginAB;?> - - begin) and !helper::isZeroDate($card->end) and $card->begin != '2030-01-01' and $card->end != '2030-01-01'):?> - end)) . $lang->kanbancard->deadlineAB;?> - - begin) and !helper::isZeroDate($card->end) and $card->begin != '2030-01-01' and $card->end != '2030-01-01' and $card->fromType == ''):?> - begin)) . ' ~ ' . date("m/d", strtotime($card->end));?> - - begin) and !helper::isZeroDate($card->end) and $card->begin != '2030-01-01' and $card->end != '2030-01-01' and $card->fromType != ''):?> - begin)) . ' ' . $lang->{$card->fromType}->to . ' ' . date("m-d", strtotime($card->end));?> - - fromType == 'ticket' and !helper::isZeroDate($card->deadline) and $card->begin != '2030-01-01' and $card->end != '2030-01-01'):?> - deadline)) . ' ' . $lang->kanbancard->deadlineAB;?> - - begin == '2030-01-01' or $card->end == '2030-01-01') echo '' . $lang->{$card->fromType}->future . ''; - - if($card->fromType == '') $assignedToList = explode(',', $card->assignedTo); - if($card->fromType == 'execution') $assignedToList = $card->PM; - if($card->fromType == 'build') $assignedToList = $card->builder; - if($card->fromType == 'release' or $card->fromType == 'productplan') $assignedToList = $card->createdBy; - if($card->fromType == 'ticket') $assignedToList = $card->assignedTo; - $count = 0; - $members = ''; - ?> - - $account) - { - if(!isset($users[$account]) or !isset($usersAvatar[$account])) - { - unset($assignedToList[$index]); - continue; - } - $members .= $users[$account] . ','; - } - $userCount = count($assignedToList); - ?> - 0):?> -
      - 2) continue; - echo html::smallAvatar(array('avatar' => $usersAvatar[$account], 'account' => $account, 'name' => $users[$account]), 'avatar-circle'); - $count ++; - $class .= ' has-avatar'; - } - ?> - 2) echo "...";?> -
      - - - "; - echo html::smallAvatar(array('avatar' => $usersAvatar[$assignedToList], 'account' => $assignedToList, 'name' => $users[$assignedToList]), 'avatar-circle'); - echo "
      "; - $class .= ' has-avatar'; - } - ?> - -
      - performable and ($card->fromType == 'execution' or empty($card->fromType))):?> -
      -
      -
      -
      -
      progress, 2) . ' %';?>
      -
      - -
      -
      - performable) and ($card->fromType == 'execution' or empty($card->fromType))) ? ' has-progress' : ' no-progress';?> -
      - config->CRKanban) and $this->config->CRKanban == '0' and $kanban->status == 'closed'); - $canRestore = (commonModel::hasPriv('kanban', 'restoreCard') and $CRKanban); - $canDelete = (commonModel::hasPriv('kanban', 'deleteCard') and $CRKanban); - - if($canRestore) echo html::a(inlink('restoreCard', "cardID={$card->id}"), $lang->kanban->restore, '', "class='btn btn-xs btn-primary' target='hiddenwin'"); - - if($canDelete) echo html::a($this->createLink('kanban', 'deleteCard', "cardID=$card->id"), $card->fromType == '' ? $lang->delete : $lang->unlink, '', "class='btn btn-xs delete-card' target='hiddenwin'"); - ?> -
      -
      - - -
      -
      - diff --git a/module/kanban/view/viewarchivedcolumn.html.php b/module/kanban/view/viewarchivedcolumn.html.php deleted file mode 100644 index 8e0b08b1a6..0000000000 --- a/module/kanban/view/viewarchivedcolumn.html.php +++ /dev/null @@ -1,64 +0,0 @@ - - * @package kanban - * @version $Id: viewarchivedcolumn.html.php 935 2021-12-22 10:49:24Z $ - * @link https://www.zentao.net - */ -?> - -
      -
      - kanban->archivedColumn;?> - -
      -
      - -
      -

      kanbancolumn->empty;?>

      -
      - - -
      -
      -
      name;?>
      - archived == '1' && !(isset($this->config->CRKanban) and $this->config->CRKanban == '0' and $kanban->status == 'closed')) echo html::a(inlink('restoreColumn', "columnID={$column->id}"), $lang->kanban->restore, '', "class='btn btn-primary' target='hiddenwin'");?> -
      - child) && $column->archived == '0'):?> - - child as $childColumn):?> - child) ? 'hr' : '';?> -
      -
      name;?>
      - archived == '1' && !(isset($this->config->CRKanban) and $this->config->CRKanban == '0' and $kanban->status == 'closed')) echo html::a(inlink('restoreColumn', "columnID={$childColumn->id}"), $lang->kanban->restore, '', "class='btn btn-primary' target='hiddenwin'");?> -
      - - - -
      - - -
      -
      - diff --git a/module/kanban/view/viewcard.html.php b/module/kanban/view/viewcard.html.php deleted file mode 100644 index 802cdee99d..0000000000 --- a/module/kanban/view/viewcard.html.php +++ /dev/null @@ -1,158 +0,0 @@ - - * @package kanban - * @version $Id: viewcard.html.php 4903 2021-12-13 16:25:59Z $ - * @link https://www.zentao.net - */ -?> - - - -
      -
      -
      -
      -
      kanbancard->desc;?>
      -
      desc;?>
      -
      -
      -
      - createLink('action', 'comment', "objectType=kanbancard&objectID=$card->id");?> - -
      -
      -
      - deleted and !$card->archived and !(isset($this->config->CRKanban) and $this->config->CRKanban == '0' and $kanban->status == 'closed')):?> - id", "{$lang->kanbancard->assign}", '', "class='btn btn-link iframe' title='{$lang->kanbancard->assign}'", true, true); - if($kanban->archived) - { - common::printLink('kanban', 'archiveCard', "cardID=$card->id", "{$lang->kanbancard->archive}", 'hiddenwin', "class='btn btn-link' title='{$lang->kanbancard->archive}'", true, true); - - echo "
      "; - } - - common::printLink('kanban', 'editCard', "cardID=$card->id", '', '', "class='btn btn-link' data-width='80%' title='{$lang->kanbancard->edit}'", true, true); - - if($kanban->performable) - { - if($card->status == 'done') echo html::a(helper::createLink('kanban', 'activateCard', "cardID={$card->id}&kanbanID={$kanban->id}"), '', '', "class='btn btn-link' title='{$lang->kanban->activateCard}'"); - if($card->status == 'doing') echo html::a(helper::createLink('kanban', 'finishCard', "cardID={$card->id}&kanbanID={$kanban->id}"), '', '', "class='btn btn-link iframe' title='{$lang->kanban->finishCard}'"); - } - - //common::printLink('kanban', 'copyCard', "cardID=$card->id", '', '', "class='btn btn-link iframe' title='{$lang->kanbancard->copy}'", true, true); - common::printLink('kanban', 'deleteCard', "cardID=$card->id", '', 'hiddenwin', "class='btn btn-link' title='{$lang->kanbancard->delete}'",true, true); - ?> - -
      -
      -
      -
      -
      -
      - -
      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - performable):?> - - - - - - -
      kanbancard->assignedTo;?> - assignedTo));?> - $assignedTo) - { - if(!isset($users[$assignedTo])) unset($assignedToPairs[$index]); - } - ?> - -
      - -
      - -
      - -
      - -
      kanbancard->space;?>name;?>
      kanbancard->kanban;?>name;?>
      kanbancard->begin;?>begin) ? '' : $card->begin;?>
      kanbancard->end;?>end) ? '' : $card->end;?>
      kanbancard->pri;?>pri;?>' title='kanbancard->priList, $card->pri);?>'>kanbancard->priList, $card->pri);?>
      kanbancard->estimate;?>estimate, 2) . ' ' . $lang->kanbancard->lblHour;?>
      kanbancard->progress;?>progress, 2) . ' %';?>
      -
      -
      -
      -
      -
      -
      - -
      -
      - - - - - - - - - - - - - - - -
      kanbancard->createdBy;?>createdBy) . $lang->at . $card->createdDate;?>
      kanbancard->archivedBy;?>archivedBy ? zget($users, $card->archivedBy) . $lang->at . $card->archivedDate : '';?>
      kanbancard->lastEditedBy;?>lastEditedBy ? zget($users, $card->lastEditedBy) . $lang->at . $card->lastEditedDate : '';?>
      -
      -
      -
      -
      -
      -
      - diff --git a/module/mail/tao.php b/module/mail/tao.php index 8f1b76e3a7..527f2092bf 100644 --- a/module/mail/tao.php +++ b/module/mail/tao.php @@ -200,6 +200,7 @@ class mailTao extends mailModel if(!$objectModel) return false; $getObjectMethod = $objectType == 'kanbancard' ? 'getCardByID' : 'getByID'; + if($objectType == 'task') $getObjectMethod = 'fetchByID'; if(method_exists($objectModel, $getObjectMethod)) { $object = call_user_func(array($objectModel, $getObjectMethod), $objectID); @@ -208,6 +209,7 @@ class mailTao extends mailModel { $object = $this->fetchByID($objectID, $objectType); } + if(!$object) return false; if($objectType == 'doc' && $object->contentType == 'markdown') diff --git a/module/mail/test/tao/getobjectformail.php b/module/mail/test/tao/getobjectformail.php index cb696a3315..aca4397adf 100755 --- a/module/mail/test/tao/getobjectformail.php +++ b/module/mail/test/tao/getobjectformail.php @@ -4,6 +4,7 @@ /** title=测试 mailModel->getObjectForMail(); +timeout=0 cid=0 - 不传入任何参数 @0 @@ -96,4 +97,4 @@ r((array)$mailModel->getObjectForMail('story', 1)) && p('id,product,type,ti r((array)$mailModel->getObjectForMail('task', 1)) && p('id,project,execution,name,desc,type,status') && e('1,11,101,开发任务11,这里是任务描述1,design,wait'); //获取任务ID=1的数据 r((array)$mailModel->getObjectForMail('bug', 1)) && p('id,product,title,steps,status') && e('1,1,BUG1,

      【步骤】


      【结果】


      【期望】


      ,active'); //获取Bug ID=1的数据 r((array)$mailModel->getObjectForMail('kanbancard', 1)) && p('id,kanban,name,status,assignedTo') && e('1,1,卡片1,doing,admin'); //获取看板卡片ID=1的数据 -r((array)$mailModel->getObjectForMail('release', 1)) && p('id,product,build,name,status') && e('1,1,1,产品正常的正常的发布1,normal'); //获取发布ID=1的数据 +r((array)$mailModel->getObjectForMail('release', 1)) && p('id,product,build,name,status') && e('1,1,1,产品正常的正常的发布1,normal'); //获取发布ID=1的数据 \ No newline at end of file diff --git a/module/mail/view/browse.html.php b/module/mail/view/browse.html.php deleted file mode 100644 index f43010b42b..0000000000 --- a/module/mail/view/browse.html.php +++ /dev/null @@ -1,80 +0,0 @@ - - * @package mail - * @version $Id$ - * @link https://www.zentao.net - */ -?> -app->getModuleRoot() . 'message/view/header.html.php';?> -
      -
      -
      - mail->browse?> -
      -
      -
      ' target='hiddenwin' id='mailForm' data-ride='table'> - - recTotal}&recPerPage={$pager->recPerPage}"; ?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      -
      - -
      - idAB);?> -
      mail->toList);?> mail->subject);?> mail->createdBy);?>mail->createdDate);?>mail->sendTime);?> mail->status);?> mail->failReason;?> actions;?>
      -
      - - -
      - id?> -
      toList, $queue->toList)?>subject?>createdBy)?>createdDate?>sendTime?>mail->statusList, $queue->status)?>failReason?> - id"), $lang->delete, 'hiddenwin'); - if(common::hasPriv('mail', 'resend') and $queue->status == 'fail') echo html::a(inlink('resend', "id=$queue->id"), $lang->mail->resend, 'hiddenwin'); - ?> -
      - - - -
      -
      - - diff --git a/module/mail/view/detect.html.php b/module/mail/view/detect.html.php deleted file mode 100755 index 2f6feeba8b..0000000000 --- a/module/mail/view/detect.html.php +++ /dev/null @@ -1,23 +0,0 @@ - - * @package mail - * @version $Id$ - * @link https://www.zentao.net - */ -?> -app->getModuleRoot() . 'message/view/header.html.php';?> -
      -
      -
      - - -
      mail->inputFromEmail; ?>mail->nextStep, '', 'btn btn-primary');?>
      -
      -
      -
      - diff --git a/module/mail/view/edit.html.php b/module/mail/view/edit.html.php deleted file mode 100755 index 59c8487e41..0000000000 --- a/module/mail/view/edit.html.php +++ /dev/null @@ -1,104 +0,0 @@ - - * @package mail - * @version $Id$ - * @link https://www.zentao.net - */ -?> -app->getModuleRoot() . 'message/view/header.html.php';?> -
      -
      -
      ' id='dataform'> - - - - - - - - global->cron)):?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      mail->turnon; ?>mail->turnonList, 1);?>
      mail->async?>mail->asyncList, zget($config->mail, 'async', 0))?>
      mail->fromAddress; ?>fromAddress, "class='form-control'");?>mail->addressWhiteList?>
      mail->fromName; ?> -
      - fromName, "class='form-control'");?> -
      mail->domain; ?>domain, "class='form-control'");?>
      mail->host; ?>host, "class='form-control'");?>
      mail->port; ?>port, "class='form-control'");?>
      mail->secure; ?> - mail->secureList['ssl']); - unset($lang->mail->secureList['tls']); - $mailConfig->secure = ''; - } - echo html::radio('secure', $lang->mail->secureList, $mailConfig->secure); - if(!$openssl) echo "   " . $lang->mail->disableSecure . ''; - ?> -
      mail->auth; ?>mail->authList, $mailConfig->auth); ?>
      mail->username; ?>username, "class='form-control'") ?>
      mail->password; ?>password, "class='form-control' placeholder='{$lang->mail->placeholder->password}'") ?>
      mail->debug; ?>mail->debugList, $mailConfig->debug);?>
      mail->charset; ?>charsets[$this->cookie->lang], $mailConfig->charset);?>
      - - mail->turnon and $mailExist) echo html::a(inlink('test'), $lang->mail->test, '', "class='btn btn-wide'"); - echo html::a(inlink('reset'), $lang->mail->reset, '', "class='btn btn-wide'"); - if(common::hasPriv('mail', 'browse') and !empty($config->mail->async) and !empty($config->global->cron)) echo html::a(inlink('browse'), $lang->mail->browse, '', "class='btn btn-wide'"); - ?> -
      -
      -
      -
      - diff --git a/module/mail/view/index.html.php b/module/mail/view/index.html.php deleted file mode 100755 index 4d3516352e..0000000000 --- a/module/mail/view/index.html.php +++ /dev/null @@ -1,32 +0,0 @@ - - * @package mail - * @version $Id$ - * @link https://www.zentao.net - */ -?> -app->getModuleRoot() . 'message/view/header.html.php';?> -
      -
      -
      -
      - mail->selectMTA;?> -
      -
      - - - - -
      - - mail->smtp, '', "class='btn w-120px'")?> - -
      -
      -
      - diff --git a/module/mail/view/test.html.php b/module/mail/view/test.html.php deleted file mode 100755 index 558a4cab48..0000000000 --- a/module/mail/view/test.html.php +++ /dev/null @@ -1,47 +0,0 @@ - - * @package mail - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - - -
      - - -app->getModuleRoot() . 'message/view/header.html.php';?> -
      -
      -
      -

      - mail->common;?> - arrow . $lang->mail->test;?> -

      -
      mail->sendmailTips;?>
      -
      -
      - - - - - -
      user->account, "class='form-control chosen'");?> - mail->test, '', 'btn btn-primary'); - $mta = $config->mail->mta; - echo html::linkButton($lang->mail->edit, inlink(($mta == 'sendcloud' or $mta == 'ztcloud') ? $mta : 'edit')); - ?> -
      -
      -
      -
      -
      - - diff --git a/module/message/view/browser.html.php b/module/message/view/browser.html.php deleted file mode 100644 index f249c954f9..0000000000 --- a/module/message/view/browser.html.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @package message - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
      -
      -
      -

      - message->browser;?> - arrow . $lang->message->setting;?> -

      -
      -
      - - - - - - - - - - - - - - - -
      message->browserSetting->turnon; ?>message->browserSetting->turnonList, $browserConfig->turnon);?>
      message->browserSetting->pollTime; ?>pollTime, "class='form-control'");?>message->browserSetting->pollTimePlaceholder?>
      -
      -
      -
      - diff --git a/module/message/view/setting.html.php b/module/message/view/setting.html.php deleted file mode 100644 index c94b5a6d02..0000000000 --- a/module/message/view/setting.html.php +++ /dev/null @@ -1,90 +0,0 @@ - - * @package message - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
      -
      - - - - message->typeList as $type => $typeName):?> - - - - - message->objectTypes as $objectType => $actions):?> - - - message->setting) ? json_decode($config->message->setting, true) : $config->message->setting;?> - message->typeList as $type => $typeName):?> - message->available[$type][$objectType])):?> - message->available[$type][$objectType] as $action) - { - if(!isset($objectActions[$objectType][$action])) continue; - $availableActions[$action] = $objectActions[$objectType][$action]; - } - ?> - - - - - - - - - - - - - - - - - -
      -
      - ' /> - -
      -
      -
      - ' /> - -
      -
      - $value) - { - $checked = strpos(",$selected,", ",{$key},") !== false ? "checked='checked'" : ''; - echo "
      "; - echo ""; - echo "
      "; - } - if(isset($config->message->condition[$type][$objectType])) - { - $moduleName = $objectType == 'case' ? 'testcase' : $objectType; - $this->app->loadLang($moduleName); - foreach(explode(',', $config->message->condition[$type][$objectType]) as $condition) - { - $listKey = $condition . 'List'; - $list = isset($this->lang->$moduleName->$listKey) ? $this->lang->$moduleName->$listKey : $users; - echo html::select("messageSetting[$type][condition][$objectType][$condition][]", $list, isset($messageSetting[$type]['condition'][$objectType][$condition]) ? join(',', $messageSetting[$type]['condition'][$objectType][$condition]) : '', "class='form-control chosen' multiple data-placeholder='{$this->lang->$moduleName->$condition}'"); - } - } - ?> -
      message->blockUser;?>message->blockUser) ? $config->message->blockUser: '', "class='form-control chosen' multiple");?>
      -
      -
      - diff --git a/module/misc/lang/de.php b/module/misc/lang/de.php index e32101b96c..f7fd535b0a 100644 --- a/module/misc/lang/de.php +++ b/module/misc/lang/de.php @@ -114,7 +114,7 @@ $lang->misc->feature->promptExecImage = 'theme/default/images/main/prompt_exec $lang->misc->feature->promptLearnMore = 'https://www.zentao.net/book/zentaopms/1097.html'; /* Release Date. */ -$lang->misc->releaseDate['21.7.5'] = '2025-08-22'; +$lang->misc->releaseDate['21.7.5'] = '2025-09-11'; $lang->misc->releaseDate['21.7.4'] = '2025-07-29'; $lang->misc->releaseDate['21.7.3'] = '2025-07-03'; $lang->misc->releaseDate['21.7.2'] = '2025-06-27'; diff --git a/module/misc/lang/en.php b/module/misc/lang/en.php index 1d6b2adc70..930cb12b08 100644 --- a/module/misc/lang/en.php +++ b/module/misc/lang/en.php @@ -115,7 +115,7 @@ $lang->misc->feature->promptExecImage = 'theme/default/images/main/prompt_exec $lang->misc->feature->promptLearnMore = 'https://www.zentao.net/book/zentaopms/1097.html'; /* Release Date. */ -$lang->misc->releaseDate['21.7.5'] = '2025-08-22'; +$lang->misc->releaseDate['21.7.5'] = '2025-09-11'; $lang->misc->releaseDate['21.7.4'] = '2025-07-29'; $lang->misc->releaseDate['21.7.3'] = '2025-07-03'; $lang->misc->releaseDate['21.7.2'] = '2025-06-27'; diff --git a/module/misc/lang/fr.php b/module/misc/lang/fr.php index 02484e24ee..b93dd8c4f3 100644 --- a/module/misc/lang/fr.php +++ b/module/misc/lang/fr.php @@ -114,7 +114,7 @@ $lang->misc->feature->promptExecImage = 'theme/default/images/main/prompt_exec $lang->misc->feature->promptLearnMore = 'https://www.zentao.net/book/zentaopms/1097.html'; /* Release Date. */ -$lang->misc->releaseDate['21.7.5'] = '2025-08-22'; +$lang->misc->releaseDate['21.7.5'] = '2025-09-11'; $lang->misc->releaseDate['21.7.4'] = '2025-07-29'; $lang->misc->releaseDate['21.7.3'] = '2025-07-03'; $lang->misc->releaseDate['21.7.2'] = '2025-06-27'; diff --git a/module/misc/lang/zh-cn.php b/module/misc/lang/zh-cn.php index 6756608b96..2f26598875 100644 --- a/module/misc/lang/zh-cn.php +++ b/module/misc/lang/zh-cn.php @@ -115,7 +115,7 @@ $lang->misc->feature->promptExecImage = 'theme/default/images/main/prompt_exec $lang->misc->feature->promptLearnMore = 'https://www.zentao.net/book/zentaopms/1097.html'; /* Release Date. */ -$lang->misc->releaseDate['21.7.5'] = '2025-08-22'; +$lang->misc->releaseDate['21.7.5'] = '2025-09-11'; $lang->misc->releaseDate['21.7.4'] = '2025-07-29'; $lang->misc->releaseDate['21.7.3'] = '2025-07-03'; $lang->misc->releaseDate['21.7.2'] = '2025-06-27'; @@ -255,6 +255,7 @@ $lang->misc->releaseDate['6.3.stable'] = '2014-11-07'; /* Release Detail. */ $lang->misc->feature->all['21.7.5'][] = array('title' => '....', 'desc' => ''); +$lang->misc->feature->all['21.7.5'][] = array('title' => '....', 'desc' => ''); $lang->misc->feature->all['21.7.4'][] = array('title' => '', 'desc' => ''); $lang->misc->feature->all['21.7.3'][] = array('title' => 'zentaopms21.7.3zentaobiz12.2max7.2ipd4.2', 'desc' => ''); $lang->misc->feature->all['21.7.2'][] = array('title' => '文档功能优化;项目模板功能发布。', 'desc' => ''); diff --git a/module/misc/test/model/sendinstallevent.php b/module/misc/test/model/sendinstallevent.php index f2637208f2..328273bca8 100644 --- a/module/misc/test/model/sendinstallevent.php +++ b/module/misc/test/model/sendinstallevent.php @@ -34,26 +34,31 @@ $locationList[2] = 'join-community'; $fingerprintList[3] = ''; $locationList[3] = ''; +$fingerprintList[4] = '572e8c0ccbce6f171980fd98b2b298a1'; +$locationList[4] = 'test'; + $data = new stdClass(); $data->fingerprint = $fingerprintList[0]; $data->location = $locationList[0]; -r($miscModel->sendInstallEvent($data)) && p() && e('true'); // 测试发送安装过程埋点是否成功 +r($miscModel->sendInstallEvent($data)) && p() && e(1); // 测试发送安装过程埋点是否成功 $data = new stdClass(); $data->fingerprint = $fingerprintList[1]; $data->location = $locationList[1]; -r($miscModel->sendInstallEvent($data)) && p() && e('false'); // 测试location = '' +r($miscModel->sendInstallEvent($data)) && p() && e(0); // 测试location = '' $data = new stdClass(); $data->fingerprint = $fingerprintList[2]; $data->location = $locationList[2]; -r($miscModel->sendInstallEvent($data)) && p() && e('false'); // 测试fingerprint = '' +r($miscModel->sendInstallEvent($data)) && p() && e(0); // 测试fingerprint = '' $data = new stdClass(); $data->fingerprint = $fingerprintList[3]; $data->location = $locationList[3]; -r($miscModel->sendInstallEvent($data)) && p() && e('false'); // 测试fingerprint = '' 并且 location = '' +r($miscModel->sendInstallEvent($data)) && p() && e(0); // 测试fingerprint = '' 并且 location = '' $data = new stdClass(); -r($miscModel->sendInstallEvent($data)) && p() && e('false'); // 测试$data中没有属性 \ No newline at end of file +$data->fingerprint = $fingerprintList[4]; +$data->location = $locationList[4]; +r($miscModel->sendInstallEvent($data)) && p() && e(1); // 测试其他location \ No newline at end of file diff --git a/module/misc/view/about.html.php b/module/misc/view/about.html.php deleted file mode 100644 index a75a8b45c7..0000000000 --- a/module/misc/view/about.html.php +++ /dev/null @@ -1,32 +0,0 @@ - -
      -
      -
      -
      -

      misc->zentao->labels['about'];?>

      -
      - - - - - - - - -
      -
      -
      -
      - diff --git a/module/misc/view/changelog.html.php b/module/misc/view/changelog.html.php deleted file mode 100644 index efd3275072..0000000000 --- a/module/misc/view/changelog.html.php +++ /dev/null @@ -1,41 +0,0 @@ - -
      -
      -
      -
      -
      -

      changeLog ?>

      -
      - -
      -
      -
      - - -
      -

      -
      -
      - - -
      - -
      - misc->feature->detailed;?> -
      -
      - -
      -
      -
      -
      - diff --git a/module/mr/view/approval.html.php b/module/mr/view/approval.html.php deleted file mode 100644 index cae4c3e25e..0000000000 --- a/module/mr/view/approval.html.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @package mr - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - - -
      -
      -
      - id; ?> -

      - title'>" . $MR->title . ' - ' . zget($lang->mr->approvalResultList, $action) . '') : html::a($this->createLink('mr', 'view', 'MRID=' . $MR->id), $MR->title); ?> - - arrow . $lang->mr->approval; ?> - -

      -
      -
      id&action=$action")?>'> - - needCI and $showCompileResult): ?> - - - - - - - - - - - - - - - - - - -
      compile->result; ?> - compile->statusList[$MR->compileStatus], '_blank'); ?> -
      mr->assignee; ?> - createdBy, "class='form-control chosen'"); ?> -
      comment; ?>
      - save); ?> - goback, $this->createLink('mr', 'view', 'MR=' . $MR->id), 'self', '', 'btn btn-wide'); ?> -
      -
      -
      -
      -
      -
      - diff --git a/module/mr/view/browse.html.php b/module/mr/view/browse.html.php deleted file mode 100644 index f49924a6ce..0000000000 --- a/module/mr/view/browse.html.php +++ /dev/null @@ -1,121 +0,0 @@ - - - -
      - -
      -

      - noData . $lang->mr->common;?> - - createLink('mr', 'create'), " " . $lang->mr->create, '', "class='btn btn-info'");?> - -

      -
      - -
      - - - - recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?> - - - - - - - - - - - - - - SCM == 'Gitlab') - { - $sourceProject = isset($projects[$MR->hostID][$MR->sourceProject]) ? $projects[$MR->hostID][$MR->sourceProject]->name_with_namespace . ':' . $MR->sourceBranch : $MR->sourceProject . ':' . $MR->sourceBranch; - $targetProject = isset($projects[$MR->hostID][$MR->targetProject]) ? $projects[$MR->hostID][$MR->targetProject]->name_with_namespace . ':' . $MR->targetBranch : $MR->targetProject . ':' . $MR->targetBranch; - } - else - { - $sourceProject = isset($projects[$MR->hostID][$MR->sourceProject]) ? $projects[$MR->hostID][$MR->sourceProject]->full_name . ':' . $MR->sourceBranch : $MR->sourceProject . ':' . $MR->sourceBranch; - $targetProject = isset($projects[$MR->hostID][$MR->targetProject]) ? $projects[$MR->hostID][$MR->targetProject]->full_name . ':' . $MR->targetBranch : $MR->targetProject . ':' . $MR->targetBranch; - } - ?> - - - - - - status == 'closed'):?> - - - - - - status == 'merged' or $MR->status == 'closed'):?> - - - - - - - - - - -
      mr->id);?>mr->title);?>mr->sourceBranch);?>mr->targetBranch);?>mr->mergeStatus);?>mr->approvalStatus);?>mr->author);?>mr->createdDate);?>actions;?>
      id;?>id}"), $MR->title);?>mr->statusList, $MR->status);?>status == 'merged') ? zget($lang->mr->statusList, $MR->status) : zget($lang->mr->mergeStatusList, $MR->mergeStatus);?> approvalStatus) ? $lang->mr->approvalStatusList['notReviewed'] : $lang->mr->approvalStatusList[$MR->approvalStatus];?>createdBy);?>createdDate;?> - user->admin or (isset($openIDList[$MR->hostID]) and isset($projects[$MR->hostID][$MR->sourceProject]->owner->id) and $projects[$MR->hostID][$MR->sourceProject]->owner->id == $openIDList[$MR->hostID])) ? '' : 'disabled'; - if($repo->SCM == 'Gitlab') - { - $canEdit = (isset($projects[$MR->hostID][$MR->sourceProject]->isDeveloper) and $projects[$MR->hostID][$MR->sourceProject]->isDeveloper == true) ? '' : 'disabled'; - } - elseif($repo->SCM == 'Gitea') - { - $canEdit = (isset($projects[$MR->hostID][$MR->sourceProject]->allow_merge_commits) and $projects[$MR->hostID][$MR->sourceProject]->allow_merge_commits == true) ? '' : 'disabled'; - } - elseif($repo->SCM == 'Gogs') - { - $canEdit = (isset($projects[$MR->hostID][$MR->sourceProject]->permissions->push) and $projects[$MR->hostID][$MR->sourceProject]->permissions->push) ? '' : 'disabled'; - } - common::printLink('mr', 'view', "MRID={$MR->id}", '', '', "title='{$lang->mr->view}' class='btn btn-info'"); - common::printIcon('mr', 'edit', "MRID={$MR->id}", $MR, 'list', '', '', $canEdit); - common::printLink('mr', 'diff', "MRID={$MR->id}", '', '', "title='{$lang->mr->viewDiff}' class='btn btn-info'"); - common::printLink('mr', 'link', "MRID={$MR->id}", '', '', "title='{$lang->mr->link}' class='btn btn-info'" . ($MR->linkButton == false ? 'disabled' : '')); - common::printLink('mr', 'delete', "MRID={$MR->id}", '', 'hiddenwin', "title='{$lang->mr->delete}' class='btn btn-info {$canDelete}'"); - ?> -
      - -
      - -
      - diff --git a/module/mr/view/create.html.php b/module/mr/view/create.html.php deleted file mode 100644 index c66a2d8208..0000000000 --- a/module/mr/view/create.html.php +++ /dev/null @@ -1,109 +0,0 @@ - - - - - -mr);?> - -
      -
      -
      -
      -

      mr->create;?>

      -
      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      mr->server;?>
      mr->sourceProject;?> -
      - - mr->sourceBranch ?> - -
      -
      mr->targetProject;?> -
      - - mr->targetBranch ?> - -
      -
      mr->title;?>
      mr->description;?>
      devops->repo;?>
      mr->removeSourceBranch;?> -
      - - -
      -
      mr->needCI;?> -
      - - -
      -
      mr->squash;?> -
      - - -
      -
      mr->assignee;?>
      - - goback, '', 'class="btn btn-wide"');?> -
      -
      -
      -
      -
      - diff --git a/module/mr/view/diff.html.php b/module/mr/view/diff.html.php deleted file mode 100644 index 4deebc335e..0000000000 --- a/module/mr/view/diff.html.php +++ /dev/null @@ -1,172 +0,0 @@ - - - - - - -
      -
      - - -
      - - - - synced and (empty($rawMR) or !isset($rawMR->id))): ?> -
      -
      -

      - mr->notFound; ?> - createLink('mr', 'browse'), " " . $lang->mr->browse, '', "class='btn btn-info'"); ?> -

      -
      -
      - - -
      -
      -
      -
      - repo->viewDiffList['inline'], "id='inline'", $arrange == 'inline' ? 'active btn btn-sm' : 'btn btn-sm')?> - repo->viewDiffList['appose'], "id='appose'", $arrange == 'appose' ? 'active btn btn-sm' : 'btn btn-sm')?> -
      -
      -
      -
      - - repo->encodingList, $encoding, $lang->repo->encodingList['utf_8']) . "", "data-toggle='dropdown'", 'btn dropdown-toggle btn-sm')?> - -
      -
      -
      - -
      -
      - -
      - - - contents)) continue;?> - contents as $content):?> - oldStartLine; - $newCurrentLine = $content->newStartLine; - ?> - - - - - - - - - - - - lines as $line):?> - - - - - - - - lines as $line):?> - - type == 'old') - { - $oldlc = $line->oldlc; - $newlc = ''; - if(isset($content->new[$oldlc])) - { - $newlc = $line->oldlc; - $line->type = 'custom'; - } - } - else - { - $oldlc = $line->oldlc; - $newlc = $line->newlc; - if(!isset($content->new[$newlc])) continue; - } - ?> - - - - - old[$oldlc])) unset($content->old[$oldlc]); - if(isset($content->new[$newlc])) unset($content->new[$newlc]); - ?> - - - - -
      fileName;?>
      ......
      type != 'new') echo $line->oldlc?>type != 'old') echo $line->newlc?>type == 'old' ? preg_replace('/^\-/', '–', $line->line) : ($line->type == 'new' ? $line->line : ' ' . $line->line); - ?>
      type?> type == 'custom') echo "line-old"?> code'>old[$oldlc])) $content->old[$oldlc] = ''; - if(!empty($oldlc)) echo $line->type != 'all' ? preg_replace('/^\-/', '–', $content->old[$oldlc]) : ' ' . $content->old[$oldlc]; - ?>type?> type == 'custom') echo "line-new"?> code'>new[$newlc])) $content->new[$newlc] = ''; - if(!empty($newlc)) echo $line->type != 'all' ? $content->new[$newlc] : ' ' . $content->new[$newlc]; - ?>
      -
      - -
      - mr->noChanges;?> - - -
      - - {$lang->mr->noChanges}

      "; - } - else - { - include '../../repo/view/diffeditor.html.php'; - } - ?> - -
      -
      - diff --git a/module/mr/view/edit.html.php b/module/mr/view/edit.html.php deleted file mode 100644 index c3f7d53a9d..0000000000 --- a/module/mr/view/edit.html.php +++ /dev/null @@ -1,133 +0,0 @@ - - -hostID);?> -sourceProject);?> - -id)): ?> -
      -
      -

      - mr->notFound;?> - createLink('mr', 'browse'), " " . $lang->mr->browse, '', "class='btn btn-info'");?> -

      -
      -
      - - -
      -
      -
      -
      -

      mr->edit;?>

      -
      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      mr->server;?>loadModel('pipeline')->getByID($MR->hostID)->name;?>
      mr->sourceProject;?> -
      - - type == 'gitlab' ? $this->loadModel('gitlab')->apiGetSingleProject($MR->hostID, $MR->sourceProject)->name_with_namespace : $MR->sourceProject;?>: - sourceBranch;?> - -
      -
      mr->targetProject;?> -
      - status == 'merged' or $MR->status == 'closed' or $host->type == 'gogs'):?> - - type == 'gitlab' ? $this->loadModel('gitlab')->apiGetSingleProject($MR->hostID, $MR->targetProject)->name_with_namespace : $MR->targetProject;?>: - targetBranch;?> - - - - type == 'gitlab' ? $this->loadModel('gitlab')->apiGetSingleProject($MR->hostID, $MR->targetProject)->name_with_namespace : $MR->targetProject;?>: - - targetBranch, "class='form-control chosen'");?> - -
      -
      mr->title;?>title, "class='form-control'");?>
      mr->description;?>description, "rows='3' class='form-control'");?>
      devops->repo;?>repoID, "class='form-control chosen'");?>
      mr->removeSourceBranch;?> - canDeleteBranch and $MR->removeSourceBranch == '1') $attr .= 'checked '; - if(!$MR->canDeleteBranch) $attr .= 'disabled'; - ?> -
      - name="removeSourceBranch" value="1" id="removeSourceBranch"> - -
      -
      mr->needCI;?> -
      - needCI == '1' ? 'checked' : '' ?> - name="needCI" value="1" id="needCI"> - -
      -
      job->common;?>jobID, "class='form-control chosen'");?>
      mr->squash;?> -
      - squash == '1' ? 'checked' : '' ?> - name="squash" value="1" id="squash"> - -
      -
      mr->assignee;?>
      - - goback, '', 'class="btn btn-wide"');?> -
      -
      -
      -
      -
      - diff --git a/module/mr/view/link.html.php b/module/mr/view/link.html.php deleted file mode 100644 index a15a7b0aff..0000000000 --- a/module/mr/view/link.html.php +++ /dev/null @@ -1,270 +0,0 @@ - - - - -productplan->confirmUnlinkStory)?> -productplan->confirmUnlinkBug)?> -mr->confirmUnlinkTask)?> -id);?> -id);?> -pageID);?> -recPerPage);?> -recTotal);?> - -
      -
      - -
      -
      '> - -
      - id, \"story\")", ' ' . $lang->productplan->linkStory, '', "class='btn btn-primary'");?> -
      - -
      id&orderBy=$orderBy");?>"> - - id}&type=story&orderBy=%s&link=$link¶m=$param"; - ?> - - - - - - - - - - - - - - - - - - - - - createLink('story', 'view', "storyID=$story->id", '', true); - $totalEstimate += $story->estimate; - ?> - - - - - - - - - - - - - - - -
      - idAB);?> - productplan->updateOrder);?>pri;?>>priAB);?>story->module);?>story->title);?> openedByAB);?> assignedToAB);?> story->estimateAB);?> statusAB);?> story->stageAB);?> actions?>
      - id);?> - pri;?>' title='story->priList, $story->pri, $story->pri);?>'>story->priList, $story->pri, $story->pri);?>module, '');?> - parent > 0) echo "story->children}>{$lang->story->childrenAB}"; - echo html::a($viewLink , $story->title, '', 'class="iframe"'); - ?> - openedBy);?>assignedTo);?>estimate . $config->hourUnit;?> - - processStatus('story', $story);?> - - story->stageList[$story->stage];?> - createLink('mr', 'unlink', "MRID=$MR->id&productID=$product->id&type=story&linkID=$story->id&confirm=yes"); - echo html::a("javascript:ajaxDelete(\"$unlinkURL\", \"storyList\", confirmUnlinkStory)", '', '', "class='btn' title='{$lang->productplan->unlinkStory}'"); - } - ?> -
      - - - -
      -
      -
      '> -
      - id, \"bug\")", ' ' . $lang->productplan->linkBug, '', "class='btn btn-primary'");?> -
      - -
      id&orderBy=$orderBy");?>"> - - - id}&type=bug&orderBy=%s&link=$link¶m=$param"; ?> - - - - - - - - - - - - - - - - - - - - - - - - -
      - idAB);?> - pri;?>> priAB);?>bug->title);?> openedByAB);?> bug->assignedToAB);?>bug->status);?> actions?>
      - id);?> - bug->priList, $bug->pri, $bug->pri);?>createLink('bug', 'view', "bugID=$bug->id", '', true), $bug->title, '', 'class="iframe"');?>openedBy);?>assignedTo);?> - - processStatus('bug', $bug);?> - - - createLink('mr', 'unlink', "MRID=$MR->id&productID=$product->id&type=bug&linkID=$bug->id&confirm=yes"); - echo html::a("javascript:ajaxDelete(\"$unlinkURL\", \"bugList\", confirmUnlinkBug)", '', '', "class='btn' title='{$lang->productplan->unlinkBug}'"); - } - ?> -
      - - - -
      -
      -
      '> -
      - id, \"task\")", ' ' . $lang->mr->linkTask, '', "class='btn btn-primary'");?> -
      - -
      id&orderBy=$orderBy");?>"> - - - id}&type=task&orderBy=%s&link=$link¶m=$param"; ?> - - - - - - - - - - - - - - - - - - - - - - - - -
      - idAB);?> - pri;?>> priAB);?>task->name);?> task->finishedByAB);?> task->assignedToAB);?>task->status);?> actions?>
      - id);?> - task->priList, $task->pri, $task->pri);?>createLink('task', 'view', "taskID=$task->id", '', true), $task->name, '', 'class="iframe"');?>finishedBy);?>assignedTo);?> - - processStatus('task', $task);?> - - - createLink('mr', 'unlink', "MRID=$MR->id&productID=$product->id&type=task&linkID=$task->id&confirm=yes"); - echo html::a("javascript:ajaxDelete(\"$unlinkURL\", \"taskList\", confirmUnlinkTask)", '', '', "class='btn' title='{$lang->mr->unlinkTask}'"); - ?> -
      - - - -
      -
      -
      -
      -
      - - - - - diff --git a/module/mr/view/linkbug.html.php b/module/mr/view/linkbug.html.php deleted file mode 100644 index 85bd3b5e50..0000000000 --- a/module/mr/view/linkbug.html.php +++ /dev/null @@ -1,79 +0,0 @@ - - * @package mr - * @version $Id: linkbug.html.php$ - * @link https://www.zentao.net - */ -?> -
      -
      -
      id&browseType=$browseType¶m=$param&orderBy=$orderBy")?>'> -
      - productplan->unlinkedBugs;?> -
      - - - - - - - - - - - - - - - - - - - - - - - - - -
      - -
      - -
      - - idAB;?> -
      pri;?>>priAB;?>bug->title;?>openedByAB;?>bug->assignedToAB;?>bug->status;?>
      - id => sprintf('%03d', $bug->id)), $relatedBugs);?> - bug->priList, $bug->pri, $bug->pri)?>createLink('bug', 'view', "bugID=$bug->id", '', true), $bug->title, '', "data-toggle='modal' data-type='iframe' data-width='90%'");?>openedBy);?>assignedTo);?> - - processStatus('bug', $bug);?> - -
      - -
      -
      - diff --git a/module/mr/view/linkstory.html.php b/module/mr/view/linkstory.html.php deleted file mode 100644 index a674b2f309..0000000000 --- a/module/mr/view/linkstory.html.php +++ /dev/null @@ -1,92 +0,0 @@ - -
      -
      -
      id&browseType=$browseType¶m=$param&orderBy=$orderBy")?>"> -
      - productplan->unlinkedStories;?> -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      - -
      - -
      - - idAB;?> -
      pri;?>>priAB;?>story->plan;?>story->module;?>story->title;?>openedByAB;?>assignedToAB;?>story->estimateAB;?>statusAB;?>story->stageAB;?>
      - id => sprintf('%03d', $story->id)), $relatedStories);?> - pri;?>' title='story->priList, $story->pri, $story->pri)?>'>story->priList, $story->pri, $story->pri)?>planTitle;?>' class='text-left'>module, '/');?> - parent > 0) echo "story->children}>{$lang->story->childrenAB}"; - echo html::a($this->createLink('story', 'view', "storyID=$story->id", '', true), $story->title, '', "data-toggle='modal' data-type='iframe' data-width='90%'"); - ?> - openedBy);?>assignedTo);?>estimate . $config->hourUnit;?> - - processStatus('story', $story);?> - - story->stageList[$story->stage];?>
      - -
      -
      - diff --git a/module/mr/view/linktask.html.php b/module/mr/view/linktask.html.php deleted file mode 100644 index e7fd954843..0000000000 --- a/module/mr/view/linktask.html.php +++ /dev/null @@ -1,79 +0,0 @@ - - * @package mr - * @version $Id: linktask.html.php$ - * @link https://www.zentao.net - */ -?> -
      -
      -
      id&browseType=$browseType¶m=$param&orderBy=$orderBy")?>'> -
      - mr->unlinkedTasks;?> -
      - - - - - - - - - - - - - - - - - - - - - - - - - -
      - -
      - -
      - - idAB;?> -
      pri;?>>priAB;?>task->name;?>task->finishedByAB;?>task->assignedToAB;?>task->status;?>
      - id => sprintf('%03d', $task->id)), $relatedTasks);?> - task->priList, $task->pri, $task->pri)?>createLink('task', 'view', "taskID=$task->id", '', true), $task->name, '', "data-toggle='modal' data-type='iframe' data-width='90%'");?>finishedBy);?>assignedTo);?> - - processStatus('task', $task);?> - -
      - -
      -
      - diff --git a/module/mr/view/view.html.php b/module/mr/view/view.html.php deleted file mode 100644 index b22dd9df96..0000000000 --- a/module/mr/view/view.html.php +++ /dev/null @@ -1,182 +0,0 @@ - -id)): ?> -
      -
      -

      - mr->notFound;?> - - createLink('mr', 'create'), " " . $lang->mr->create, '', "class='btn btn-info'"); ?> - -

      -
      -
      - -synced and (empty($rawMR) or !isset($rawMR->id))): ?> -
      -
      -

      - mr->notFound; ?> - createLink('mr', 'browse'), " " . $lang->mr->browse, '', "class='btn btn-info'"); ?> -

      -
      -
      - - - -
      -
      - -
      -
      -
      -
      -
      - - - - - - - - - - - - - - - synced and empty($rawMR->changes_count)):?> - - - - - - - - synced === '1' ? $rawMR->has_conflicts : (bool)$MR->hasNoConflict;?> - - - - - - - -
      - status == 'merged' and $MR->removeSourceBranch == '1') ? 'disabled' : '';?> - mr->from . html::a($sourceProjectURL, $sourceProjectName . ":" . $MR->sourceBranch, "_blank", "class='btn btn-link btn-active-text' style='color: blue' $sourceDisabled") . $lang->mr->to . html::a($targetProjectURL, $targetProjectName . ":" . $MR->targetBranch, "_blank", "class='btn btn-link btn-active-text' style='color: blue'"); ?> -
      mr->status;?> - syncError) and $MR->synced === '0'):?> - syncError;?> - - mr->statusList, $MR->status);?> - -
      mr->mergeStatus; ?> - mr->cantMerge; ?> - synced) echo '' . $lang->mr->noChanges . '';?> - mr->mergeStatusList, !empty($rawMR->merge_status) ? $rawMR->merge_status : $MR->mergeStatus);?>
      mr->MRHasConflicts; ?>mr->hasConflicts : $lang->mr->hasNoConflict);?>
      mr->description;?> - description) ? $MR->description : $lang->noData; ?> -
      - -
      -
      -
      - - synced and $rawMR->state == 'opened'): ?> -
      mr->commandDocument, $httpRepoURL, $MR->sourceBranch, $branchPath, $MR->targetBranch, $branchPath, $MR->targetBranch); ?>
      - - - app->getViewType() != 'xhtml'):?> -
      - - -
      -
      - - approvalStatus != 'approved' or (!empty($compile->id) and $compile->status != 'success')) ? ' disabled' : ''; ?> - synced and $rawMR->state == 'opened' and !$rawMR->has_conflicts) common::printIcon('mr', 'accept', "mr=$MR->id", $MR, 'button', 'flow', 'hiddenwin', 'mergeButton btn', false, $acceptDisabled, $lang->mr->acceptMR);?> - synced and $rawMR->state == 'opened'): ?> - has_conflicts or (!empty($compile->id) and $compile->status != 'success') or $MR->approvalStatus == 'approved'):?> - id&action=approve", $MR, 'button', 'ok', 'hiddenwin', 'mergeButton', true, 'disabled', $lang->mr->approve);?> - - id&action=approve", $MR, 'button', 'ok', 'hiddenwin', 'mergeButton btn iframe showinonlybody', true, '', $lang->mr->approve);?> - - id&action=reject", $MR, 'button', 'bug', 'hiddenwin', 'mergeButton btn iframe showinonlybody', true, ($MR->approvalStatus == 'rejected' ? 'disabled' : ''), $lang->mr->reject);?> - id", $MR, 'button', 'off', 'hiddenwin', 'mergeButton');?> - id", $MR, 'button', 'edit');?> - - synced and $rawMR->state == 'closed') common::printIcon('mr', 'reopen', "mr=$MR->id", $MR, 'button', 'restart', 'hiddenwin', 'mergeButton'); ?> - id", $MR, 'button', 'trash', 'hiddenwin');?> -
      -
      -
      - -
      -
      -
      - compile->job;?> -
      - compileID):?> - - - - app->getClientLang(), array('zh-cn','zh-tw')) ? 'w-90px' : 'w-100px'; ?> - - - - - - - - id)):?> - - - - - - -
      job->common;?>name;?>
      compile->atTime;?>createdDate;?>
      compile->result;?> - compile->statusList, $compile->status);?>    - createLink('job', 'view', "jobID=$compileJob->id&compileID=$compile->id", '', true), "{$lang->compile->logs}", "", "class='iframe'");?> -
      - needCI):?> - createLink('job', 'view', "jobID={$MR->jobID}");?> -
      compile->statusList[$MR->compileStatus], '_blank');?>
      - -
      mr->noCompileJob;?>
      - -
      -
      -
      -
      -
      -
      -
      - - - - diff --git a/module/my/view/audit.html.php b/module/my/view/audit.html.php deleted file mode 100644 index 0730d32667..0000000000 --- a/module/my/view/audit.html.php +++ /dev/null @@ -1,167 +0,0 @@ -getModuleRoot() . 'common/view/header.html.php'?> - -recTotal);?> -rawMethod);?> - -
      - -
      -

      - noData;?> -

      -
      - -
      - - - recTotal&recPerPage=$pager->recPerPage&pageID=$pager->pageID"; - if($rawMethod == 'contribute') $vars = "mode=$mode&browseType=$browseType¶m=&orderBy=%s&recTotal=$pager->recTotal&recPerPage=$pager->recPerPage&pageID=$pager->pageID"; - ?> - - - - - - - - - - - - - - - - - type; - if($type == 'projectreview') $type = 'review'; - - $typeName = ''; - if(isset($lang->{$review->type}->common)) $typeName = $lang->{$review->type}->common; - if($type == 'story') $typeName = $review->storyType == 'story' ? $lang->SRCommon : $lang->URCommon; - if($review->type == 'projectreview') $typeName = $lang->project->common; - if(isset($flows[$review->type])) $typeName = $flows[$review->type]; - - $statusList = array(); - if(isset($lang->$type->statusList)) $statusList = $lang->$type->statusList; - if($type == 'attend') $statusList = $lang->attend->reviewStatusList; - if(!in_array($type, array('demand', 'story', 'testcase', 'feedback', 'review')) and strpos(",{$config->my->oaObjectType},", ",$type,") === false) - { - if($rawMethod == 'audit') $statusList = $lang->approval->nodeList; - if(isset($flows[$review->type])) $statusList = $rawMethod == 'audit' ? $lang->approval->nodeList : $lang->approval->statusList; - } - ?> - - - - - - - $type))$reviewResultList = zget($lang->$type, 'reviewResultList', array()); - if(strpos(",{$config->my->oaObjectType},", ",$type,") !== false) $reviewResultList = zget($lang->$type, 'reviewStatusList', array()); - ?> - - - - - - - - - -
      idAB);?>my->auditField->title) : common::printOrderLink('title', $orderBy, $vars, $lang->my->auditField->title);?> my->auditField->type);?> my->auditField->time);?> my->auditField->result);?> my->auditField->status) : common::printOrderLink('status', $orderBy, $vars, $lang->my->auditField->status);?>actions?>
      id?> - title; - if($type == 'attend') - { - $titleHtml = html::a($this->createLink($type, 'review', "objectID=$review->id", 'html', true), $review->title, '', "data-toggle='modal'"); - } - else - { - $class = "class='iframe' data-width='90%'"; - if(strpos(",{$config->my->oaObjectType},", ",{$type},") !== false) $class = "data-toggle='modal'"; - $titleHtml = html::a($this->createLink($type, 'view', "objectID=$review->id", 'html', true), $review->title, '', $class); - } - echo $titleHtml; - ?> - time, 0, 19);?>result);?>status, '');?> - id"; - - $reviewIcon = ''; - $passIcon = ''; - $rejectIcon = ''; - - if($module == 'review') - { - $method = 'assess'; - $params = "reviewID=$review->id&from={$rawMethod}"; - common::printLink($module, $method, $params, $reviewIcon, '', "class='btn' title='{$lang->review->common}'"); - } - elseif($module == 'attend') - { - common::printLink($module, 'review', "attendID={$review->id}&status=", $reviewIcon, '', "class='btn' data-toggle='modal' title='{$lang->review->common}'", true, true); - } - elseif(strpos(",{$config->my->oaObjectType},", ",$module,") !== false) - { - common::printLink($module, 'view', $params, $reviewIcon, '', "class='btn' data-toggle='modal' title='{$lang->review->common}'", true, true); - } - elseif(!in_array($module, array('demand', 'story', 'testcase', 'feedback'))) - { - common::printLink($module, 'approvalreview', $params, $reviewIcon, '', "class='btn' data-toggle='modal' title='{$lang->review->common}'", true, true); - } - else - { - common::printLink($module, $method, $params, $reviewIcon, '', "class='btn iframe' title='{$lang->review->common}'", true, true); - } - ?> -
      - -
      - -
      -my->confirmReview);?> - -getModuleRoot() . 'common/view/footer.html.php'?> diff --git a/module/my/view/bug.html.php b/module/my/view/bug.html.php deleted file mode 100644 index fac1135e83..0000000000 --- a/module/my/view/bug.html.php +++ /dev/null @@ -1,229 +0,0 @@ - - * @package dashboard - * @version $Id: bug.html.php 5107 2013-07-12 01:46:12Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -recTotal);?> -rawMethod);?> - -
      - rawMethod == 'work' ? 'workBug' : 'contributeBug';?> -
      >
      - -
      -

      bug->notice->noBug;?>

      -
      - -
      '> - - - - session->myBugType : $type;?> - - - - - - - - - - - - - - rawMethod == 'work'):?> - - - - - - - - - - - - - bug->severityList as $severityKey => $severityValue) - { - if(!empty($severityKey) and (string)$severityKey != (string)$severityValue) - { - $hasCustomSeverity = true; - break; - } - } - ?> - - - - - - - - - - - - - - - rawMethod == 'work'):?> - - - - - - - - - - - - - -
      - -
      - -
      - - idAB);?> -
      bug->title);?>bug->abbr->severity);?>priAB);?>bug->type);?>bug->product);?>bug->abbr->openedBy);?>bug->abbr->confirmed);?>bug->deadline);?>bug->assignedTo);?>bug->resolvedBy);?>bug->abbr->resolution);?>actions;?>
      - -
      - /> - -
      - - id);?> -
      - createLink('bug', 'view', "bugID=$bug->id"), $bug->title, null, "style='color: $bug->color' title='{$bug->title}'");?> - case) echo html::a(helper::createLink('testcase', 'view', "caseID=$bug->case&version=$bug->caseVersion"), "[" . $this->lang->testcase->common . "#$bug->case]", '', "class='bug' title='$bug->case'");?> - - - ' title='bug->severityList, $bug->severity);?>' data-severity='severity;?>'>bug->severityList, $bug->severity, $bug->severity);?> - - ' data-severity='severity;?>' title='bug->severityList, $bug->severity);?>'> - - pri?>' title='bug->priList, $bug->pri);?>'>bug->priList, $bug->pri)?>bug->typeList, $bug->type, '');?> - shadow) and !empty($bug->shadow)) - { - echo html::a($this->createLink('project', 'browse'), $bug->productName, null, "title={$bug->productName}"); - } - else - { - $productLink = explode('-', $config->productLink); - $param = $config->productLink == 'product-all' ? '' : "productID=$bug->product"; - echo html::a($this->createLink('product', $productLink[1], $param), $bug->productName, null, "title={$bug->productName}"); - } - ?> - openedBy);?>' title='bug->confirmedList, $bug->confirmed);?>'>bug->confirmedList, $bug->confirmed)?>deadline, 0, 4) > 0) echo '' . substr($bug->deadline, 5, 6) . '';?>bug->printAssignedHtml($bug, $users);?>resolvedBy);?>bug->resolutionList, $bug->resolution);?> - id"; - common::printIcon('bug', 'confirm', $params, $bug, 'list', 'ok', '', 'iframe', true, '', '', $bug->project); - common::printIcon('bug', 'resolve', $params, $bug, 'list', 'checked', '', 'iframe', true, '', '', $bug->project); - common::printIcon('bug', 'close', $params, $bug, 'list', '', '', 'iframe', true, '', '', $bug->project); - common::printIcon('bug', 'edit', $params, $bug, 'list', '', '', 'iframe', true, "data-width='95%'", '', $bug->project); - common::printIcon('bug', 'create', "product=$bug->product&branch=$bug->branch&extra=$params", $bug, 'list', 'copy', '', 'iframe', true, "data-width='95%'", '', $bug->project); - } - ?> -
      -
      - - diff --git a/module/my/view/changepassword.html.php b/module/my/view/changepassword.html.php deleted file mode 100644 index afa3a581ef..0000000000 --- a/module/my/view/changepassword.html.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @package user - * @version $Id: editprofile.html.php 2605 2012-02-21 07:22:58Z wwccss $ - * @link https://www.zentao.net - */ -?> - - - - - -
      -
      -

      my->changePassword;?>

      -
      -
      - - - - - - - - - - - - - - - - - - - - -
      user->account;?>account . html::hidden('account',$user->account);?>
      user->originalPassword;?>
      user->newPassword;?> - - user->placeholder->passwordStrength, $config->safe->mode, '') . "'");?> - - -
      user->password2;?>
      - - -
      - app->user->modifyPasswordReason)):?> - app->loadLang('admin');?> -
      - app->user->modifyPasswordReason;?> - admin->safe->common . ' : ';?> - admin->safe->changeWeak : $lang->admin->safe->$reason;?> -
      - -
      - -
      -user->passwordStrengthList)?> - - diff --git a/module/my/view/doc.html.php b/module/my/view/doc.html.php deleted file mode 100644 index 5c55a5cee1..0000000000 --- a/module/my/view/doc.html.php +++ /dev/null @@ -1,107 +0,0 @@ - - * @package my - * @version $Id - * @link https://www.zentao.net - */ -?> - - - -
      - -
      >
      -
      -

      - doc->noDoc;?> -

      -
      - -
      >
      -
      - - - - - - - - - - - - - - - - - - - - collector, ',' . $this->app->user->account . ',') !== false ? 'star' : 'star-empty';?> - collector, ',' . $this->app->user->account . ',') !== false ? $lang->doc->cancelCollection : $lang->doc->collect;?> - - - - - - - - - - - - - - - - -
      doc->id;?>doc->title;?>doc->object;?>doc->addedByAB;?>doc->addedDate;?>doc->editedBy;?>doc->editedDate;?>actions;?>
      id;?> - type == 'text' ? 'wiki-file' : $doc->type; - $icon = html::image("static/svg/{$docType}.svg", "class='file-icon'"); - if(common::hasPriv('doc', 'view')) - { - echo html::a($this->createLink('doc', 'view', "docID=$doc->id"), $icon . $doc->title, '', "title='{$doc->title}' class='doc-title' data-app='doc'"); - } - else - { - echo "$icon {$doc->title}"; - } - ?> - status == 'draft') echo "{$lang->doc->draft}";?> - - id&objectType=doc");?>" title="" class='btn btn-link ajaxCollect'> - - - doc->objectIconList, $doc->objectType);?> - " . $doc->objectName;?> - addedBy);?>addedDate, 'Y-m-d');?>editedBy);?>editedDate, 'Y-m-d');?> - - id&comment=false&from={$lang->navGroup->doc}", "", '', "title='{$lang->edit}' class='btn' data-app='doc'", true, false)?> - id&confirm=no&from={$lang->navGroup->doc}", "", 'hiddenwin', "title='{$lang->delete}' class='btn'")?> - -
      - -
      - -
      - diff --git a/module/my/view/dynamic.html.php b/module/my/view/dynamic.html.php deleted file mode 100644 index 22a102bec9..0000000000 --- a/module/my/view/dynamic.html.php +++ /dev/null @@ -1,126 +0,0 @@ -dynamic view file of dashboard module of ZenTaoPMS. - * - * @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com) - * @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html) - * @author Chunsheng Wang - * @package dashboard - * @version $Id: action->dynamic.html.php 1477 2011-03-01 15:25:50Z wwccss $ - * @link https://www.zentao.net - */ -?> - - -
      -
      - -
      -

      action->noDynamic;?>

      -
      - - - $actions):?> - -
      -
      - - action->dynamic->today;?> - - - -
      -
        - - $action):?> - action == 'adjusttasktowait') continue;?> - - major ? 'active' : '';?> - action, array('releaseddoc', 'collected'))) $class .= " {$action->action}";?> -
      • major) echo "class='$class'";?>> -
        - time?> - - user->realname;?> - actionLabel;?> - action != 'login' and $action->action != 'logout'):?> - objectLabel;?> - objectID):?> - objectType,") !== false and strpos(',created,edited,moved,', "$action->action") !== false) ? trim($action->extra, ',') : $action->objectID;?> - - - objectType == 'meeting') $tab = $action->project ? "data-app='project'" : "data-app='my'";?> - - edition, array('max', 'ipd')) and strpos($config->action->assetType, ",{$action->objectType},") !== false) and empty($action->objectName)) - { - echo '#' . $action->objectID; - } - elseif(empty($action->objectID) and $action->extra) - { - echo $action->extra; - } - elseif(empty($action->objectLink)) - { - echo $action->objectName; - } - else - { - echo html::a($action->objectLink, $action->objectName, '', $tab); - } - ?> - - - -
        -
      • - -
      -
      - - -
      -
      - -originalDate) + 24 * 3600); -$lastDate = substr($action->originalDate, 0, 10); -$hasPre = $this->action->hasPreOrNext($firstDate, 'pre'); -$hasNext = $this->action->hasPreOrNext($lastDate, 'next'); -$preLink = $hasPre ? inlink('dynamic', "type=$type&recTotal={$pager->recTotal}&date=" . strtotime($firstDate) . '&direction=pre&originTotal=' . $originTotal) : 'javascript:;'; -$nextLink = $hasNext ? inlink('dynamic', "type=$type&recTotal={$pager->recTotal}&date=" . strtotime($lastDate) . '&direction=next&originTotal=' . $originTotal) : 'javascript:;'; -?> - -
      - -
      - - - - diff --git a/module/my/view/editprofile.html.php b/module/my/view/editprofile.html.php deleted file mode 100644 index f33cfea2aa..0000000000 --- a/module/my/view/editprofile.html.php +++ /dev/null @@ -1,104 +0,0 @@ - - * @package user - * @version $Id: editprofile.html.php 4728 2013-05-03 06:14:34Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - -
      -
      -

      my->editProfile;?>

      -
      -
      - - - - - - - - - - - - - - -
      my->form->lblBasic;?>
      user->realname;?>realname, "class='form-control'");?>user->email;?>email, "class='form-control'");?>
      user->gender;?>user->genderList, $user->gender);?>user->birthyear;?>birthday,"class='form-date form-control'");?>
      - - - - - - - - - - - - - - -
      my->form->lblAccount;?>
      user->account;?>account, "class='form-control' readonly='readonly'");?>user->commiter;?>commiter, "class='form-control'");?>
      user->password;?> - - - safe->mode) ? $lang->user->placeholder->passwordStrength[$config->safe->mode] : '') . "'");?> - - - user->password2;?>
      - - - user->contactField)):?> - - user->contactField) as $field):?> - ';?> - - - - ';?> - - - - - - - - -
      my->form->lblContact;?>
      >user->$field;?>$field, "class='form-control'");?>
      user->address;?>address, "class='form-control'");?>user->zipcode;?>zipcode, "class='form-control'");?>
      - - - - - - -
      user->verify;?>
      user->verifyPassword;?> -
      - user->placeholder->verify}'");?> -
      - visions, "class='form-control chosen' multiple");?> -
      -
      - -
      -user->passwordStrengthList)?> - - diff --git a/module/my/view/execution.html.php b/module/my/view/execution.html.php deleted file mode 100644 index c69703f397..0000000000 --- a/module/my/view/execution.html.php +++ /dev/null @@ -1,93 +0,0 @@ - - * @package my - * @version $Id - * @link https://www.zentao.net - */ -?> - - - -
      - -
      -

      - noData;?> -

      -
      - - - - - - - - - - - - - - - - - - - id]);?> - createLink('execution', 'browse', "id=$execution->id", '', '', $execution->project);?> - - - - - - - - - - - - - - -
      idAB;?>my->name;?>statusAB;?>team->roleAB;?>execution->myTask;?>execution->begin;?>execution->end;?>team->join;?>my->hours;?>execution->progress;?>
      id) : html::a($link, sprintf('%03d', $execution->id));?> - systemMode == 'ALM'):?> - type === 'stage') echo "{$lang->project->stage} "; - if($execution->type === 'sprint') echo "{$lang->executionCommon} "; - if($execution->type === 'kanban') echo "{$lang->execution->kanban} "; - ?> - - name : html::a($link, $execution->name, '', "title='$execution->name'");?> - - delay)):?> - execution->delayed;?> - - processStatus('project', $execution);?> - - - role;?>assignedToMeTasks;?>begin;?>end;?>join;?>hours;?> -
      -
      progress;?>
      -
      -
      - - -
      - diff --git a/module/my/view/feedback.html.php b/module/my/view/feedback.html.php deleted file mode 100644 index 6680425a02..0000000000 --- a/module/my/view/feedback.html.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @package my - * @version $Id - * @link https://www.zentao.net - */ -?> -getModuleRoot() . 'common/view/header.html.php';?> - -recTotal);?> -rawMethod);?> - - - - - - - -
      -
      createLink('search', 'buildOldForm', 'module=workFeedback');?>>
      - -
      -

      feedback->noFeedback;?>

      -
      - - - -
      -getModuleRoot() . 'common/view/footer.html.php';?> diff --git a/module/my/view/managecontacts.html.php b/module/my/view/managecontacts.html.php deleted file mode 100644 index d936db7801..0000000000 --- a/module/my/view/managecontacts.html.php +++ /dev/null @@ -1,101 +0,0 @@ - - * @package my - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
      -
      -

      my->contactList;?>

      -
      - ' . $lang->user->contacts->createList, '', "class='btn btn-secondary createBtn'"); ?> - $listName) - { - $listClass = ($id == $listID and $mode == 'edit') ? 'btn btn-block active' : 'btn btn-block'; - echo html::a(inlink('managecontacts', "listID=$id&mode=edit"), $listName, '', "class='{$listClass}' title='$listName'"); - } - ?> -
      -
      -
      -
      -

      - - user->contacts->createList;?> - - user->contacts->manage;?> - -

      -
      - -
      - - - - - - - - - - - - - - - - - id, $disabled)):?> - - - - - -
      user->contacts->listName;?> -
      - id, $disabled) ? ' readonly' : ''; - if($mode == 'new') - { - echo html::input('newList', '', "class='form-control'"); - } - else - { - echo html::input('listName', $list->listName, "$readonly class='form-control'"); - echo html::hidden('listID', $list->id); - } - ?> -
      user->contacts->selectedUsers;?> - userList, "multiple $readonly class='form-control picker' data-drop_direction='down'"); - } - ?> -
      - -
      - - delete, 'hiddenwin', "class='btn btn-danger btn-wide'");?> -
      -
      - -
      - -
      - diff --git a/module/my/view/preference.html.php b/module/my/view/preference.html.php deleted file mode 100644 index 31f7a30e99..0000000000 --- a/module/my/view/preference.html.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @package user - * @version $Id: editprofile.html.php 2605 2012-02-21 07:22:58Z wwccss $ - * @link https://www.zentao.net - */ -?> - - -
      -
      -

      my->preference;?>

      -
      -
      - - - - - - config->systemMode == 'ALM'):?> - - - - - - - - - - - - - - - - - - - - -
      my->storyConcept;?>
      my->programLink;?>my->programLinkList, $programLink, "class='form-control picker programLink'");?>
      my->productLink;?>my->productLinkList, $productLink, "class='form-control picker productLink'");?>
      my->projectLink;?>my->projectLinkList, $projectLink, "class='form-control picker projectLink'");?>
      my->executionLink;?>my->executionLinkList, $executionLink, "class='form-control picker executionLink'");?>
      - - -
      -

      my->alert;?>

      -
      - -
      -
      -
      - diff --git a/module/my/view/profile.html.php b/module/my/view/profile.html.php deleted file mode 100644 index c823517eb4..0000000000 --- a/module/my/view/profile.html.php +++ /dev/null @@ -1,132 +0,0 @@ - - * @package my - * @version $Id: profile.html.php 4694 2013-05-02 01:40:54Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - -app->user->avatar);?> -app->user->id);?> -user->roleList, $user->role, '')):?> - - -
      -
      -
      -
      - -
      id='avatarForm' enctype='multipart/form-data'> - - ', '', "class='btn-avatar' id='avatarUploadBtn' data-toggle='tooltip' data-container='body' data-placement='bottom' title='{$lang->my->uploadAvatar}'");?> -
      -
      -
      realname;?>
      -
      user->roleList, $user->role, '');?>
      -
      -
      - - - - - - - - - - - - - - - - - - - - - - - - - -
      user->realname;?>realname;?>user->gender;?>user->genderList, $user->gender);?>
      user->account;?>account;?>user->email;?>email);?>
      user->dept;?> - $dept) - { - if($dept->name) echo $dept->name; - if(isset($deptPath[$key + 1])) echo $lang->arrow; - } - } - ?> - user->role;?>user->roleList, $user->role, '');?>
      user->abbr->join;?>join);?>user->priv;?>name . ' ';?>
      - - - - - - - - - - - - - - - - - - - -
      user->mobile;?>mobile;?>user->weixin;?>weixin;?>
      user->phone;?>phone;?>user->qq;?>qq;?>
      user->zipcode;?>zipcode;?>user->abbr->address;?>address;?>
      - - - - - - - - - - - - - - - - - - - - - - - - - -
      user->commiter;?>commiter;?>user->skype;?>skype) echo html::a("callto://$user->skype", $user->skype);?>
      user->visits;?>visits;?>user->whatsapp;?>whatsapp;?>
      user->last;?>last;?>user->slack;?>slack;?>
      user->ip;?>ip;?>user->dingding;?>dingding;?>
      -
      -
      -
      - -
      - changePassword, '', "title={$lang->changePassword} class='btn'");?> - user->editProfile, '', "title={$lang->user->editProfile} class='btn'");?> - my->uploadAvatar, '', "class='btn'");?> -
      - -
      -
      - diff --git a/module/my/view/project.html.php b/module/my/view/project.html.php deleted file mode 100644 index 963fddf248..0000000000 --- a/module/my/view/project.html.php +++ /dev/null @@ -1,127 +0,0 @@ - - * @package my - * @version $Id - * @link https://www.zentao.net - */ -?> - - -
      - -
      -

      - project->empty;?> -

      -
      - -
      - - - - - - - - - - - - - - - - - - - - status == 'wait') $waitCount ++;?> - status == 'doing') $doingCount ++;?> - status == 'suspended') $suspendedCount ++;?> - status == 'closed') $closedCount ++;?> - - - - - - - - app->getClientLang(), array('zh-cn','zh-tw')) ? round((float)$project->budget / 10000, 2) . $this->lang->project->tenThousand : round((float)$project->budget, 2);?> - - - - - - - -
      idAB);?>project->name);?>project->PM);?>project->status);?>project->budget);?>project->begin);?>project->end);?>actions;?>
      id);?> - model == 'scrum' ? 'sprint' : $project->model; - if(isset($project->delay)) $suffix = "{$lang->project->statusList['delay']}"; - if(!empty($suffix)) echo '
      '; - echo html::a($this->createLink('project', 'index', "projectID=$project->id"), " " . $project->name, '', "data-app='project' title='{$project->name}'"); - if(!empty($suffix)) echo $suffix; - ?> -
      - PM)):?> - PM);?> - $usersAvatar[$project->PM], 'account' => $project->PM, 'name' => $userName), "avatar-circle avatar-{$project->PM}"); ?> - PM]) ? $PMList[$project->PM]->id : '';?> - createLink('user', 'profile', "userID=$userID", '', true), $userName, '', "title='{$userName}' data-toggle='modal' data-type='iframe' data-width='600'");?> - - project->statusList, $project->status, '');?>budget != 0 ? zget($lang->project->currencySymbol, $project->budgetUnit) . ' ' . $projectBudget : $lang->project->future;?>begin;?>end == LONG_TIME ? $this->lang->project->longTime : $project->end;?> - status == 'wait' || $project->status == 'suspended') common::printIcon('project', 'start', "projectID=$project->id", $project, 'list', 'play', '', 'iframe', true);?> - status == 'doing') common::printIcon('project', 'close', "projectID=$project->id", $project, 'list', 'off', '', 'iframe', true);?> - status == 'closed') common::printIcon('project', 'activate', "projectID=$project->id", $project, 'list', 'magic', '', 'iframe', true);?> - status != 'doing') || (common::hasPriv('project','activate') && $project->status != 'closed')):?> -
      - - -
      - - id", $project, 'list', 'edit', '', '', false, "data-group='project'", '', $project->id);?> - id", $project, 'list', 'group', '', '', false, "data-group='project'", '', $project->id);?> - id", $project, 'list', 'lock', '', '', false, "data-group='project'", '', $project->id);?> - -
      - - -
      - -
      - -
      - -
      - diff --git a/module/my/view/requirement.html.php b/module/my/view/requirement.html.php deleted file mode 100644 index 230d0048e4..0000000000 --- a/module/my/view/requirement.html.php +++ /dev/null @@ -1,296 +0,0 @@ - - * @package my - * @version $Id - * @link https://www.zentao.net - */ -?> - - - -recTotal);?> -rawMethod);?> - -
      -
      rawMethod == 'contribute' ? 'contributeRequirement' : 'workRequirement');?>>
      - -
      -

      my->noData, $lang->URCommon);?>

      -
      - -
      - - - URCommon . ' ' . $lang->my->name : $lang->URCommon . $lang->my->name; - ?> - - - - - - - - - - - - - - - - createLink('story', 'view', "id=$story->id&version=0¶m=0&storyType=requirement"); - $canBeChanged = common::canBeChanged('story', $story); - $spanClass = $canBatchAction ? 'c-span' : ''; - ?> - - - - - - - - - - - - children)):?> - - children as $key => $child):?> - createLink('story', 'view', "id=$child->id");?> - - children)) ? ' table-child-bottom' : '';?> - - - - - - - - - - - - - - - - -
      - -
      - -
      - - idAB);?> -
      pri;?>>priAB);?> statusAB);?> story->product);?> story->openedByAB);?> story->estimateAB);?> story->stageAB);?> actions;?>
      - -
      - /> - -
      - - id);?> -
      - title, null, "style='color: $story->color' data-group='product' title='$story->title'") : "$story->title";?> - children)) echo '';?> - pri;?>' title='story->priList, $story->pri, $story->pri);?>'>story->priList, $story->pri, $story->pri);?>processStatus('story', $story);?>productTitle;?>openedBy);?>estimate . $config->hourUnit;?>story->stageList, $story->stage);?> - id}"; - echo common::buildIconButton('story', 'change', "$vars&from=&storyType=requirement", $story, 'list', 'alter', '', 'iframe', true); - - if(strpos('draft,changing', $story->status) !== false) - { - echo common::buildIconButton('story', 'submitReview', "$vars&storyType=requirement", $story, 'list', 'confirm', '', 'iframe', true); - } - else - { - echo common::buildIconButton('story', 'review', "$vars&from=product&storyType=requirement", $story, 'list', 'search', '', 'iframe', true); - } - - $title = $story->status == 'changing' ? $this->lang->story->recallChange : $this->lang->story->recall; - echo common::buildIconButton('story', 'recall', "$vars&from=list&confirm=no&storyType=requirement", $story, 'list', 'undo', 'hiddenwin', '', '', '', $title); - echo common::buildIconButton('story', 'edit', "$vars&from=default&storyType=requirement", $story, 'list', '', '', 'iframe', true, "data-width='95%'"); - - $storyType = 'storyType=requirement'; - $canChange = common::hasPriv('story', 'change', '', $storyType); - $canSubmitReview = (strpos('draft,changing', $story->status) !== false and common::hasPriv('story', 'submitReview', '', $storyType)); - $canReview = (strpos('draft,changing', $story->status) === false and common::hasPriv('story', 'review', '', $storyType)); - $canRecall = common::hasPriv('story', 'recall', '', $storyType); - $canEdit = common::hasPriv('story', 'edit', '', $storyType); - $canClose = common::hasPriv('story', 'close', '', $storyType); - if(($canChange or $canSubmitReview or $canReview or $canRecall or $canEdit) and $canClose) - { - echo "
      "; - } - - echo common::buildIconButton('story', 'close', "$vars&from=&storyType=requirement", $story, 'list', '', '', 'iframe', true); - } - ?> -
      - - id);?> - - lang->story->children .'">SR ' . (common::hasPriv('story', 'view') ? html::a($storyLink, $child->title, null, "style='color: $child->color' data-group='product' title='$child->title'") : $child->title);?> - pri;?>' title='story->priList, $child->pri, $child->pri);?>'>story->priList, $child->pri, $child->pri);?>URChanged ? "{$this->lang->story->URChanged}" : "" . $this->processStatus('story', $child) . ''?>productTitle;?>openedBy);?>estimate . $config->hourUnit;?>story->stageList, $child->stage);?> - id}"; - if($child->URChanged) - { - common::printIcon('story', 'processStoryChange', $vars, $child, 'list', 'ok'); - } - else - { - common::printIcon('story', 'change', "$vars&from=&storyType=story", $child, 'list', 'alter', '', 'iframe', true); - - if(strpos('draft,changing', $child->status) !== false) - { - common::printIcon('story', 'submitReview', "$vars&storyType=story", $child, 'list', 'confirm', '', 'iframe', true); - } - else - { - common::printIcon('story', 'review', "$vars&from=product&storyType=story", $child, 'list', 'search', '', 'iframe', true); - } - - $title = $child->status == 'changing' ? $this->lang->story->recallChange : $this->lang->story->recall; - common::printIcon('story', 'recall', "$vars&from=list&confirm=no&storyType=story", $child, 'list', 'undo', 'hiddenwin', '', '', '', $title); - common::printIcon('story', 'edit', "$vars&from=default&storyType=story", $child, 'list'); - $storyType = 'storyType=story'; - $canChange = common::hasPriv('story', 'change', '', $storyType); - $canSubmitReview = (strpos('draft,changing', $child->status) !== false and common::hasPriv('story', 'submitReview', '', $storyType)); - $canReview = (strpos('draft,draft', $child->status) === false and common::hasPriv('story', 'review', '', $storyType)); - $canRecall = common::hasPriv('story', 'recall', '', $storyType); - $canEdit = common::hasPriv('story', 'edit', '', $storyType); - $canClose = common::hasPriv('story', 'close', '', $storyType); - if(($canChange or $canSubmitReview or $canReview or $canRecall or $canEdit) and $canClose) - { - echo "
      "; - } - common::printIcon('story', 'close', "$vars&from=&storyType=story", $child, 'list', '', '', 'iframe', true); - } - } - ?> -
      -
      - diff --git a/module/my/view/score.html.php b/module/my/view/score.html.php deleted file mode 100644 index beca4f76df..0000000000 --- a/module/my/view/score.html.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @package my - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -
      - - - - - - - - - - - - - - - - - - - - - - - - - -
      score->time; ?>score->module; ?>score->method; ?>score->before; ?>score->score; ?>score->after; ?>score->desc; ?>
      time; ?>score->modules[$score->module]; ?>score->methods[$score->module][$score->method]; ?>before; ?>score; ?>after; ?>desc;?>
      - - - -
      - diff --git a/module/my/view/story.html.php b/module/my/view/story.html.php deleted file mode 100644 index 1d44945025..0000000000 --- a/module/my/view/story.html.php +++ /dev/null @@ -1,303 +0,0 @@ - - * @package my - * @version $Id - * @link https://www.zentao.net - */ -?> - - -recTotal);?> -rawMethod);?> - -
      -
      rawMethod == 'contribute' ? 'contributeStory' : 'workStory');?>>
      - -
      -

      my->noData, $lang->SRCommon);?>

      -
      - -
      - - - SRCommon . ' ' . $lang->my->name : $lang->SRCommon . $lang->my->name; - ?> - - - - - - - - - - - - - - - - - createLink('story', 'view', "id=$story->id", '', $story->shadow ? true : false); - $canBeChanged = common::canBeChanged('story', $story); - ?> - - - - - - - - - - - - - children)):?> - - children as $key => $child):?> - createLink('story', 'view', "id=$child->id");?> - - children)) ? ' table-child-bottom' : '';?> - - - - - - - - - - - - - - - - - -
      - -
      - -
      - - idAB);?> -
      my->pri;?>>priAB);?> statusAB);?> story->product);?> story->plan);?> story->openedByAB);?> story->estimateAB);?> story->stageAB);?>actions;?>
      - -
      - /> - -
      - - id);?> -
      - shadow ? "class='iframe'" : '';?> - title, null, "style='color: $story->color' data-group='product' $class") : $story->title;?> - children)) echo '';;?> - pri;?>' title='story->priList, $story->pri, $story->pri);?>'>story->priList, $story->pri, $story->pri);?>processStatus('story', $story);?>productTitle;?>planTitle;?>openedBy);?>estimate . $config->hourUnit;?>story->stageList, $story->stage);?> - id}"; - echo common::buildIconButton('story', 'change', $vars, $story, 'list', 'alter', '', 'iframe', true); - - if(strpos('draft,changing', $story->status) !== false) - { - echo common::buildIconButton('story', 'submitReview', $vars, $story, 'list', 'confirm', 'confirm', 'iframe', true); - } - else - { - echo common::buildIconButton('story', 'review', $vars, $story, 'list', 'search', '', 'iframe', true); - } - - $title = $story->status == 'changing' ? $this->lang->story->recallChange : $this->lang->story->recall; - echo common::buildIconButton('story', 'recall', $vars, $story, 'list', 'undo', 'hiddenwin', '', '', '', $title); - echo common::buildIconButton('story', 'edit', $vars, $story, 'list', '', '', 'iframe', true, "data-width='95%'"); - - $canSubmitReview = (strpos('draft,changing', $story->status) !== false and common::hasPriv('story', 'submitReview')); - $canReview = (strpos('draft,changing', $story->status) === false and common::hasPriv('story', 'review')); - - if(($canChange or $canSubmitReview or $canReview or $canRecall or $canEdit) and ($canCreateCase or $canClose)) - { - echo "
      "; - } - - echo common::buildIconButton('testcase', 'create', "productID=$story->product&branch=$story->branch&module=0&from=¶m=0&$vars", $story, 'list', 'sitemap', '', 'iframe', true, "data-width='95%'"); - - if($canCreateCase and $canClose) echo "
      "; - - echo common::buildIconButton('story', 'close', $vars, $story, 'list', '', '', 'iframe', true); - } - ?> -
      - -
      - - -
      - - id);?> -
      - lang->story->children .'">' . $this->lang->story->childrenAB . ' ' . html::a($storyLink, $child->title, null, "style='color: $child->color' data-group='product' title='$child->title'");?> - pri;?>' title='story->priList, $child->pri, $child->pri);?>'>story->priList, $child->pri, $child->pri);?>processStatus('story', $child);?>productTitle;?>planTitle;?>openedBy);?>estimate . $config->hourUnit;?>story->stageList, $child->stage);?> - id}"; - common::printIcon('story', 'change', $vars, $child, 'list', 'alter', '', 'iframe', true); - - if(strpos('draft,changing', $child->status) !== false) - { - common::printIcon('story', 'submitReview', $vars, $child, 'list', 'confirm', '', 'iframe', true); - } - else - { - common::printIcon('story', 'review', $vars, $child, 'list', 'search', '', 'iframe', true); - } - - $title = $child->status == 'changing' ? $this->lang->story->recallChange : $this->lang->story->recall; - common::printIcon('story', 'recall', $vars, $child, 'list', 'undo', 'hiddenwin', '', '', '', $title); - common::printIcon('story', 'edit', $vars, $child, 'list', '', '', 'iframe', true, "data-width='95%'"); - - $canSubmitReview = (strpos('draft,changing', $child->status) !== false and common::hasPriv('story', 'submitReview')); - $canReview = (strpos('draft,changing', $child->status) === false and common::hasPriv('story', 'review')); - - if(($canChange or $canSubmitReview or $canReview or $canRecall or $canEdit) and ($canCreateCase or $canClose)) - { - echo "
      "; - } - - common::printIcon('testcase', 'create', "productID=$child->product&branch=$child->branch&module=0&from=¶m=0&$vars", $child, 'list', 'sitemap', '', 'iframe', true, "data-width='95%'"); - - if($canCreateCase and $canClose) echo "
      "; - - common::printIcon('story', 'close', $vars, $child, 'list', '', '', 'iframe', true); - } - ?> -
      -
      - diff --git a/module/my/view/task.html.php b/module/my/view/task.html.php deleted file mode 100644 index 8788d3f362..0000000000 --- a/module/my/view/task.html.php +++ /dev/null @@ -1,351 +0,0 @@ - - * @package dashboard - * @version $Id: task.html.php 5101 2013-07-12 00:44:27Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -recTotal);?> -rawMethod);?> -app->loadLang('task');?> - -
      - rawMethod == 'work' ? 'workTask' : 'contributeTask';?> -
      >
      - -
      -

      task->noTask;?>

      -
      - -
      - -
      - - - session->myTaskType : $type;?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - children)):?> - - children as $key => $child):?> - - children)) ? ' table-child-bottom' : '';?> - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      - -
      - -
      - - idAB);?> -
      task->name);?>task->pri;?>>priAB);?>statusAB);?>my->projects);?>task->execution);?>task->assignedTo);?>task->deadlineAB);?>task->estimateAB);?>task->consumedAB);?>task->leftAB);?>task->openedByAB);?>task->finishedByAB);?>actions;?>
      - -
      - /> - -
      - - id);?> -
      ' title='name?>'> - team)) echo '' . $this->lang->task->multipleAB . ' ';?> - executionMultiple) ? 'project' : 'execution'; - if($task->parent > 0) - { - echo '' . $this->lang->task->childrenAB . ' ' . html::a($this->createLink('task', 'view', "taskID=$task->id", '', '', $task->project), $task->parentName . ' / '. $task->name, '', "title='{$task->parentName} / {$task->name}' data-app='$tab'"); - } - else - { - $onlybody = $task->executionType == 'kanban' ? true : ''; - $class = $task->executionType == 'kanban' ? 'iframe' : ''; - echo html::a($this->createLink('task', 'view', "taskID=$task->id", '', $onlybody, $task->project), $task->name, null, "class='$class' data-width='80%' style='color: $task->color' data-app='$tab'"); - } - ?> - children)) echo '';?> - pri;?>' title='task->priList, $task->pri);?>'>task->priList, $task->pri);?> - storyStatus) and $task->storyStatus == 'active' and $task->latestStoryVersion > $task->storyVersion and !in_array($task->status, array('cancel', 'closed')));?> - {$this->lang->my->storyChanged}") : print(" " . $this->processStatus('task', $task) . "");?> - - projectName and $task->project) ? html::a($this->createLink('project', 'index', "projectID=$task->project"), $task->projectName) : '';?> - - executionMultiple) echo html::a($this->createLink('execution', 'task', "executionID=$task->execution"), $task->executionName, '');?> - task->printAssignedHtml($task, $users);?>deadline, 0, 4) > 0) echo '' . substr($task->deadline, 5, 6) . '';?>estimate, 1) . $lang->execution->workHourUnit;?>consumed, 1) . $lang->execution->workHourUnit;?>left, 1) . $lang->execution->workHourUnit;?>openedBy);?>finishedBy);?> - needConfirm) - { - $this->lang->task->confirmStoryChange = $this->lang->confirm; - common::printIcon('task', 'confirmStoryChange', "taskid=$task->id", '', 'list', '', 'hiddenwin', '', '', '', '', $task->project); - } - else - { - $attr = isset($kanbanList[$task->execution]) ? "disabled" : ''; - $canStart = ($task->status != 'pause' and common::hasPriv('task', 'start')); - $canRestart = ($task->status == 'pause' and common::hasPriv('task', 'restart')); - if($task->status != 'pause') common::printIcon('task', 'start', "taskID=$task->id", $task, 'list', '', '', 'iframe', true); - if($task->status == 'pause') common::printIcon('task', 'restart', "taskID=$task->id", $task, 'list', '', '', 'iframe', true); - common::printIcon('task', 'finish', "taskID=$task->id", $task, 'list', '', '', 'iframe', true); - common::printIcon('task', 'close', "taskID=$task->id", $task, 'list', '', '', 'iframe', true); - - if(($canStart or $canRestart or $canFinish or $canClose) and ($canRecordEstimate or $canEdit or $canBatchCreate)) - { - echo "
      "; - } - - common::printIcon('task', 'recordWorkhour', "taskID=$task->id", $task, 'list', 'time', '', 'iframe', true); - common::printIcon('task', 'edit', "taskID=$task->id", $task, 'list', '', '', 'iframe', true, "data-width='95%'"); - common::printIcon('task', 'batchCreate', "executionID=$task->execution&storyID=$task->story&moduleID=$task->module&taskID=$task->id&ifame=true", $task, 'list', 'split', '', 'iframe', true, "data-width='95%' $attr", $this->lang->task->children); - } - } - ?> -
      - -
      - /> - -
      - - id);?> -
      - executionMultiple) ? 'project' : 'execution';?> - parent > 0) echo '' . $this->lang->task->childrenAB . ' ';?> - createLink('task', 'view', "taskID=$child->id", '', '', $child->project), $child->name, null, "style='color: $child->color' data-app='$tab'");?> - pri;?>' title='task->priList, $child->pri);?>'>task->priList, $child->pri);?> - storyStatus) and $child->storyStatus == 'active' and $child->latestStoryVersion > $child->storyVersion and !in_array($child->status, array('cancel', 'closed')));?> - {$this->lang->my->storyChanged}") : print(" " . $this->processStatus('task', $child) . "");?> - - projectName and $task->project) ? html::a($this->createLink('project', 'view', "projectID=$task->project"), $task->projectName) : '';?> - - executionMultiple) echo html::a($this->createLink('execution', 'task', "executionID=$child->project"), $child->executionName, '');?> - task->printAssignedHtml($child, $users);?>deadline, 0, 4) > 0) echo '' . substr($child->deadline, 5, 6) . '';?>estimate, 1) . ' ' . $lang->execution->workHourUnit;?>consumed, 1) . ' ' . $lang->execution->workHourUnit;?>left, 1) . ' ' . $lang->execution->workHourUnit;?>openedBy);?>finishedBy);?> - needConfirm) - { - $this->lang->task->confirmStoryChange = $this->lang->confirm; - common::printIcon('task', 'confirmStoryChange', "taskid=$child->id", '', 'list', '', 'hiddenwin'); - } - else - { - $canStart = ($child->status != 'pause' and common::hasPriv('task', 'start')); - $canRestart = ($child->status == 'pause' and common::hasPriv('task', 'restart')); - if($child->status != 'pause') common::printIcon('task', 'start', "taskID=$child->id", $child, 'list', '', '', 'iframe', true); - if($child->status == 'pause') common::printIcon('task', 'restart', "taskID=$child->id", $child, 'list', '', '', 'iframe', true); - common::printIcon('task', 'finish', "taskID=$child->id", $child, 'list', '', '', 'iframe', true); - common::printIcon('task', 'close', "taskID=$child->id", $child, 'list', '', '', 'iframe', true); - - if(($canStart or $canRestart or $canFinish or $canClose) and ($canRecordEstimate or $canEdit or $canBatchCreate)) - { - echo "
      "; - } - - common::printIcon('task', 'recordWorkhour', "taskID=$child->id", $child, 'list', 'time', '', 'iframe', true); - common::printIcon('task', 'edit', "taskID=$child->id", $child, 'list', '', '', 'iframe', true, "data-width='95%'"); - common::printIcon('task', 'batchCreate', "executionID=$child->execution&storyID=$child->story&moduleID=$child->module&taskID=$child->id&iframe=true", $child, 'list', 'split', '', 'iframe', true, '', $this->lang->task->children); - } - } - ?> -
      -
      - -
      - -
      - - - diff --git a/module/my/view/team.html.php b/module/my/view/team.html.php deleted file mode 100644 index bc8e8fb48e..0000000000 --- a/module/my/view/team.html.php +++ /dev/null @@ -1,66 +0,0 @@ - - * @package product - * @version $Id: browse.html.php 5096 2013-07-11 07:02:43Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -
      -
      -
      -
      - - - - recTotal}&recPerPage={$pager->recPerPage}";?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      idAB);?>user->realname);?>user->account);?>user->role);?>user->gender);?>user->phone);?>config->isINT) ? common::printOrderLink('skype', $orderBy, $vars, $lang->user->skype) : common::printOrderLink('qq', $orderBy, $vars, $lang->user->qq);?>user->last);?>user->visits);?>
      id);?>id&from=my", $user->realname, '', "title='$user->realname' data-group='my'")) echo $user->realname;?>account;?>'>user->roleList, $user->role, '');?>email);?>user->genderList, $user->gender, $user->gender);?>phone;?>config->isINT) ? $user->skype : ($user->qq ? html::a("tencent://message/?uin=$user->qq#open=my", $user->qq) : '');?>last) echo date('Y-m-d', $user->last);?>visits;?>
      - - - -
      -
      -
      - diff --git a/module/my/view/testcase.html.php b/module/my/view/testcase.html.php deleted file mode 100644 index 5e78af2fae..0000000000 --- a/module/my/view/testcase.html.php +++ /dev/null @@ -1,151 +0,0 @@ - - * @package dashboard - * @version $Id: test.html.php 1191 2010-11-13 07:30:35Z jajacn@126.com $ - * @link https://www.zentao.net - */ -?> - - -recTotal);?> -rawMethod);?> -testcase->confirmDelete)?> - -
      -
      rawMethod == 'contribute' ? 'contributeTestcase' : 'workTestcase');?>>
      - -
      -

      testcase->noCase;?>

      -
      - -
      - - app->loadLang('testtask'); - $canBatchEdit = (common::hasPriv('testcase', 'batchEdit') and $type == 'assigntome'); - ?> - - - - - - - - - - - - - - - - - - - - case : $case->id; - $runID = $type == 'assigntome' ? $case->run : 0; - $canBeChanged = common::canBeChanged('testcase', $case); - ?> - - - version";?> - task";?> - - - - - - - - - - - - - - - -
      - -
      - -
      - - idAB);?> -
      testcase->title);?> priAB);?> testtask->common);?> typeAB);?> statusAB;?> testcase->openedByAB);?> testtask->lastRunAccount);?>testtask->lastRunTime);?> testtask->lastRunResult);?> actions;?>
      - -
      - /> - -
      - - id); ?> -
      createLink('testcase', 'view', $params), $case->title, null, "style='color: $case->color' title='{$case->title}'");?>pri?>' title='testcase->priList, $case->pri, $case->pri);?>'>testcase->priList, $case->pri, $case->pri)?>taskName;?>testcase->typeList, $case->type);?> - needconfirm) - { - print("{$this->lang->story->changed}"); - } - elseif(isset($case->fromCaseVersion) and $case->fromCaseVersion > $case->version and !$case->needconfirm) - { - print("{$this->lang->testcase->changed}"); - } - else - { - print("" . $this->processStatus('testcase', $case) . ""); - } - ?> - openedBy);?>lastRunner);?>lastRunDate) ? '' : substr($case->lastRunDate, 5, 11);?>lastRunResult ? $lang->testcase->resultList[$case->lastRunResult] : $lang->testcase->unexecuted;?> - lastRunResult) and $case->lastRunResult != 'fail') ? 'disabled' : ''; - common::printIcon('testcase', 'createBug', "product=$case->product&branch=$case->branch&extra=caseID=$caseID,version=$case->version,runID=$runID", $case, 'list', 'bug', '', "iframe $disabled", 'true', "data-app='qa' data-toggle=''"); - common::printIcon('testcase', 'create', "productID=$case->product&branch=$case->branch&moduleID=$case->module&from={$app->rawMethod}¶m=$caseID", $case, 'list', 'copy', '', 'iframe', true, "data-width='95%'"); - $disabled = $case->status == 'wait' ? 'disabled' : ''; - common::printIcon('testtask', 'runCase', "runID=$runID&caseID=$caseID&version=$case->version", '', 'list', 'play', '', "iframe $disabled", true, "data-width='95%'", '', $case->project); - common::printIcon('testtask', 'results', "runID=$runID&caseID=$caseID", '', 'list', 'list-alt', '', 'iframe', true, "data-width='95%'", '', $case->project); - common::printIcon('testcase', 'edit', "caseID=$caseID", $case, 'list', 'edit', '', 'iframe', true, "data-width='95%'", '', $case->project); - } - ?> -
      - -
      - -
      - - diff --git a/module/my/view/testtask.html.php b/module/my/view/testtask.html.php deleted file mode 100644 index 8d886a59ae..0000000000 --- a/module/my/view/testtask.html.php +++ /dev/null @@ -1,98 +0,0 @@ - - * @package dashboard - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -recTotal);?> -rawMethod);?> -testtask->confirmDelete)?> - -
      - -
      -

      testtask->noTesttask;?>

      -
      - - - - - - - - - - - - - - - - - - - status == 'wait') $waitCount ++;?> - status == 'doing') $testingCount ++;?> - status == 'blocked') $blockedCount ++;?> - - - - - executionName; - if(empty($task->executionMultiple)) $executionName = $task->projectName . "({$this->lang->project->disableExecution})"; - ?> - - - - - - - - -
      idAB);?> testtask->name);?> testtask->build);?>testtask->execution);?> statusAB);?> testtask->begin);?> testtask->end);?>actions;?>
      id);?>createLink('testtask', 'view', "taskID=$task->id"), $task->name);?>trunk : $task->buildName;?>'>build == 'trunk' ? print($lang->trunk) : print(html::a($this->createLink('build', 'view', "buildID=$task->build"), $task->buildName));?>'>processStatus('testtask', $task);?>begin?>end?> - id", $task, 'list', 'sitemap', '', '', '', "data-app='qa'"); - common::printIcon('testtask', 'view', "taskID=$task->id", '', 'list', 'list-alt', '', 'iframe', true, "data-width='90%'"); - common::printIcon('testtask', 'linkCase', "taskID=$task->id", $task, 'list', 'link', '', '', false, "data-app='qa'"); - common::printIcon('testreport', 'browse', "objectID=$task->product&objectType=product&extra=$task->id", $task, 'list', 'summary', '', '', false, "data-app='qa'"); - common::printIcon('testtask', 'edit', "taskID=$task->id", $task, 'list', '', '', 'iframe', true, "data-width='90%'"); - if(common::hasPriv('testtask', 'delete', $task)) - { - $deleteURL = $this->createLink('testtask', 'delete', "taskID=$task->id&confirm=yes"); - echo html::a("javascript:ajaxDelete(\"$deleteURL\", \"taskList\", confirmDelete)", '', '', "title='{$lang->testtask->delete}' class='btn'"); - } - ?> -
      - - -
      - diff --git a/module/my/view/todo.html.php b/module/my/view/todo.html.php deleted file mode 100644 index b8bc75538a..0000000000 --- a/module/my/view/todo.html.php +++ /dev/null @@ -1,210 +0,0 @@ - - * @package dashboard - * @version $Id: todo.html.php 4735 2013-05-03 08:30:02Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -todo->confirmDelete)?> - - -
      - -
      -

      - my->noTodo;?> - - createLink('todo', 'create'), " " . $lang->todo->create, '', "class='btn btn-info' data-app='my'");?> - -

      -
      - -
      - - - id}&status=$status&orderBy=%s&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID"; ?> - - - - - app->clientLang == 'en' ? "style='width:80px'" : '';?> - - - - - - - - - - - - - - - - - status == 'wait') $waitCount ++;?> - status == 'doing') $doingCount ++;?> - - - - - - - - - - - - - - - - - - -
      - -
      - -
      - - idAB);?> -
      todo->name);?> title=todo->pri;?>> priAB);?>todo->date);?> todo->status);?>todo->type);?> todo->assignedTo);?> todo->assignedBy);?> todo->beginAB);?> todo->endAB);?>actions;?>
      - -
      - - -
      - - id?> -
      createLink('todo', 'view', "id=$todo->id&from=my", '', true), $todo->name, '', "data-toggle='modal' data-width='80%' data-type='iframe' data-title='" . $lang->todo->view . "' data-icon='check'");?>pri;?>' title='todo->priList, $todo->pri, $todo->pri);?>'>todo->priList, $todo->pri)?>date == '2030-01-01' ? $lang->todo->future : $todo->date;?>todo->statusList[$todo->status];?>todo->typeList, $todo->type, '');?>assignedTo);?>assignedBy);?>begin;?>end;?> - id", $todo, 'list', 'play', 'hiddenwin'); - if($todo->status == 'done' or $todo->status == 'closed') - { - common::printIcon('todo', 'activate', "id=$todo->id", $todo, 'list', 'magic', 'hiddenwin'); - if($todo->status == 'done') - { - common::printIcon('todo', 'close', "id=$todo->id", $todo, 'list', 'off', 'hiddenwin'); - } - else - { - echo html::a('javascript:;', "", '', "class='btn disabled'"); - } - } - else - { - common::printIcon('todo', 'assignTo', "todoID=$todo->id", $todo, 'list', 'hand-right', '', "iframe", false, "data-width='600'"); - common::printIcon('todo', 'finish', "id=$todo->id", $todo, 'list', 'checked', 'hiddenwin'); - } - common::printIcon('todo', 'edit', "id=$todo->id", '', 'list', 'edit', '', 'iframe', true); - - if(common::hasPriv('todo', 'delete')) - { - $deleteURL = $this->createLink('todo', 'delete', "todoID=$todo->id&confirm=yes"); - echo html::a("javascript:ajaxDelete(\"$deleteURL\", \"todoList\", confirmDelete)", '', '', "class='btn' title='{$lang->todo->delete}'"); - } - ?> -
      - -
      - -
      - -todo->summary, count($todos), $waitCount, $doingCount));?> -todo->checkedSummary);?> - diff --git a/module/personnel/view/accessible.html.php b/module/personnel/view/accessible.html.php deleted file mode 100644 index 76eef7a8bf..0000000000 --- a/module/personnel/view/accessible.html.php +++ /dev/null @@ -1,66 +0,0 @@ - - * @package ZenTaoPMS - * @version $Id - */ -?> - - -
      - -
      -
      -
      - - - - - - - - - - - - - - - - - - - - - - - -
      idAB;?>personnel->realName;?>personnel->department;?>personnel->job;?>personnel->userName;?>personnel->genders;?>
      id;?>realname;?>dept);?>user->roleList, $personnel->role, '');?>account;?>user->genderList, $personnel->gender, '');?>
      - -
      -
      -
      - diff --git a/module/personnel/view/addwhitelist.html.php b/module/personnel/view/addwhitelist.html.php deleted file mode 100644 index 67d1416db3..0000000000 --- a/module/personnel/view/addwhitelist.html.php +++ /dev/null @@ -1,113 +0,0 @@ - - * @package personnel - * @version $Id - * @link https://www.zentao.net - */ -?> - - - -projectCommon);?> - -
      -
      - - - - - - - - - - - - - - - - account] = $user->realname; - ?> - - - $realname):?> - - - - - - - - - - - - - - - - - - - - - -
      team->account;?> actions;?>
      - - - - - -
      - - - - -
      - - -
      - - session->whitelistList;?> - - goback, '', "class='btn btn-back btn-wide' $dataGroup");?> -
      -
      -
      -
      - - - - - - -
      - - - - - - diff --git a/module/personnel/view/invest.html.php b/module/personnel/view/invest.html.php deleted file mode 100644 index 3bf8bf5d5e..0000000000 --- a/module/personnel/view/invest.html.php +++ /dev/null @@ -1,103 +0,0 @@ - - * @package ZenTaoPMS - * @version $Id - */ -?> - - -
      - -
      -
      - - - - - - - - - - - - config->edition == 'max' or $this->config->edition == 'ipd'): ?> - - - - - - - - - - - - - - config->URAndSR):?> - - - - config->edition == 'max' or $this->config->edition == 'ipd'): ?> - - - - - - - - - - - $personnelList):?> - - - - - - - - - - - - - - - config->URAndSR):?> - - - - config->edition == 'max' or $this->config->edition == 'ipd'): ?> - - - - - - - - - - - -
      personnel->role;?> personnel->name;?>personnel->projects;?>personnel->executions;?>personnel->workingHours;?>personnel->task;?>personnel->bug;?>URAndSR ? "colspan='2'" : "rowspan='2'";?> class="c-story">personnel->createStories;?>personnel->issue;?>personnel->risk;?>
      personnel->invest;?>personnel->left;?>personnel->created;?>personnel->finished;?>personnel->wait;?>personnel->created;?>personnel->resolved;?>personnel->wait;?>personnel->UR;?>personnel->SR;?>personnel->created;?>personnel->resolved;?>personnel->wait;?>personnel->created;?>personnel->resolved;?>personnel->wait;?>
      ' style="overflow: hidden; white-space:nowrap; text-overflow: ellipsis;">'>
      -
      -
      - -
      -

      - noData;?> -

      -
      - -
      - diff --git a/module/personnel/view/whitelist.html.php b/module/personnel/view/whitelist.html.php deleted file mode 100644 index 4babf9e452..0000000000 --- a/module/personnel/view/whitelist.html.php +++ /dev/null @@ -1,80 +0,0 @@ - - * @package personnel - * @version $Id - * @link https://www.zentao.net - */ -?> - - -
      -
      - -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      - idAB;?> - user->realname;?>user->dept;?>user->role;?>user->phone;?>user->qq;?>user->weixin;?>actions;?>
      - id);?> - realname;?>dept);?>user->roleList, $user->role);?>phone;?>qq;?>weixin;?>email;?> - app->tab == 'program') $module = 'program'; - if(common::hasPriv($module, 'unbindWhitelist')) echo html::a($this->createLink($module, 'unbindWhitelist', "id=$user->id&confirm=no"), '', 'hiddenwin', "title='{$lang->personnel->delete}' class='btn' $tab"); - ?> -
      - - - -
      - -
      noData;?>
      - -
      -
      - diff --git a/module/pivot/view/bugassign.html.php b/module/pivot/view/bugassign.html.php deleted file mode 100644 index 715c1462ff..0000000000 --- a/module/pivot/view/bugassign.html.php +++ /dev/null @@ -1,56 +0,0 @@ -config->edition != 'open'):?> - - - - -
      -
      -

      error->noData;?>

      -
      -
      - -
      -
      -
      -
      - -
      -
      - - - - - - - - - - - $assign):?> - - - - - $count):?> - ';?> - - - - - - '; $id ++;?> - - - - -
      pivot->user;?>pivot->product;?>pivot->bugTotal;?>pivot->total;?>
      - createLink('product', 'view', "product={$count['productID']}") : $this->createLink('project', 'view', "projectID={$count['projectID']}");?> - - - -
      -
      -
      -
      - - diff --git a/module/pivot/view/bugcreate.html.php b/module/pivot/view/bugcreate.html.php deleted file mode 100644 index 1c97908732..0000000000 --- a/module/pivot/view/bugcreate.html.php +++ /dev/null @@ -1,79 +0,0 @@ - -
      -
      -
      -
      - pivot->bugOpenedDate;?> -
      - pivot->to;?> -
      -
      -
      -
      -
      - pivot->product;?> - -
      -
      -
      -
      - execution->common;?> - -
      -
      -
      -
      - -
      -
      -

      error->noData;?>

      -
      -
      - -
      -
      -
      -
      - -
      -
      - - - - - - bug->resolutionList as $resolutionType => $resolution):?> - - - - - - - - - $bug):?> - - - - - bug->resolutionList as $resolutionType => $resolution):?> - - - - - - - - -
      bug->openedBy;?>bug->unResolved;?>pivot->validRate;?>pivot->total;?>
      -
      -
      -
      - - diff --git a/module/pivot/view/preview.html.php b/module/pivot/view/preview.html.php deleted file mode 100644 index 4fab319771..0000000000 --- a/module/pivot/view/preview.html.php +++ /dev/null @@ -1,65 +0,0 @@ -app->getModuleRoot() . 'common/view/header.html.php';?> - -config->edition != 'open'):?> - - - - - - -config->edition != 'open'):?> -app->getModuleExtPath('', 'pivot', 'view');?> - - - -
      - -
      - -
      -

      error->noData;?>

      -
      - - fetch($module, $method, $params);?> - -
      -
      -app->getModuleRoot() . 'common/view/footer.html.php';?> diff --git a/module/pivot/view/productsummary.html.php b/module/pivot/view/productsummary.html.php deleted file mode 100644 index 532d0a5a20..0000000000 --- a/module/pivot/view/productsummary.html.php +++ /dev/null @@ -1,113 +0,0 @@ - -
      -
      -
      -
      -
      -
      -
      -
      - /> - -
      -
      - /> - -
      -
      -
      -
      - -
      -
      -
      - -
      -
      -

      error->noData;?>

      -
      -
      - -
      -
      -
      - - - - - - - - - - - - - - - - - - - - - plans) ? count($product->plans) : 1;?> - - - plans)):?> - - plans as $plan):?> - - "?> - parent) and $plan->parent > 0 and isset($product->plans[$plan->parent])) ? ' child' : '';?> - - - - status['draft']) ? $plan->status['draft'] : 0; - $reviewingCount = isset($plan->status['reviewing']) ? $plan->status['reviewing'] : 0; - $activeCount = isset($plan->status['active']) ? $plan->status['active'] : 0; - $changedCount = isset($plan->status['changing']) ? $plan->status['changing'] : 0; - $closedCount = isset($plan->status['closed']) ? $plan->status['closed'] : 0; - ?> - - - - - - - "?> - - - - - - - - - - - - - - - - - - - -
      product->name;?>pivot->PO;?>productplan->common;?>productplan->begin;?>productplan->end;?>story->statusList['draft'];?>story->statusList['reviewing'];?>story->statusList['active'];?>story->statusList['changing'];?>story->statusList['closed'];?>pivot->total;?>
      " . html::a($this->createLink('product', 'view', "product=$product->id"), $product->name) . "

      ";?>
      " . zget($users, $product->PO) . '

      ';?>
      title;?>begin == '2030-01-01' ? $lang->productplan->future : $plan->begin;?>end == '2030-01-01' ? $lang->productplan->future : $plan->end;?>000000
      -
      -
      -
      - - diff --git a/module/pivot/view/projectdeviation.html.php b/module/pivot/view/projectdeviation.html.php deleted file mode 100644 index 24d990e088..0000000000 --- a/module/pivot/view/projectdeviation.html.php +++ /dev/null @@ -1,184 +0,0 @@ - - -
      -
      -
      -
      - pivot->execution . $lang->pivot->begin;?> -
      -
      -
      -
      -
      - pivot->execution . $lang->pivot->end;?> -
      -
      -
      -
      -
      - -
      -
      -

      error->noData;?>

      -
      -
      - - array(), 'data' => array());?> -
      -
      -
      -
      - - - -
      - -
      -
      - - - - - - - - - - - - - - $execution):?> - - - - - - - consumed - $execution->estimate, 2);?> - - - - - -
      pivot->id;?>pivot->project;?>pivot->execution;?>pivot->estimate;?>pivot->consumed;?>pivot->deviation;?>pivot->deviationRate;?>
      - name ? $execution->projectName : html::a($this->createLink('project', 'index', "projectID=$execution->projectID"), $execution->projectName);?> - - multiple):?> - name ? html::a($this->createLink('execution', 'view', "executionID=$id"), $execution->name) : '';?> - - null;?> - - estimate, 2);?>consumed, 2);?> - 0) - { - echo '↑' . $deviation; - } - else if($deviation < 0) - { - echo '↓' . abs($deviation); - } - else - { - echo '0'; - } - ?> - - estimate ? round($deviation / $execution->estimate * 100, 2) : 'n/a'; - if($num >= 50) - { - echo '' . $num . '%'; - } - elseif($num >= 30) - { - echo '' . $num . '%'; - } - elseif($num >= 10) - { - echo '' . $num . '%'; - } - elseif($num > 0) - { - echo '' . abs($num) . '%'; - } - elseif($num <= -20) - { - echo '' . abs($num) . '%'; - } - elseif($num < 0) - { - echo '' . abs($num) . '%'; - } - elseif($num == 'n/a') - { - echo '' . $num . ''; - } - else - { - echo '' . abs($num) . '%'; - } - - $chartData['labels'][] = $execution->name; - $chartData['data'][] = $deviation; - ?> -
      -
      -
      -
      - - -
      - 30) - { - $chartData['labels'] = array_slice($chartData['labels'], 0, 30); - $chartData['data'] = array_slice($chartData['data'], 0, 30); - } - ?> -
      -
      -
      pivot->deviationChart;?>
      -
      -
      - -
      -
      -
      - - - diff --git a/module/pivot/view/show.html.php b/module/pivot/view/show.html.php deleted file mode 100644 index d3998422ad..0000000000 --- a/module/pivot/view/show.html.php +++ /dev/null @@ -1,86 +0,0 @@ - - * @package pivot - * @version $Id$ - * @link https://www.zentao.net - */ -?> -id) ? $group->id : 0);?> -id) ? $pivot->id : 0);?> - -pivot->widthInput);?> -pivot->widthDate);?> -bi->pickerHeight);?> -lang->datepicker->dpText);?> -
      ";?> - - - - -
      - -
      -
      - pivot->noPivot;?> -
      -
      - -
      -
      - name;?> - desc)):?> - - -
      -
      -
      -
      -
      - filters)):?> -
      pivot->query, "", 'btn btn-primary btn-query');?>
      - -
      -
      - loadModel('chart')->parseSqlVars($pivot->sql, $pivot->filters);?> - pivot->buildPivotTable($data, $configs, json_decode(json_encode($pivot->fieldSettings), true), $sql);?> -
      -
      - -
      - - - - diff --git a/module/pivot/view/workload.html.php b/module/pivot/view/workload.html.php deleted file mode 100644 index 10e78f9e67..0000000000 --- a/module/pivot/view/workload.html.php +++ /dev/null @@ -1,120 +0,0 @@ - -execution->weekend);?> -
      -
      -
      -
      -
      - pivot->dept;?> - -
      -
      -
      -
      - pivot->beginAndEnd;?> -
      - pivot->to;?> -
      -
      -
      -
      -
      - pivot->diffDays;?> - -
      -
      -
      -
      -
      -
      - pivot->workday;?> - -
      -
      -
      - pivot->assign, $assign, "class='form-control' onchange='changeParams(this)'");?> -
      -
      - pivot->query, '', 'btn btn-primary btn-block');?> -
      -
      -
      -
      -
      -
      - -
      -
      -

      error->noData;?>

      -
      -
      - -
      -
      -
      -
      - -
      - -
      -
      - - - - - - - - - - - - - - - $load):?> - - - - $info) foreach($info['execution'] as $executionName => $executionInfo) $userCount ++;?> - - $info):?> - - $executionInfo) $projectCount ++ ;?> - $executionInfo):?> - ";?> - - - - - - - - - - - - - - - - ";?> - - - - - - - -
      pivot->user;?>pivot->project ;?> - pivot->execution;?>pivot->task;?>pivot->remain;?>pivot->taskTotal;?>pivot->manhourTotal;?>pivot->workloadAB;?>
      createLink('project', 'view', "projectID={$info['projectID']}"), $projectName);?>createLink('execution', 'view', "executionID={$executionInfo['executionID']}"), $executionName);?>null;?>
      -
      -
      -
      - - diff --git a/module/product/model.php b/module/product/model.php index 978dd1a7d1..711110283b 100755 --- a/module/product/model.php +++ b/module/product/model.php @@ -2036,7 +2036,6 @@ class productModel extends model if($module == 'product' && in_array($method, array('doc', 'view'))) return helper::createLink($module, $method, "productID=%s"); if($module == 'product' && in_array($method, array('create', 'showimport'))) return helper::createLink($module, 'browse', "productID=%s&type=$extra"); if($module == 'bug' && in_array($method, array('edit', 'view'))) return helper::createLink($module, 'browse', "productID=%s"); - if($module == 'testcase' && in_array($method, array('edit', 'view'))) return helper::createLink($module, 'browse', "productID=%s"); if($module == 'ticket' && in_array($method, array('browse', 'view', 'edit', 'createstory'))) return helper::createLink('ticket', 'browse', "browseType=byProduct&productID=%s"); if($module == 'testreport' && in_array($method, array('edit', 'browse'))) return helper::createLink($module, 'browse', "objectID=%s"); if($module == 'feedback' && $this->config->vision == 'lite') return helper::createLink('feedback', 'browse', "browseType=byProduct&productID=%s"); @@ -2067,7 +2066,8 @@ class productModel extends model } return helper::createLink($module, $method, "productID=%s&branch={$branchID}&groupBy=&projectID=$projectID") . "#app=project"; } - if($module == 'story' and $this->config->vision == 'or') return helper::createLink('story', 'create', "productID=%s&branch=0&moduleID=0&storyID=0&objectID=0&bugID=0&planID0&todoID=0&extra=&storyType=requirement"); + if($module == 'testcase' && !in_array($method, array('browse', 'browsescene', 'groupcase', 'zerocase', 'create'))) return helper::createLink($module, 'browse', "productID=%s"); + if($module == 'story' && $this->config->vision == 'or') return helper::createLink('story', 'create', "productID=%s&branch=0&moduleID=0&storyID=0&objectID=0&bugID=0&planID0&todoID=0&extra=&storyType=requirement"); return helper::createLink($module, $method, "productID=%s{$branchParam}{$extraParam}"); } diff --git a/module/product/test/tao/getprojectproductlist.php b/module/product/test/tao/getprojectproductlist.php old mode 100644 new mode 100755 index 8c59381fe6..47b8c98bd2 --- a/module/product/test/tao/getprojectproductlist.php +++ b/module/product/test/tao/getprojectproductlist.php @@ -8,14 +8,10 @@ timeout=0 cid=0 - 测试传入空的产品ID列表 @0 -- 测试传入产品ID列表 @0 -- 测试传入产品ID列表 @0 - 测试传入产品ID列表 - 第61条的product属性 @3 - 第61条的project属性 @61 -- 测试传入产品ID列表 - - 第100条的product属性 @4 - - 第100条的project属性 @100 +- 测试传入产品ID列表 @0 - 测试传入不存在的产品ID列表 @0 */ @@ -24,6 +20,7 @@ include dirname(__FILE__, 2) . '/lib/product.unittest.class.php'; zenData('user')->gen(5); zenData('project')->loadYaml('program')->gen(30); +zenData('product')->loadYaml('product')->gen(20); zenData('projectproduct')->loadYaml('projectproduct')->gen(30); su('admin'); @@ -32,9 +29,8 @@ $productIdList[1] = range(1, 10); $productIdList[2] = range(11, 20); $productTester = new productTest(); -r($productTester->getProjectProductListTest($productIdList[0])) && p() && e('0'); // 测试传入空的产品ID列表 -r($productTester->getProjectProductListTest($productIdList[1])[1]) && p() && e('0'); // 测试传入产品ID列表 -r($productTester->getProjectProductListTest($productIdList[1])[2]) && p() && e('0'); // 测试传入产品ID列表 + +r($productTester->getProjectProductListTest($productIdList[0])) && p() && e('0'); // 测试传入空的产品ID列表 r($productTester->getProjectProductListTest($productIdList[1])[3]) && p('61:product,project') && e('3,61'); // 测试传入产品ID列表 -r($productTester->getProjectProductListTest($productIdList[1])[4]) && p('100:product,project') && e('4,100'); // 测试传入产品ID列表 -r($productTester->getProjectProductListTest($productIdList[2])) && p() && e('0'); // 测试传入不存在的产品ID列表 +r($productTester->getProjectProductListTest($productIdList[1])[4]) && p('') && e('0'); // 测试传入产品ID列表 +r($productTester->getProjectProductListTest($productIdList[2])) && p() && e('0'); // 测试传入不存在的产品ID列表 \ No newline at end of file diff --git a/module/product/ui/all.html.php b/module/product/ui/all.html.php index 15d615eded..0492963839 100644 --- a/module/product/ui/all.html.php +++ b/module/product/ui/all.html.php @@ -16,26 +16,8 @@ jsVar('orderBy', $orderBy); /* Get field list for data table. */ if(str_contains($orderBy, 'line')) $orderBy = str_replace('line', 'productLine', $orderBy); -$fnGetTableFieldList = function() use ($config) -{ - $fieldList = $this->loadModel('datatable')->getSetting('product'); - $extendFieldList = $this->product->getFlowExtendFields(); - foreach($extendFieldList as $extendField) - { - $extCol = $config->product->dtable->extendField; - $extCol['name'] = $extendField->field; - $extCol['title'] = $extendField->name; - $fieldList[$extendField->field] = $extCol; - } - - end($fieldList); - $endField = key($fieldList); - $fieldList[$endField]['align'] = 'left'; - - return $fieldList; -}; -$cols = $fnGetTableFieldList(); +$cols = $this->loadModel('datatable')->getSetting('product'); /* Closure function for generating table data. */ $productStats = initTableData($productStats, $cols, $this->product); diff --git a/module/product/ui/browse.html.php b/module/product/ui/browse.html.php index 803bbcfa45..0a0c74f333 100644 --- a/module/product/ui/browse.html.php +++ b/module/product/ui/browse.html.php @@ -477,7 +477,7 @@ featureBar li(searchToggle ( set::simple($isFromDoc), - set::open($browseType == 'bysearch' || $storyBrowseType == 'bysearch'), + set::open(!$isFromDoc && ($browseType == 'bysearch' || $storyBrowseType == 'bysearch')), set::module($config->product->search['module']), $isFromDoc ? set::target('#docSearchForm') : null, $isFromDoc ? set::onSearch(jsRaw('function(){$(this.element).closest(".modal").find("#featureBar .nav-item>.active").removeClass("active").find(".label").hide()}')) : null diff --git a/module/product/view/all.html.php b/module/product/view/all.html.php deleted file mode 100644 index 878128fd49..0000000000 --- a/module/product/view/all.html.php +++ /dev/null @@ -1,280 +0,0 @@ - - * @package ZenTaoPMS - * @version $Id - */ -?> - - - - - -
      - -
      -
      -

      product->noProduct;?>

      -
      - -
      -
      -
      ' data-preserve-nested='true' data-expand-nest-child='true'> - - - - - - - - - - - - - - product->getFlowExtendFields(); - foreach($extendFields as $extendField) echo ""; - ?> - - - - - - - - - - - - - - - $program):?> - - $lineName) - { - if(!isset($program[$lineID])) - { - $program[$lineID] = array(); - $program[$lineID]['product'] = ''; - $program[$lineID]['lineName'] = $lineName; - } - } - } - ?> - systemMode == 'ALM'):?> - > - - - - - - - - - - - - - - - - ";?> - - - - - - $line):?> - systemMode == 'ALM'):?> - - config->systemMode == 'ALM' and $programID) - { - $trAttrs = "data-id='line.$lineID' data-parent='program.$programID'"; - $trAttrs .= " data-nest-parent='program.$programID' data-nest-path='program.$programID,line.$lineID'" . "class='text-center'"; - } - else - { - $trAttrs = "data-id='line.$lineID' data-parent='0' data-nested='true'"; - $trClass = 'is-top-level table-nest-child text-center'; - $trAttrs .= " class='$trClass'"; - } - ?> - > - - - - - - - - - - - - - - - - ";?> - - - - - - - $product):?> - stories['finishClosed'] + $product->stories['unclosed']; - - $trClass = ''; - if($product->line and $this->config->systemMode == 'ALM') - { - $path = "line.$product->line,$product->id"; - if($this->config->systemMode == 'ALM' and $product->program) $path = "program.$product->program,$path"; - $trAttrs = "data-id='$product->id' data-parent='line.$product->line'"; - $trClass .= ' is-nest-child table-nest'; - $trAttrs .= " data-nest-parent='line.$product->line' data-nest-path='$path'"; - } - elseif($product->program and $this->config->systemMode == 'ALM') - { - $trAttrs = "data-id='$product->id' data-parent='program.$product->program'"; - $trClass .= ' is-nest-child table-nest'; - $trAttrs .= " data-nest-parent='program.$product->program' data-nest-path='program.$product->program,$product->id'"; - } - else - { - $trAttrs = "data-id='$product->id' data-parent='0'"; - $trClass .= ' no-nest'; - } - $trAttrs .= " class='$trClass'"; - ?> - > - - - - - - - - - - - - - - - " . $this->loadModel('flow')->getFieldValue($extendField, $product) . "";?> - - - - - - - -
      - lang->selectAll}'>";?> - - systemMode == 'ALM'):?> - - - product->name);?> - - product->manager);?> - story->story;?>bug->common;?>product->plan;?>product->release;?>{$extendField->name}actions;?>
      story->draft;?>story->activate;?>story->change;?>story->statusList['reviewing'];?>
      story->completeRate;?>
      bug->activate;?>bug->fixedRate;?>
      - - - - - $usersAvatar[$programPM], 'account' => $programPM, 'name' => $userName), 'avatar-circle avatar-top avatar-' . zget($userIdPairs, $programPM)); - - $userID = isset($userIdPairs[$programPM]) ? $userIdPairs[$programPM] : ''; - echo html::a($this->createLink('user', 'profile', "userID=$userID", '', true), $userName, '', "title='{$userName}' class='iframe' data-width='600'"); - } - ?> - %%
      - - - %%
      id => ''));?> - createLink('product', 'browse', 'productID=' . $product->id), $product->name); - ?> - - PO)) - { - $userName = zget($users, $product->PO); - echo html::smallAvatar(array('avatar' => $usersAvatar[$product->PO], 'account' => $product->PO, 'name' => $userName), 'avatar-circle avatar-' . zget($userIdPairs, $product->PO)); - - $userID = isset($userIdPairs[$product->PO]) ? $userIdPairs[$product->PO] : ''; - echo html::a($this->createLink('user', 'profile', "userID=$userID", '', true), $userName, '', "title='{$userName}' class='iframe' data-width='600'"); - } - ?> - stories['draft'];?>stories['active'];?>stories['changing'];?>stories['reviewing'];?>stories['finishClosed'] / $totalStories, 3) * 100;?>%unResolved;?>unResolved + $product->fixedBugs) == 0 ? 0 : round($product->fixedBugs / ($product->unResolved + $product->fixedBugs), 3) * 100;?>%plans;?>releases;?>product->buildOperateMenu($product, 'browse');?>
      - -
      -
      - -
      - - -product->checkedProducts);?> -app->getClientLang());?> - - - - diff --git a/module/product/view/batchedit.html.php b/module/product/view/batchedit.html.php deleted file mode 100755 index 67fc0cb3c0..0000000000 --- a/module/product/view/batchedit.html.php +++ /dev/null @@ -1,123 +0,0 @@ - - * @package ZenTaoPMS - * @version $Id$ - */ -?> - -product->aclTips['open']);?> -product->aclTips['private']);?> - -
      -
      -

      product->batchEdit;?>

      -
      - createLink('custom', 'ajaxSaveCustomFields', 'module=product§ion=custom&key=batchEditFields')?> - -
      -
      - product->edit->requiredFields) as $field) - { - if($field) - { - $requiredFields[$field] = ''; - if(strpos(",{$config->product->customBatchEditFields},", ",{$field},") !== false) $visibleFields[$field] = ''; - } - } - ?> -
      -
      - - - - - 6) - { - $width = 'w-200px'; - $full = ''; - } - ?> - config->systemMode == 'ALM'):?> - - - - config->systemMode == 'ALM'):?> - - - - - - - - - - product->getFlowExtendFields(); - foreach($extendFields as $extendField) echo ""; - ?> - - - - - config->moreLinks["PO"])) $this->config->moreLinks["POs[$productID]"] = $this->config->moreLinks["PO"]; - if(!empty($this->config->moreLinks["QD"])) $this->config->moreLinks["QDs[$productID]"] = $this->config->moreLinks["QD"]; - if(!empty($this->config->moreLinks["RD"])) $this->config->moreLinks["RDs[$productID]"] = $this->config->moreLinks["RD"]; - ?> - - - config->systemMode == 'ALM'):?> - program])):?> - - - - - - - config->systemMode == 'ALM'):?> - program]) ? $lines[$products[$productID]->program] : '';?> - - - - - - - - - - control == 'select' or $extendField->control == 'multi-select') ? " style='overflow:visible'" : '') . ">" . $this->loadModel('flow')->getFieldControl($extendField, $products[$productID], $extendField->field . "[{$productID}]") . "";?> - - config->moreLinks["POs[$productID]"])) unset($this->config->moreLinks["POs[$productID]"]); - if(isset($this->config->moreLinks["QDs[$productID]"])) unset($this->config->moreLinks["QDs[$productID]"]); - if(isset($this->config->moreLinks["RDs[$productID]"])) unset($this->config->moreLinks["RDs[$productID]"]); - ?> - - -
      idAB;?>'>product->program;?>product->name;?>'>product->line;?>'>product->PO;?>'>product->QD;?>'>product->RD;?>'>product->type;?>'>product->status;?>'>product->desc;?>'>product->acl;?>{$extendField->name}
      ' style='overflow:visible'>program, "class='form-control' disabled");?>' style='overflow:visible'>program, "class='form-control picker-select' onchange='loadProductLines(this.value, $productID)'");?>name, "class='form-control'");?>' style='overflow:visible' id="line_">config->systemMode == 'ALM' ? $productLines : $lines, $products[$productID]->line, "class='form-control picker-select'");?>' style='overflow:visible'>PO, "class='form-control picker-select'");?>' style='overflow:visible'>QD, "class='form-control picker-select'");?>' style='overflow:visible'>RD, "class='form-control picker-select'");?>'>product->typeList, $products[$productID]->type, "class='form-control'");?>'>product->statusList, $products[$productID]->status, "class='form-control'");?>'>desc), "rows='1' class='form-control autosize'");?>'> product->acls, $products[$productID]->acl));?>
      - -
      -
      -
      - diff --git a/module/product/view/browse.html.php b/module/product/view/browse.html.php deleted file mode 100755 index 87d3092fa6..0000000000 --- a/module/product/view/browse.html.php +++ /dev/null @@ -1,781 +0,0 @@ - - * @package product - * @version $Id: browse.html.php 4909 2013-06-26 07:23:50Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - -loadModel('story'); -$lang->story->createCommon = $storyType == 'story' ? $lang->story->createStory : $lang->story->createRequirement; -$unfoldStories = isset($config->product->browse->unfoldStories) ? json_decode($config->product->browse->unfoldStories, true) : array(); -$unfoldStories = zget($unfoldStories, $productID, array()); -$isProjectStory = $this->app->rawModule == 'projectstory'; -$projectHasProduct = $isProjectStory && !empty($project->hasProduct); -$projectIDParam = $isProjectStory ? "projectID=$projectID&" : ''; -js::set('browseType', $browseType); -js::set('account', $this->app->user->account); -js::set('reviewStory', $lang->product->reviewStory); -js::set('productID', $productID); -js::set('projectID', $projectID); -js::set('branch', $branch); -js::set('rawModule', $this->app->rawModule); -js::set('productType', $this->app->tab == 'product' ? $product->type : ''); -js::set('projectHasProduct', $projectHasProduct); -js::set('URAndSR', $this->config->URAndSR); -js::set('unfoldStories', $unfoldStories); -js::set('unfoldAll', $lang->execution->treeLevel['all']); -js::set('foldAll', $lang->execution->treeLevel['root']); -js::set('storyType', $storyType); -js::set('vision', $this->config->vision); -?> - -hasProduct) && empty($project->hasProduct) && $project->model != 'scrum'):?> - - - -app->getViewType() == 'xhtml'):?> -
      - - product->getByID($productID)->name ?> - -
      - -
      - -
      -
      - -
      -

      - story->noStory : $lang->story->noRequirement;?> - - createLink('story', 'create', "productID={$productID}&branch={$branch}&moduleID={$moduleID}&storyID=0&projectID=$projectID&bugID=0&planID=0&todoID=0&extra=&storyType=$storyType"), " " . $lang->story->create, '', "class='btn btn-info' data-app='$from'");?> - -

      -
      - -
      -
      - -
      - moduleName . ucfirst($this->methodName); - $useDatatable = (isset($config->datatable->$datatableId->mode) and $config->datatable->$datatableId->mode == 'datatable'); - $vars = "productID=$productID&branch=$branch&browseType=$browseType¶m=$param&storyType=$storyType&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}"; - if($from == 'project' and !empty($projectID)) $vars = "projectID=$projectID&productID=$productID&branch=$branch&browseType=$browseType¶m=$param&storyType=$storyType&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}"; - - if($useDatatable) include '../../common/view/datatable.html.php'; - $setting = $this->datatable->getSetting('product'); - $widths = $this->datatable->setFixedFieldWidth($setting); - $columns = 0; - - $canBeChanged = common::canModify('product', $product); - $canBatchEdit = ($canBeChanged and common::hasPriv($storyType, 'batchEdit')); - $canBatchClose = (common::hasPriv($storyType, 'batchClose') and strtolower($browseType) != 'closedbyme' and strtolower($browseType) != 'closedstory'); - $canBatchReview = ($canBeChanged and common::hasPriv($storyType, 'batchReview')); - $canBatchChangeStage = ($canBeChanged and common::hasPriv('story', 'batchChangeStage') and $storyType == 'story'); - $canBatchChangeBranch = ($canBeChanged and common::hasPriv($storyType, 'batchChangeBranch') and $this->session->currentProductType and $this->session->currentProductType != 'normal' and $productID); - $canBatchChangeModule = ($canBeChanged and common::hasPriv($storyType, 'batchChangeModule')); - $canBatchChangePlan = ($canBeChanged and common::hasPriv('story', 'batchChangePlan') and $storyType == 'story' and (!$isProjectStory or $projectHasProduct or ($isProjectStory and isset($project->model) and $project->model == 'scrum'))); - $canBatchAssignTo = ($canBeChanged and common::hasPriv($storyType, 'batchAssignTo')); - $canBatchUnlink = ($canBeChanged and $projectHasProduct and common::hasPriv('projectstory', 'batchUnlinkStory')); - $canBatchImportToLib = ($canBeChanged and $isProjectStory and isset($this->config->maxVersion) and common::hasPriv('story', 'batchImportToLib') and helper::hasFeature('storylib')); - $canBatchAction = ($canBatchEdit or $canBatchClose or $canBatchReview or $canBatchChangeStage or $canBatchChangeModule or $canBatchChangePlan or $canBatchAssignTo or $canBatchUnlink or $canBatchImportToLib or $canBatchChangeBranch); - ?> - ';?> - ' id='storyList' data-fixed-left-width='' data-fixed-right-width=''> - - - app->getViewType() == 'xhtml'):?> - $value) - { - if($value->id == 'title' || $value->id == 'id' || $value->id == 'pri' || $value->id == 'status') - { - if($storyType == 'requirement' and (in_array($value->id, array('plan', 'stage', 'taskCount', 'bugCount', 'caseCount')))) $value->show = false; - - if($value->show) - { - $this->datatable->printHead($value, $orderBy, $vars, $canBatchAction); - $columns ++; - } - } - }?> - - $value) - { - if($storyType == 'requirement' and (in_array($value->id, array('plan', 'stage', 'taskCount', 'bugCount', 'caseCount')))) $value->show = false; - - if($value->show) - { - $this->datatable->printHead($value, $orderBy, $vars, $canBatchAction); - $columns ++; - } - } - ?> - - - - - - children)) echo "data-children=" . count($story->children);?> data-cases='id, 0);?>'> - from = $from;?> - product]) ? $branchOptions[$story->product] : array(); - } - ?> - app->getViewType() == 'xhtml'):?> - $value) - { - if($value->id == 'title' || $value->id == 'id' || $value->id == 'pri' || $value->id == 'status') - { - $this->story->printCell($value, $story, $users, $branchOption, $storyStages, $modulePairs, $storyTasks, $storyBugs, $storyCases, $useDatatable ? 'datatable' : 'table', $storyType, $project); - } - }?> - - $value) $this->story->printCell($value, $story, $users, $branchOption, $storyStages, $modulePairs, $storyTasks, $storyBugs, $storyCases, $useDatatable ? 'datatable' : 'table', $storyType, $project);?> - - - children)):?> - - children as $key => $child):?> - from = $from;?> - - children)) ? ' table-child-bottom' : '';?> - - app->getViewType() == 'xhtml'):?> - $value) - { - if($value->id == 'title' || $value->id == 'id' || $value->id == 'pri' || $value->id == 'status') - { - $this->story->printCell($value, $child, $users, $branchOption, $storyStages, $modulePairs, $storyTasks, $storyBugs, $storyCases, $useDatatable ? 'datatable' : 'table', $storyType, $project); - } - }?> - - $value) $this->story->printCell($value, $child, $users, $branchOption, $storyStages, $modulePairs, $storyTasks, $storyBugs, $storyCases, $useDatatable ? 'datatable' : 'table', $storyType, $project);?> - - - - - - - -
      - ';?> - -
      - -
      -
      - - - - - - - diff --git a/module/product/view/close.html.php b/module/product/view/close.html.php deleted file mode 100644 index 7cd57a1925..0000000000 --- a/module/product/view/close.html.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @package product - * @version $Id: close.html.php 935 2013-01-16 07:49:24Z wwccss@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -
      -
      -

      - id;?> - name'>" . $product->name . '') : html::a($this->createLink('product', 'view', "productID=$product->id"), $product->name);?> - - arrow . $lang->product->close;?> - -

      -
      -
      - - - - - - printExtendFields($product, 'table');?> - - - - - - - -
      product->status;?>
      comment;?>
      - - goback, $this->session->taskList, 'self', '', 'btn btn-wide');?> -
      -
      -
      -
      - -
      -
      - diff --git a/module/product/view/create.html.php b/module/product/view/create.html.php deleted file mode 100644 index ac488da84f..0000000000 --- a/module/product/view/create.html.php +++ /dev/null @@ -1,129 +0,0 @@ - - * @package product - * @version $Id: create.html.php 4129 2013-01-18 01:58:14Z wwccss $ - * @link https://www.zentao.net - */ -?> - - - - -config->systemMode);?> - -
      -
      -
      -

      product->create;?>

      -
      -
      - - - config->systemMode == 'ALM'):?> - - - - - - - - - - - - - - - - - - setCode) and $config->setCode == 1):?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - printExtendFields('', 'table');?> - - - - - - - - - - - - - - - - -
      program->common;?>
      product->line;?> -
      - 1 ? '' : 'checked';?> - - - - -
      - onchange="toggleLine(this)" id="newLine0" /> - -
      -
      - -
      -
      product->name;?>
      product->code;?>
      product->PO;?>app->user->account, "class='form-control chosen'");?>
      product->QD;?>
      product->RD;?>
      product->reviewer;?>
      product->type;?> - product->typeList as $key => $type) $productTypeList[$key] = $type . zget($lang->product->typeTips, $key, ''); - ?> - -
      product->status;?>
      product->desc;?> - fetch('user', 'ajaxPrintTemplates', "type=product&link=desc");?> - -
      product->acl;?>product->aclList, 'private', "onclick='setWhite(this.value);'", 'block'));?>
      whitelist;?> -
      - - fetch('my', 'buildContactLists', "dropdownName=whitelist");?> -
      -
      - - goback, '', 'class="btn btn-wide"') : html::backButton();?> -
      -
      -
      -
      - diff --git a/module/product/view/dynamic.html.php b/module/product/view/dynamic.html.php deleted file mode 100755 index 4855e32136..0000000000 --- a/module/product/view/dynamic.html.php +++ /dev/null @@ -1,129 +0,0 @@ -dynamic view file of dashboard module of ZenTaoPMS. - * - * @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com) - * @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html) - * @author Chunsheng Wang - * @package dashboard - * @version $Id: action->dynamic.html.php 1477 2011-03-01 15:25:50Z wwccss $ - * @link https://www.zentao.net - */ -?> - - -
      -
      - -
      -

      action->noDynamic;?>

      -
      - - - $actions):?> - -
      -
      - - action->dynamic->today;?> - - - -
      -
        - - $action):?> - - major ? 'active' : '';?> - action, array('releaseddoc', 'collected'))) $class .= " {$action->action}";?> -
      • major) echo "class='$class'";?>> -
        - time?> - - actor);?> - actionLabel;?> - objectLabel;?> - objectType == 'module' and strpos(',created,edited,moved,', "$action->action") !== false) ? trim($action->extra, ',') : $action->objectID;?> - objectName) echo !empty($action->objectLink) ? html::a($action->objectLink, $action->objectName) : $action->objectName;?> - -
        -
      • - -
      -
      - - -
      -
      - -originalDate) + 24 * 3600); -$lastDate = substr($action->originalDate, 0, 10); -$hasPre = $this->action->hasPreOrNext($firstDate, 'pre'); -$hasNext = $this->action->hasPreOrNext($lastDate, 'next'); -$preLink = $hasPre ? inlink('dynamic', "productID=$productID&type=$type¶m=$param&recTotal={$pager->recTotal}&date=" . strtotime($firstDate) . '&direction=pre') : 'javascript:;'; -$nextLink = $hasNext ? inlink('dynamic', "productID=$productID&type=$type¶m=$param&recTotal={$pager->recTotal}&date=" . strtotime($lastDate) . '&direction=next') : 'javascript:;'; -?> - -
      - -
      - - - - diff --git a/module/product/view/edit.html.php b/module/product/view/edit.html.php deleted file mode 100644 index f6d1ee3692..0000000000 --- a/module/product/view/edit.html.php +++ /dev/null @@ -1,110 +0,0 @@ - - * @package product - * @version $Id: edit.html.php 4129 2013-01-18 01:58:14Z wwccss $ - * @link https://www.zentao.net - */ -?> - - - -program);?> -program);?> - -
      -
      -
      -

      - id;?> - createLink('product', 'view', 'product=' . $product->id), $product->name, '', "title='$product->name'");?> - arrow . ' ' . $lang->product->edit;?> -

      -
      -
      - - - config->systemMode == 'ALM'):?> - - - program and strpos(",{$this->app->user->view->programs},", ",{$product->program},") === false) ? 'disabled' : '';?> - program);?> - - - - - - - - - - - - setCode) and $config->setCode == 1):?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - printExtendFields($product, 'table');?> - - - - - - - - - - - - - - - - -
      product->program;?>program, "class='form-control chosen' $attr");?>
      product->line;?>line, "class='form-control picker-select'");?>
      product->name;?>name, "class='form-control' required");?>
      product->code;?>code, "class='form-control' required");?>
      product->PO;?>PO, "class='form-control chosen'");?>
      product->QD;?>QD, "class='form-control chosen'");?>
      product->RD;?>RD, "class='form-control chosen'");?>
      product->reviewer;?>reviewer, "class='form-control picker-select' multiple");?>
      product->type;?>product->typeList, $product->type, "class='form-control'");?>
      product->status;?>product->statusList, $product->status, "class='form-control'");?>
      product->desc;?>desc), "rows='8' class='form-control'");?>
      product->acl;?>product->aclList, $product->acl, "onclick='setWhite(this.value);'", 'block'));?>
      whitelist;?> -
      - whitelist, 'class="form-control picker-select" multiple');?> - fetch('my', 'buildContactLists', "dropdownName=whitelist");?> -
      -
      - - - -
      -
      -
      -
      - diff --git a/module/product/view/export.html.php b/module/product/view/export.html.php deleted file mode 100644 index dc449f2d8a..0000000000 --- a/module/product/view/export.html.php +++ /dev/null @@ -1,13 +0,0 @@ - - * @package product - * @version $Id$ - * @link https://www.zentao.net - */ -?> - diff --git a/module/product/view/index.html.php b/module/product/view/index.html.php deleted file mode 100644 index 8d227baa6e..0000000000 --- a/module/product/view/index.html.php +++ /dev/null @@ -1,21 +0,0 @@ - - * @package product - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -
      -

      product->noProduct;?> " . $lang->product->create, '', "class='btn btn-info'");?>

      -
      - -fetch('block', 'dashboard', 'dashboard=product');?> - - diff --git a/module/product/view/kanban.html.php b/module/product/view/kanban.html.php deleted file mode 100644 index 532ab36712..0000000000 --- a/module/product/view/kanban.html.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @package ZenTaoPMS - * @version $Id - */ -?> - - -systemMode == 'ALM'):?> -
      -
      - product->showAllProjects ? 'checked' : '';?>> - -
      -
      - -
      - -
      -

      product->noProduct;?>

      -
      - - $programs):?> - -
      -
      - product->myProduct : $lang->product->otherProduct;?> -
      -
      -
      -
      -
      - - $lang->product->unclosedProduct, 'type' => 'unclosedProduct'); - $kanbanColumns['unexpiredPlan'] = array('name' => $lang->product->unexpiredPlan, 'type' => 'unexpiredPlan'); - $kanbanColumns['doingProject'] = array('name' => $lang->product->doingProject, 'type' => 'doingProject'); - $kanbanColumns['doingExecution'] = array('name' => $lang->product->doingExecution, 'type' => 'doingExecution'); - $kanbanColumns['normalRelease'] = array('name' => $lang->product->normalRelease, 'type' => 'normalRelease'); - $userPrivs = array(); - $userPrivs['product'] = common::hasPriv('product', 'browse'); - $userPrivs['productplan'] = common::hasPriv('productplan', 'view'); - $userPrivs['project'] = common::hasPriv('project', 'index'); - $userPrivs['execution'] = common::hasPriv('execution', 'task'); - $userPrivs['release'] = common::hasPriv('release', 'view'); - js::set('kanbanColumns', array_values($kanbanColumns)); - js::set('userPrivs', $userPrivs); - js::set('kanbanList', $kanbanList); - js::set('programList', $programList); - js::set('productList', $productList); - js::set('planList', $planList); - js::set('projectList', $projectList); - js::set('projectProduct', $projectProduct); - js::set('latestExecutions', $latestExecutions); - js::set('classicExecution', $executionList); - js::set('releaseList', $releaseList); - js::set('hourList', $hourList); - js::set('doingText', $lang->product->doing); - js::set('isLightMode', $config->systemMode == 'light'); - ?> - -
      - diff --git a/module/product/view/manageline.html.php b/module/product/view/manageline.html.php deleted file mode 100644 index 5f6504e781..0000000000 --- a/module/product/view/manageline.html.php +++ /dev/null @@ -1,163 +0,0 @@ - - * @package ZenTaoPMS - * @version $Id - */ -?> - -
      -
      -
      -
      -
      product->line;?>
      -
      -
      -
        -
        -
        -
        -
        -
        -
        -
        product->manageLine;?>
        -
        -
        - - - - - - - -
        -
        -
        -
        product->lineName;?>
        - config->systemMode == 'ALM'):?> -
        product->program;?>
        - -
        -
        - - -
        -
        id]", $line->name, 'class="form-control"');?>
        - config->systemMode == 'ALM'):?> -
        id]", $programs, $line->root, "class='form-control chosen' required");?>
        - -
        -
        - - -
        -
        - config->systemMode == 'ALM'):?> -
        - -
        - - -
        -
        - -
        -
        -
        -
        - config->systemMode == 'ALM'):?> -
        - -
        - - -
        -
        -
        -
        - - -
        -
        -
        -
        -
        -
        -
        - - diff --git a/module/product/view/project.html.php b/module/product/view/project.html.php deleted file mode 100644 index d2108c5ece..0000000000 --- a/module/product/view/project.html.php +++ /dev/null @@ -1,140 +0,0 @@ - - * @package ZenTaoPMS - * @version $Id: index.html.php 2343 2011-11-21 05:24:56Z wwccss $ - */ -?> - -loadLang('execution');?> - -
        - -
        -

        project->empty;?>

        -
        - -
        - - - - - systemMode == 'ALM'):?> - - - - - - - - - - - - - - - - - - - status == 'wait') $waitCount ++;?> - status == 'doing') $doingCount ++;?> - status == 'suspended') $suspendedCount ++;?> - status == 'closed') $closedCount ++;?> - - - systemMode == 'ALM'):?> - - - - - processStatus('project', $project);?> - - - - app->getClientLang(), array('zh-cn','zh-tw')) ? round((float)$project->budget / 10000, 2) . $this->lang->project->tenThousand : round((float)$project->budget, 2);?> - budget != 0 ? zget($this->lang->project->currencySymbol, $project->budgetUnit) . ' ' . $projectBudget : $this->lang->project->future;?> - - - - - - - - - -
        idAB;?>program->common;?>project->name;?>project->status;?>project->PM;?>project->budget;?>project->begin;?>project->end;?>project->estimate;?>project->consume;?>project->progress;?>
        id);?>programName;?> - model == 'scrum' ? 'sprint' : $project->model; - echo html::a($this->createLink('project', 'index', 'project=' . $project->id), " " . $project->name, '', "title='$project->name'"); - ?> - - - - PM]) ? $PMList[$project->PM]->id : ''?> - PM)) echo html::a($this->createLink('user', 'profile', "userID=$userID", '', true), zget($users, $project->PM), '', "data-toggle='modal' data-type='iframe' data-width='800'");?> - begin;?>end;?>hours->totalEstimate . $lang->execution->workHourUnit;?>hours->totalConsumed . $lang->execution->workHourUnit;?> -
        -
        hours->progress);?>
        -
        -
        - -
        - -
        - - - diff --git a/module/product/view/roadmap.html.php b/module/product/view/roadmap.html.php deleted file mode 100644 index bcfbc5ee7a..0000000000 --- a/module/product/view/roadmap.html.php +++ /dev/null @@ -1,85 +0,0 @@ - - * @package product - * @version $Id: roadmap.html.php 4129 2013-01-18 01:58:14Z wwccss $ - * @link https://www.zentao.net - */ -?> - -
        -

        product->iteration;?> product->iterationInfo, $roadmaps['total']);?>

        - type != 'normal'):?> -
        - -
        - -
        - $branchName):?> -
        - $yearRoadmaps) - { - if(isset($yearRoadmaps[$branchKey])) - { - $hasRoadmaps = true; - break; - } - } - ?> - -
        -

        - release->noRelease;?> - - createLink('release', 'create', "productID=$product->id&branch=$branchKey"), " " . $lang->release->create, '', "class='btn btn-info'");?> - -

        -
        - - $yearRoadmaps):?> - - -
        -
        -
        year) : '');?>
        -
        product->iterationInfo, count($groupRoadmaps, 1) - count($groupRoadmaps));?>
        -
        - - $roadmapData):?> - - -
        - - -
        - -
        -
        - diff --git a/module/product/view/showerrornone.html.php b/module/product/view/showerrornone.html.php deleted file mode 100644 index 0e3797b8be..0000000000 --- a/module/product/view/showerrornone.html.php +++ /dev/null @@ -1,27 +0,0 @@ - - * @package product - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -app->tab == 'project'):?> -
        -

        product->noProduct;?> " . $lang->project->manageProducts, '', "class='btn btn-info' data-app='project'");?>

        -
        -app->tab == 'execution'):?> -
        -

        product->noProduct;?> " . $lang->execution->manageProducts, '', "class='btn btn-info' data-app='execution'");?>

        -
        - -
        -

        product->noProduct;?> " . $lang->product->create, '', "class='btn btn-info' data-app='product'");?>

        -
        - - diff --git a/module/product/view/track.html.php b/module/product/view/track.html.php deleted file mode 100644 index 730fbabda0..0000000000 --- a/module/product/view/track.html.php +++ /dev/null @@ -1,124 +0,0 @@ - - -app->rawModule);?> - -
        -
        - -
        -

        - noData;?> -

        -
        - - app->rawModule == 'projectstory' ? "style='overflow: unset; text-align: left'" : '';?> - app->rawModule == 'projectstory' ? 'project' : 'product';?> - app->rawModule == 'projectstory' ? 'projectstory' : 'story';?> -
        - - - - URAndSR):?> - - - - - edition == 'max' or $config->edition == 'ipd'):?> - - - - edition == 'max' or $config->edition == 'ipd') and helper::hasFeature('devops')):?> - - - - - - - $requirement):?> - track;?> - - story->noRequirement;?> - - URAndSR):?> - - - - - $story):?> - 0) echo '';?> - - - edition == 'max' or $config->edition == 'ipd'):?> - - - - edition == 'max' or $config->edition == 'ipd') and helper::hasFeature('devops')):?> - - - - 0) echo '';?> - - - - - - -
        > - app->rawModule == 'projectstory' and $this->session->hasProduct): ?> - - - story->requirement;?> - - story->story;?>story->tasks;?>story->design;?>story->case;?>story->repoCommit;?>story->bug;?>
        story->statusList, $requirement->status);?> - type, 'view') ? html::a($this->createLink('story', 'view', "storyID=$requirement->id"), $requirement->title, '', "title=$requirement->title data-app='$tab'") : $requirement->title;?> - - -
        - parent) and $story->parent > 0):?>lang->story->childrenAB;?> - createLink($module, 'view', "storyID=$storyID"), $story->title, '', "title='$story->title' data-app='$tab'");?> - - tasks as $taskID => $task):?> - createLink('task', 'view', "taskID=$taskID"), $task->name, '', "title='$task->name'") . '
        ';?> - -
        - designs as $designID => $design):?> - createLink('design', 'view', "designID=$designID"), $design->name, '', "title='$design->name'") . '
        ';?> - -
        - cases as $caseID => $case):?> - createLink('testcase', 'view', "caseID=$caseID"), $case->title, '', "title='$case->title'") . '
        ';?> - -
        - revisions as $revision => $repoComment):?> - createLink('design', 'revision', "repoID=$revision"), '#'. $revision . '-' . $repoComment, '', "data-app='devops'") . '
        '; - ?> - -
        - bugs as $bugID => $bug):?> - createLink('bug', 'view', "bugID=$bugID"), $bug->title, '', "title='$bug->title'") . '
        ';?> - -
        - -
        - -
        -
        - diff --git a/module/product/view/view.html.php b/module/product/view/view.html.php deleted file mode 100644 index e450e60d5e..0000000000 --- a/module/product/view/view.html.php +++ /dev/null @@ -1,201 +0,0 @@ - - * @package product - * @version $Id: view.html.php 4129 2013-01-18 01:58:14Z wwccss $ - * @link https://www.zentao.net - */ -?> - - - -
        > -
        -
        -
        -
        -
        - setCode) or $config->setCode == 0) ? 'hidden' : '';?> -

        id;?> code;?> name;?>

        -
        -

        desc;?>

        -
        -
        - type == 'platform'):?> -
        -
        product->branchName['platform'];?>id}")?>">
        - -
        - -
        -
        product->manager;?>
        -
        - - - - - - - - - - - - - config->edition == 'open'):?> - - - - - config->edition != 'open'):?> - - - - - - -
        productCommon;?>PO);?> product->release;?>RD);?>
        product->qa;?>QD);?> product->reviewer;?>
        product->reviewer;?>
        -
        -
        -
        -
        product->basicInfo;?>
        -
        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - acl == 'custom'):?> - - - - - - -
        product->code;?>code;?>story->openedBy?>createdBy);?>
        product->type;?>product->typeList, $product->type);?>story->openedDate?>createdDate, DT_DATE1);?>
        productCommon . $lang->product->status;?>product->statusList, $product->status);?>product->acl;?>code) ? "colspan='4'" : "colspan='2'";?>>product->aclList[$product->acl];?>
        product->type;?>product->typeList, $product->type);?>story->openedBy?>createdBy);?>
        productCommon . $lang->product->status;?>product->statusList, $product->status);?>story->openedDate?>createdDate, DT_DATE1);?>
        product->acl;?>product->aclList[$product->acl];?>
        product->whitelist;?> - - whitelist); - foreach($whitelist as $groupID) if(isset($groups[$groupID])) echo $groups[$groupID] . ' '; - ?> - -
        -
        -
        -
        -
        product->otherInfo;?>
        -
        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        story->statusList['active'] . $space . $lang->story->common;?>stories['active']?>product->plans?>plans?>product->bugs?>bugs?>
        story->statusList['draft'] . $space . $lang->story->common;?>stories['draft']?>product->builds?>builds?>product->docs?>docs?>
        story->statusList['changing'] . $space . $lang->story->common;?>stories['changing']?>product->releases?>releases?>product->cases?>cases?>
        story->statusList['reviewing'] . $space . $lang->story->common;?>stories['reviewing']?>product->projects?>projects?>product->executions?>executions?>
        -
        -
        - printExtendFields($product, 'div', "position=left&inForm=0&inCell=1");?> -
        -
        -
        -
        -
        - session->productList ? $this->session->productList : inlink('browse', "productID=$product->id"); - common::printBack($browseLink); - - if(!$product->deleted) echo $this->product->buildOperateMenu($product, 'view'); - ?> -
        -
        -
        -
        -
        -
        - printExtendFields($product, 'div', "position=right&inForm=0&inCell=1");?> - - createLink('action', 'comment', "objectType=product&objectID=$product->id");?> - -
        -
        -
        -
        -
        - -
        - diff --git a/module/productplan/config.php b/module/productplan/config.php index 18074af9ca..46643c97c7 100644 --- a/module/productplan/config.php +++ b/module/productplan/config.php @@ -64,13 +64,13 @@ $config->productplan->actionList['linkStory']['icon'] = 'link'; $config->productplan->actionList['linkStory']['hint'] = $lang->productplan->linkStory; $config->productplan->actionList['linkStory']['text'] = $lang->productplan->linkStory; $config->productplan->actionList['linkStory']['notLoadModel'] = true; -if($app->rawModule) $config->productplan->actionList['linkStory']['url'] = array('module' => $app->rawModule, 'method' => 'view', 'params' => 'planID={id}&type=story&orderBy=id_desc&link=true'); +if($app->rawModule) $config->productplan->actionList['linkStory']['url'] = common::hasPriv('productplan', 'linkStory') ? array('module' => $app->rawModule, 'method' => 'view', 'params' => 'planID={id}&type=story&orderBy=id_desc&link=true') : null; $config->productplan->actionList['linkBug']['icon'] = 'bug'; $config->productplan->actionList['linkBug']['hint'] = $lang->productplan->linkBug; $config->productplan->actionList['linkBug']['text'] = $lang->productplan->linkBug; $config->productplan->actionList['linkBug']['notLoadModel'] = true; -if($app->rawModule) $config->productplan->actionList['linkBug']['url'] = array('module' => $app->rawModule, 'method' => 'view', 'params' => 'planID={id}&type=bug&orderBy=id_desc&link=true'); +if($app->rawModule) $config->productplan->actionList['linkBug']['url'] = common::hasPriv('productplan', 'linkBug') ? array('module' => $app->rawModule, 'method' => 'view', 'params' => 'planID={id}&type=bug&orderBy=id_desc&link=true') : null; $config->productplan->actionList['edit']['icon'] = 'edit'; $config->productplan->actionList['edit']['hint'] = $lang->productplan->edit; diff --git a/module/productplan/view/batchchangestatus.html.php b/module/productplan/view/batchchangestatus.html.php deleted file mode 100755 index 52993a3f0f..0000000000 --- a/module/productplan/view/batchchangestatus.html.php +++ /dev/null @@ -1,55 +0,0 @@ - - * @package productplan - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
        -
        -

        productplan->common . $lang->hyphen . $lang->productplan->batchClose;?>

        -
        -
        "> - - - - - - - - - - - $plan):?> - - - - - - - - - - - -
        idAB;?>productplan->title;?>productplan->status;?>productplan->closedReason;?>productplan->comment;?>
        title;?>title;?> - - - - -
        - -
        -
        - - -
        -
        -
        - diff --git a/module/productplan/view/batchedit.html.php b/module/productplan/view/batchedit.html.php deleted file mode 100644 index 8fbffe2b73..0000000000 --- a/module/productplan/view/batchedit.html.php +++ /dev/null @@ -1,88 +0,0 @@ - - * @package productplan - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - - -
        -
        -

        productplan->batchEdit;?>

        -
        -
        - - - - - type != 'normal'):?> - - - - - - - - productplan->getFlowExtendFields(); - foreach($extendFields as $extendField) echo ""; - ?> - - - - - begin == $config->productplan->future and $plan->end == $config->productplan->future) ? 'checked="checked"' : '';?> - - - type != 'normal'):?> - - - - parent != -1):?> - - - - - begin == $config->productplan->future and $plan->end == $config->productplan->future)) ? 'disabled="disabled"' : '';?> - parent == -1 and ($plan->begin == $config->productplan->future and $plan->end == $config->productplan->future)) $disabled = 'disabled="disabled"';?> - begin == $config->productplan->future) $plan->begin = '';?> - end == $config->productplan->future) $plan->end = '';?> - - - - control == 'select' or $extendField->control == 'multi-select') ? " style='overflow:visible'" : '') . ">" . $this->loadModel('flow')->getFieldControl($extendField, $plan, $extendField->field . "[{$plan->id}]") . "";?> - - - - - - - - -
        productplan->id?>product->branch;?>productplan->title?>productplan->status?>productplan->begin?>productplan->end?>productplan->future?>{$extendField->name}
        id . html::hidden("id[$plan->id]", $plan->id);?> - parent == -1 ? "disabled='disabled'" : ''; - $parentBranches = array(); - if($plan->parent > 0 and isset($parentList[$plan->parent])) - { - foreach($branchTagOption as $branchID => $branchName) - { - if(strpos(",{$parentList[$plan->parent]->branch},", ",$branchID,") !== false) $parentBranches[$branchID] = $branchName; - } - } - echo html::select("branch[$plan->id][]", ($plan->parent > 0 and !empty($parentBranches)) ? $parentBranches : $branchTagOption, $plan->branch, "onchange='getConflictStories($plan->id); 'class='form-control chosen' multiple $disabled"); - ?> - id]", $plan->title, "class='form-control'")?>id]", array_slice($lang->productplan->statusList,($plan->status == 'wait' ? 0 : 1)), $plan->status, "class='form-control chosen'");?>id]", array_slice($lang->productplan->statusList,($plan->status == 'wait' ? 0 : 1)), $plan->status, "class='form-control chosen' disabled ");?>id]", $plan->begin, "class='form-control form-date' $disabled");?>id]", $plan->end, "class='form-control form-date' $disabled");?>
        onclick="changeDate(id;?>);"/>
        - - -
        -
        -
        - diff --git a/module/productplan/view/browse.html.php b/module/productplan/view/browse.html.php deleted file mode 100644 index 8696ff22ce..0000000000 --- a/module/productplan/view/browse.html.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @package plan - * @version $Id: browse.html.php 4707 2013-05-02 06:57:41Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - -productplan->confirmDelete)?> - - -productplan->noLinkedProject);?> -productplan->enterProjectList);?> -productplan->projectNotEmpty)?> - - - -config->minColWidth);?> -config->maxColWidth);?> - - - diff --git a/module/productplan/view/browsebykanban.html.php b/module/productplan/view/browsebykanban.html.php deleted file mode 100644 index 67e9cdd7da..0000000000 --- a/module/productplan/view/browsebykanban.html.php +++ /dev/null @@ -1,75 +0,0 @@ - - * @package plan - * @version $Id: browsebykanban.html.php 4707 2021-12-27 16:07:41Z $ - * @link https://www.zentao.net - */ -?> - - - -rawModule);?> - -productplan->noAssigned);?> -productplan);?> - common::hasPriv('kanban', 'assigncard')));?> - -
        -
        -
        -
        -
        diff --git a/module/productplan/view/browsebylist.html.php b/module/productplan/view/browsebylist.html.php deleted file mode 100644 index 882ba26be7..0000000000 --- a/module/productplan/view/browsebylist.html.php +++ /dev/null @@ -1,267 +0,0 @@ - - * @package plan - * @version $Id: browsebylist.html.php 4707 2013-05-02 06:57:41Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> -productplan->browse->unfoldPlans) ? json_decode($config->productplan->browse->unfoldPlans, true) : array();?> - - - -rawModule == 'projectplan';?> - -
        -
        - - - - -
        -

        - productplan->noPlan;?> - - createLink('projectplan', 'create', "productID=$product->id&branch=$branch"), " " . $lang->productplan->create, '', "class='btn btn-info'"); - } - elseif(common::hasPriv('productplan', 'create')) - { - echo html::a($this->createLink('productplan', 'create', "productID=$product->id&branch=$branch"), " " . $lang->productplan->create, '', "class='btn btn-info'"); - } - ?> - -

        -
        - -
        id&branch=$branch")?>' data-preserve-nested='true'> - - - recTotal}&recPerPage={$pager->recPerPage}"; ?> - - - - - - - session->currentProductType != 'normal'):?> - - - - - - - - - - productplan->getFlowExtendFields(); - foreach($extendFields as $extendField) echo ""; - ?> - - - - - loadModel('file');?> - - file->replaceImgURL($plan, 'desc'); - if($plan->parent == '-1') - { - $parent = $plan->id; - $children = isset($plan->children) ? $plan->children : 0; - - $totalParent ++; - } - if($plan->parent == 0) $parent = 0; - if(!empty($parent) and $plan->parent > 0 and $plan->parent != $parent) $parent = 0; - if($plan->parent <= 0) $i = 0; - if($plan->parent > 0) $totalChild ++; - if($plan->parent == 0) $totalIndependent ++; - - $class = ''; - if(!empty($parent) and $plan->parent == $parent) - { - $class = "table-children parent-{$parent}"; - $class .= $i == 0 ? ' table-child-top' : ''; - $class .= ($i + 1 == $children) ? ' table-child-bottom' : ''; - $i++; - } - ?> - - - - - - - session->currentProductType != 'normal'):?> - - branch) as $branchID) $planBranches .= $branchOption[$branchID] . ',';?> - - - - - - - - - - " . $this->loadModel('flow')->getFieldValue($extendField, $plan) . "";?> - - - - -
        - -
        - -
        - - idAB);?> -
        productplan->title);?>productplan->status);?>product->branchName[$product->type]);?>productplan->begin);?>productplan->end);?>productplan->stories;?>productplan->bugs;?>productplan->hour;?>productplan->execution;?>productplan->desc;?>{$extendField->name}actions;?>
        - - id => ''), '', $attribute);?> - id"), sprintf('%03d', $plan->id)) : html::a(helper::createLink('productplan', 'view', "planID=$plan->id"), sprintf('%03d', $plan->id));?> - - id);?> - - ' title="title?>"> - expired and in_array($plan->status, array('wait', 'doing'))) - { - $class .= ' expired'; - $expired = "{$this->lang->productplan->expired}"; - } - - echo "
        "; - if($plan->parent > 0) echo "{$this->lang->productplan->childrenAB}"; - echo html::a($this->createLink($app->rawModule, 'view', "id=$plan->id"), $plan->title); - if(!empty($expired)) echo $expired; - if(isset($plan->children)) echo ''; - echo '
        '; - ?> -
        status)?>'>begin == $config->productplan->future ? $lang->productplan->future : $plan->begin;?>end == $config->productplan->future ? $lang->productplan->future : $plan->end;?>stories;?>bugs;?>hour;?> - ', '
        ', '
        ', '
        '), "\n", str_replace(array("\n", "\r"), '', $plan->desc)), ''));?> -
        -
        productplan->buildOperateMenu($plan, 'browse'); ?>
        - -
        - -
        - diff --git a/module/productplan/view/close.html.php b/module/productplan/view/close.html.php deleted file mode 100644 index 3feb2ebe43..0000000000 --- a/module/productplan/view/close.html.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @package productplan - * @link https://www.zentao.net - */ -?> - - -
        -
        -
        -

        - id;?> - title'>" . $productplan->title . '';?> - arrow . $lang->productplan->close;?> -

        -
        -
        - - - - - - - - - - - - -
        productplan->closedReason;?>
        productplan->comment;?>
        - -
        -
        -
        -
        -
        - diff --git a/module/productplan/view/create.html.php b/module/productplan/view/create.html.php deleted file mode 100644 index 9c6a591b18..0000000000 --- a/module/productplan/view/create.html.php +++ /dev/null @@ -1,101 +0,0 @@ - - * @package productplan - * @version $Id: create.html.php 4728 2013-05-03 06:14:34Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -execution->weekend);?> - -productplan->last);?> - - -
        -
        -
        -

        productplan->createChildren : $lang->productplan->create;?>

        -
        -
        - - - - - - - - shadow):?> - - - - - - - - - - - type != 'normal'):?> - - - $branchName) - { - if(strpos(",$parentPlan->branch,", ",$branchID,") === false) unset($branches[$branchID]); - } - } - ?> - - - - - - - - - - - - - - - - - - - - - - - printExtendFields('', 'table', 'columns=3');?> - - - - -
        productplan->parent;?>title;?> -
        productplan->product;?>name;?>
        productplan->parent;?> '') + $parentPlanPairs, 0, "class='form-control chosen'");?> -
        product->branch;?>
        productplan->title;?>productplan->last . ': ' . $lastPlan->title . ')';?>
        productplan->begin;?> -
        - - -
        -
        productplan->end;?>productplan->endList , '', "onclick='computeEndDate(this.value)'");?>
        productplan->desc;?>
        - - - id);?> - - - -
        -
        -
        -
        - diff --git a/module/productplan/view/edit.html.php b/module/productplan/view/edit.html.php deleted file mode 100644 index eb3e5022b7..0000000000 --- a/module/productplan/view/edit.html.php +++ /dev/null @@ -1,92 +0,0 @@ - - * @package productplan - * @version $Id: edit.html.php 4728 2013-05-03 06:14:34Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -execution->weekend);?> - - - - -id);?> -
        -
        -
        -

        id"), $plan->title, '', "title='$plan->title'");?>

        -
        -
        - - - shadow):?> - - - - - - parent == '-1'):?> - parent);?> - - - - - - shadow and $product->type != 'normal'):?> - - - - - - - - - - - - parent == -1 ? "disabled='disabled'" : '' ;?> - - - - begin == $config->productplan->future and $plan->end == $config->productplan->future) ? "checked='checked'" : '';?> - - - - - - - - end == $config->productplan->future ? 0 : (strtotime($plan->end) - strtotime($plan->begin)) / 3600 / 24 + 1;?> - - - printExtendFields($plan, 'table', 'columns=3');?> - - - - - - - - -
        productplan->product;?>name;?>
        productplan->parent;?> '') + $parentPlanPairs, $plan->parent, "class='form-control chosen'");?> -
        product->branch;?>branch, "class='form-control chosen' multiple");?>
        productplan->title;?>title, "class='form-control' required");?>
        productplan->status;?>productplan->statusList,($plan->status == 'wait' ? 0 : 1)), $plan->status, "class='form-control chosen' $disabled");?>
        productplan->begin;?>begin != $config->productplan->future ? formatTime($plan->begin) : '', "class='form-control form-date'");?> -
        - /> - -
        -
        productplan->end;?>end != $config->productplan->future ? formatTime($plan->end) : '', "class='form-control form-date'");?>productplan->endList , $deltaValue, "onclick='computeEndDate(this.value)'");?>
        productplan->desc;?>desc), "rows='10' class='form-control kindeditor' hidefocus='true'");?>
        - - - id);?> -
        -
        -
        -
        - diff --git a/module/productplan/view/linkbug.html.php b/module/productplan/view/linkbug.html.php deleted file mode 100644 index 0dc8603008..0000000000 --- a/module/productplan/view/linkbug.html.php +++ /dev/null @@ -1,79 +0,0 @@ - - * @package productplan - * @version $Id: linkbug.html.php 5096 2013-07-11 07:02:43Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> -
        -
        -
        id&browseType=$browseType¶m=$param&orderBy=$orderBy")?>'> -
        - productplan->unlinkedBugs;?> -
        - - - - - - - - - - - - - - - - - - - - - - - - - -
        - -
        - -
        - - idAB;?> -
        priAB;?>bug->title;?>openedByAB;?>bug->abbr->assignedTo;?>bug->status;?>
        - id => sprintf('%03d', $bug->id)));?> - bug->priList, $bug->pri)?>createLink('bug', 'view', "bugID=$bug->id", '', true), $bug->title, '', "data-toggle='modal' data-type='iframe' data-width='90%'");?>openedBy);?>assignedTo);?> - - processStatus('bug', $bug);?> - -
        - -
        -
        - diff --git a/module/productplan/view/linkstory.html.php b/module/productplan/view/linkstory.html.php deleted file mode 100644 index 5cebc1b4be..0000000000 --- a/module/productplan/view/linkstory.html.php +++ /dev/null @@ -1,92 +0,0 @@ - - * @package productplan - * @version $Id: linkstory.html.php 5096 2013-07-11 07:02:43Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> -
        -
        -
        id&browseType=$browseType¶m=$param&orderBy=$orderBy")?>"> -
        - productplan->unlinkedStories;?> -
        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        - -
        - -
        - - idAB;?> -
        priAB;?>story->plan;?>story->module;?>story->title;?>openedByAB;?>assignedToAB;?>story->estimateAB;?>statusAB;?>story->stageAB;?>
        - id => sprintf('%03d', $story->id)));?> - story->priList, $story->pri)?>planTitle;?>module];?> - parent > 0) echo "story->children}>{$lang->story->childrenAB}"; - echo html::a($this->createLink('story', 'view', "storyID=$story->id", '', true), $story->title, '', "data-toggle='modal' data-type='iframe' data-width='90%'"); - ?> - openedBy);?>assignedTo);?>estimate . $config->hourUnit;?> - - processStatus('story', $story);?> - - story->stageList[$story->stage];?>
        - -
        -
        - diff --git a/module/productplan/view/view.html.php b/module/productplan/view/view.html.php deleted file mode 100644 index 5b7b3620c0..0000000000 --- a/module/productplan/view/view.html.php +++ /dev/null @@ -1,618 +0,0 @@ - - * @package productplan - * @version $Id: view.html.php 5096 2013-07-11 07:02:43Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - - -productplan->confirmUnlinkStory)?> -productplan->confirmUnlinkBug)?> -id);?> -pageID);?> -recPerPage);?> -recTotal);?> - -SRCommon);?> -product->checkedSRSummary);?> - -
        -
        - app->getViewType() == 'xhtml'):?> -
        name . ' ' . $plan->title ?>
        - - -
        -
        '> - -
        - deleted and $plan->parent >= 0 and $canBeChanged):?> -
        - -
        - - parent >= 0) echo html::a("javascript:showLink($plan->id, \"story\")", ' ' . $lang->productplan->linkStory, '', "class='btn btn-primary'");?> -
        - - - - -
        -
        '> - parent >= 0):?> -
        - id, \"bug\")", ' ' . $lang->productplan->linkBug, '', "class='btn btn-primary'");?> -
        - - - -
        -
        '> -
        -
        -
        productplan->basicInfo;?>
        -
        - - - - - - parent > 0):?> - - - - - - type != 'normal'):?> - - - - - - - - - - - - - - - parent == '-1'):?> - - - - - - printExtendFields($plan, 'table', 'inForm=0');?> - - - - - - - - -
        productplan->title;?>title;?>
        productplan->parent;?>id}"), "#{$parentPlan->id} " . $parentPlan->title, '', "data-app={$app->tab}");?>
        product->branch;?>
        productplan->begin;?>begin == $config->productplan->future ? $lang->productplan->future : $plan->begin;?>
        productplan->end;?>end == $config->productplan->future ? $lang->productplan->future : $plan->end;?>
        productplan->children;?> - - id}"), "#{$childrenPlan->id} " . $childrenPlan->title, '', "data-app={$app->tab}") . '
        ';?> - -
        productplan->status;?>productplan->statusList[$plan->status];?>
        productplan->desc;?>desc;?>
        -
        -
        - app->getViewType() != 'xhtml') include '../../common/view/action.html.php';?> -
        -
        -
        -
        -
        - - -id)?> - - -app->getViewType() == 'xhtml'):?> - - - diff --git a/module/program/view/browse.html.php b/module/program/view/browse.html.php deleted file mode 100644 index 51c26999c1..0000000000 --- a/module/program/view/browse.html.php +++ /dev/null @@ -1,65 +0,0 @@ - - * @package ZenTaoPMS - * @version $Id - */ -?> - - - - -edit);?> -selectAll);?> - -program->checkedProjects);?> -app->getClientLang());?> - - - - -
        - -
        -
        -

        - program->noProgram;?> - " . $lang->program->create, '', "class='btn btn-info'");?> -

        -
        - -
        -
        - -
        - -
        - diff --git a/module/program/view/create.html.php b/module/program/view/create.html.php deleted file mode 100644 index c68686908f..0000000000 --- a/module/program/view/create.html.php +++ /dev/null @@ -1,153 +0,0 @@ - - * @package project - * @version $Id: pgmcreate.html.php 4728 2013-05-03 06:14:34Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - createLink('project', 'task', 'projectID=' . $projectID);?> - - - - - - - - - - - -execution->weekend);?> -execution->placeholder);?> -project->errorSameProducts);?> -program->longTime);?> - -project->currencySymbol);?> -program->parentBudget);?> -project->future);?> - -project->budgetOverrun);?> -project->currencySymbol)?> -program->parentBudget);?> -program->beginLessThanParent);?> -program->endGreatThanParent);?> -program->ignore);?> -app->getMethodName());?> -program->subAclList : $lang->program->aclList;?> -program->create->requiredFields;?> -
        -
        -
        -

        id) ? $lang->program->children : $lang->program->create;?>

        -
        -
        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - printExtendFields('', 'table');?> - - - - - - - - - - - - - - - -
        program->parent;?> - id) ? 'disabled' : '';?> - id) ? $parentProgram->id : 0, "class='form-control chosen' onchange=setBudgetTipsAndAclList(this.value) $disabled");?> - id);?> -
        program->name;?>
        program->PM;?>
        program->budget;?> -
        - program->parentBudget . zget($lang->project->currencySymbol, $parentProgram->budgetUnit) . $budgetLeft . '"' : '';?> - - - budgetUnit);?> - - - project->defaultCurrency, "class='form-control'");?> - -
        -
        -
        - - -
        -
        project->dateRange;?> -
        - project->begin . "' required");?> - project->to;?> - project->end . "' required");?> -
        -
        program->endList, '', "onclick='computeEndDate(this.value)'");?>
        project->status;?>
        program->desc;?> - -
        project->acl;?>
        whitelist;?> -
        - - fetch('my', 'buildContactLists', "dropdownName=whitelist");?> -
        -
        - - goback, '', 'class="btn btn-wide"') : html::backButton();?> -
        -
        -
        -
        - - -id) ? $parentProgram->id : 0);?> - diff --git a/module/program/view/edit.html.php b/module/program/view/edit.html.php deleted file mode 100644 index 591810072f..0000000000 --- a/module/program/view/edit.html.php +++ /dev/null @@ -1,169 +0,0 @@ - - * @package program - * @version $Id: create.html.php 4728 2013-05-03 06:14:34Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - -app->getMethodName());?> -execution->weekend);?> -program->longTime);?> -project->currencySymbol);?> -program->parentBudget);?> -program->parentBudget);?> -project->future);?> - - -budgetUnit);?> -error->notempty, $lang->program->exchangeRate));?> -error->float, $lang->program->exchangeRate));?> -program->exRateNotNegative);?> -id);?> -project->budgetOverrun);?> -project->currencySymbol)?> -program->parentBudget);?> -program->beginLessThanParent);?> -program->endGreatThanParent);?> -program->beginGreatEqualChild);?> -program->endLessThanChild);?> -program->ignore);?> -parent ? $lang->program->subAclList : $lang->program->aclList;?> -program->edit->requiredFields;?> -
        -
        -
        -

        program->edit;?>

        -
        -
        - - - - - - - - - - - - - - - - - - - - - - - end == LONG_TIME ? 999 : (strtotime($program->end) - strtotime($program->begin)) / 3600 / 24 + 1;?> - - - - - - - printExtendFields($program, 'table');?> - - - - - - - - - - - - - - - -
        program->parent;?>parent, "class='form-control chosen' onchange=setBudgetTipsAndAclList(this.value)");?>
        program->name;?>name, "class='form-control' required");?>
        program->PM;?>PM, "class='form-control chosen'" . (strpos($requiredFields, 'PM') !== false ? ' required' : ''));?>
        program->budget;?> -
        - budget != 0) ? 'placeholder="' . $lang->program->parentBudget . zget($lang->project->currencySymbol, $parentProgram->budgetUnit) . $availableBudget . '"' : '';?> - budget != 0 ? $program->budget : '', "class='form-control' onchange='budgetOverrunTips()' maxlength='10' " . (strpos($requiredFields, 'budget') !== false ? 'required ' : '') . ($program->budget == 0 ? 'disabled ' : '') . $placeholder);?> - - budgetUnit);?> - - - budgetUnit, "class='form-control'");?> - - - -
        -
        -
        - budget == 0) echo 'checked';?> /> - -
        -
        project->dateRange;?> -
        - begin, "class='form-control form-date' onchange='outOfDateTip();' placeholder='" . $lang->project->begin . "' required");?> - project->to;?> - end == LONG_TIME ? $lang->program->longTime : $program->end; - echo html::input('end', $end, "class='form-control form-date' onchange='outOfDateTip();' placeholder='" . $lang->project->end . "' required"); - ?> -
        -
        program->endList , $endValue, "onclick='computeEndDate(this.value)'");?>
        project->realBegan;?>realBegan) ? '' : $program->realBegan, "class='form-control form-date'");?>
        program->desc;?> - desc, "rows='6' class='form-control kindeditor' hidefocus='true'" . (strpos($requiredFields, 'desc') !== false ? ' required' : ''));?> -
        project->acl;?>acl, "onclick='setWhite(this.value);'", 'block'));?>
        whitelist;?> -
        - whitelist, 'class="form-control picker-select" multiple data-dropDirection="top"');?> - fetch('my', 'buildContactLists', "dropdownName=whitelist");?> -
        -
        - - -
        -
        -
        -
        - - - - - diff --git a/module/program/view/export.html.php b/module/program/view/export.html.php deleted file mode 100644 index 677cb08843..0000000000 --- a/module/program/view/export.html.php +++ /dev/null @@ -1,13 +0,0 @@ - - * @package project - * @version $Id$ - * @link https://www.zentao.net - */ -?> - diff --git a/module/program/view/kanban.html.php b/module/program/view/kanban.html.php deleted file mode 100644 index 5b06d737a4..0000000000 --- a/module/program/view/kanban.html.php +++ /dev/null @@ -1,58 +0,0 @@ - - * @package ZenTaoPMS - * @version $Id - */ -?> - - -
        -
        - program->showAllProjects ? 'checked' : '';?>> - -
        -
        -
        - -
        -

        program->noProgram;?>

        -
        - - $programs):?> - -
        -
        - program->kanban->typeList[$type];?> -
        -
        -
        -
        -
        - - $lang->program->kanban->openProducts, 'type' => 'unclosedProduct'); - $kanbanColumns['unexpiredPlan'] = array('name' => $lang->program->kanban->unexpiredPlans, 'type' => 'unexpiredPlan'); - $kanbanColumns['waitProject'] = array('name' => $lang->program->kanban->waitingProjects, 'type' => 'waitProject'); - $kanbanColumns['doingProject'] = array('name' => $lang->program->kanban->doingProjects, 'type' => 'doingProject'); - $kanbanColumns['doingExecution'] = array('name' => $lang->program->kanban->doingExecutions, 'type' => 'doingExecution'); - $kanbanColumns['normalRelease'] = array('name' => $lang->program->kanban->normalReleases, 'type' => 'normalRelease'); - $userPrivs = array(); - $userPrivs['product'] = common::hasPriv('product', 'browse'); - $userPrivs['productplan'] = common::hasPriv('productplan', 'view'); - $userPrivs['project'] = common::hasPriv('project', 'index'); - $userPrivs['execution'] = common::hasPriv('execution', 'task'); - $userPrivs['release'] = common::hasPriv('release', 'view'); - js::set('kanbanColumns', array_values($kanbanColumns)); - js::set('userPrivs', $userPrivs); - js::set('kanbanGroup', $kanbanGroup); - js::set('doingText', $lang->program->statusList['doing']); - ?> - -
        - diff --git a/module/program/view/product.html.php b/module/program/view/product.html.php deleted file mode 100644 index aa0f298f00..0000000000 --- a/module/program/view/product.html.php +++ /dev/null @@ -1,148 +0,0 @@ - - * @package ZenTaoPMS - * @version $Id - */ -?> - - -product->checkedProducts);?> -app->getClientLang());?> - - -
        - -
        -

        product->noProduct;?>

        -
        - -
        -
        '> - - - recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?> - - - - - - - - - - - - - - - - - - - - - - - - stories['finishClosed'] + $product->stories['unclosed'];?> - - - - - - - - - - - - - - - - - -
        - -
        - -
        - - idAB);?> -
        product->name);?>product->manager);?>story->story;?>bug->common;?>product->plan;?>product->release;?>actions;?>
        story->draft;?>story->activate;?>story->change;?>story->statusList['reviewing'];?>story->completeRate;?>bug->activate;?>bug->fixedRate;?>
        - - id => sprintf('%03d', $product->id)), '', 'class="id-checkbox ' . (!$showBatchEdit ? 'hidden"' : '"'));?> - - id);?> - createLink('product', 'browse', 'product=' . $product->id), $product->name);?> - PO)) - { - $userName = zget($users, $product->PO); - echo html::smallAvatar(array('avatar' => $usersAvatar[$product->PO], 'account' => $product->PO, 'name' => $userName), 'avatar-circle avatar-' . zget($userIdPairs, $product->PO)); - - $userID = isset($userIdPairs[$product->PO]) ? $userIdPairs[$product->PO] : ''; - echo html::a($this->createLink('user', 'profile', "userID=$userID", '', true), $userName, '', "title='{$userName}' data-toggle='modal' data-type='iframe' data-width='600'"); - } - ?> - stories['draft'];?>stories['active'];?>stories['changing'];?>stories['reviewing'];?>stories['finishClosed'] / $totalStories, 3) * 100;?>%unResolved;?>unResolved + $product->fixedBugs) == 0 ? 0 : round($product->fixedBugs / ($product->unResolved + $product->fixedBugs), 3) * 100;?>%plans;?>releases;?> - id&action=edit&extra=&programID=$programID", $product, 'list', 'edit');?> - - - -
        - - - -
        -
        - -
        - - - - diff --git a/module/program/view/project.html.php b/module/program/view/project.html.php deleted file mode 100644 index cfada3300c..0000000000 --- a/module/program/view/project.html.php +++ /dev/null @@ -1,115 +0,0 @@ - - * @package program - * @version $Id: pgmproject.html.php 4769 2013-05-05 07:24:21Z wwccss $ - * @link https://www.zentao.net - */ -?> - - - -
        -
        - -
        -

        - project->empty;?> - ' . $lang->project->create, '', 'class="btn btn-info btn-wide " data-toggle="modal"');?> -

        -
        - -
        - recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}"; - $setting = $this->datatable->getSetting('program'); - ?> - - - - id == 'projectStatus' and $browseType !== 'all') $value->show = false; - if($value->id == 'status' and strpos('all,unclosed', $browseType) === false) $value->show = false; - if($value->show) $this->datatable->printHead($value, $orderBy, $vars, $canBatchEdit); - } - ?> - - - - - - from = 'pgmproject';?> - status == 'wait') $waitCount ++;?> - status == 'doing') $doingCount ++;?> - status == 'suspended') $suspendedCount ++;?> - status == 'closed') $closedCount ++;?> - project->printCell($value, $project, $users, $programID);?> - - - -
        - -
        - -
        -
        -project->summary, count($projectStats))); -js::set('allSummary', sprintf($lang->project->allSummary, count($projectStats), $waitCount, $doingCount, $suspendedCount, $closedCount)); -js::set('checkedSummary', $lang->project->checkedSummary); -js::set('checkedAllSummary', $lang->project->checkedAllSummary); -?> - - diff --git a/module/program/view/stakeholder.html.php b/module/program/view/stakeholder.html.php deleted file mode 100644 index 3b331ad5e8..0000000000 --- a/module/program/view/stakeholder.html.php +++ /dev/null @@ -1,88 +0,0 @@ - - * @package product - * @version $Id: browse.html.php 5096 2013-07-11 07:02:43Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - -project->confirmDelete);?> - - -
        -
        - -
        - - - - - - - - - - - - - - - - - - - key ? " " : '';?> - key ? $lang->program->isStakeholderKey : '';?> - - - - - - - - - - - -
        -
        - idAB;?> -
        user->realname;?>program->stakeholderType;?>user->role;?>user->phone;?>user->qq;?>user->weixin;?>user->email;?>actions;?>
        - id => ''));?> - id);?> - realname . $isKey;?>'>stakeholder->fromList, $stakeholder->from, '');?>user->roleList, $stakeholder->role, '');?>phone;?>qq;?>weixin;?>email;?> - createLink('program', 'unlinkStakeholder', "id=$stakeholder->id&programID=$programID&confirm=no"), '', 'hiddenwin', "title='{$lang->program->unlinkStakeholder}' class='{$deleteClass}'"); - ?> -
        - - - -
        - -
        noData;?>
        - -
        -
        - diff --git a/module/programplan/ui/create.html.php b/module/programplan/ui/create.html.php index c8077dfc66..432d47ec5f 100644 --- a/module/programplan/ui/create.html.php +++ b/module/programplan/ui/create.html.php @@ -131,20 +131,6 @@ $fnGenerateFields = function() use ($lang, $requiredFields, $showFields, $fields $field['value'] = empty($programPlan) ? 'open' : $programPlan->acl; } - if(!empty($project->isTpl)) - { - if($name == 'begin') - { - $field['value'] = $project->begin; - $field['hidden'] = true; - } - if($name == 'end') - { - $field['value'] = $project->end; - $field['hidden'] = true; - } - } - /* Field for agileplus. */ if($name == 'type' && in_array($project->model, array('waterfallplus', 'ipd'))) { diff --git a/module/programplan/view/browse.html.php b/module/programplan/view/browse.html.php deleted file mode 100644 index bba127e09a..0000000000 --- a/module/programplan/view/browse.html.php +++ /dev/null @@ -1,39 +0,0 @@ - - * @package programplan - * @version $Id: browse.html.php 4903 2013-06-26 05:32:59Z wyd621@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - -
        - -
        -

        - programplan->noData;?> - - createLink('programplan', 'create', "projectID=$projectID&productID=$productID"), " " . $lang->programplan->create, '', "class='btn btn-info'");?> - -

        -
        - - - - -
        - - diff --git a/module/programplan/view/create.html.php b/module/programplan/view/create.html.php deleted file mode 100644 index f1d15b8371..0000000000 --- a/module/programplan/view/create.html.php +++ /dev/null @@ -1,284 +0,0 @@ - - * @package programplan - * @version $Id: create.html.php 4903 2013-06-26 05:32:59Z wyd621@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - - - -
        -
        - model == 'waterfallplus'):?> -
        -
        programplan->subPlanManage . ':'?>
        -
        - programplan->typeList) > 1) - { - foreach($lang->programplan->typeList as $key => $value) - { - $label = ""; - echo html::a($this->createLink('programplan', 'create', "projectID=$project->id&productID=$productID&planID=$planID&type=$key"), $label); - } - } - else - { - echo zget($lang->programplan->typeList, $executionType); - } - ?> -
        -
        -
        - -
        - createLink('custom', 'ajaxSaveCustomFields', "module=programplan§ion={$custom}&key=createFields")?> - -
        -
        - - - - - programplan->name : $lang->programplan->subStageName;?> -
        -
        - - - - - - setCode) and $config->setCode == 1):?> - - - - - - - - - - - - - config->edition == 'max' or $this->config->edition == 'ipd') and $executionType == 'stage'):?> - - - - - - - - - - - - setCode) and $config->setCode == 1):?> - - - - - - - - - - - - config->edition == 'max' or $this->config->edition == 'ipd') and $executionType == 'stage'):?> - - - - - - - - - - setMilestone) ? '' : "disabled='disabled'"?> - id);?> - - - - setCode) and $config->setCode == 1):?> - - - - - - - - - - - - - config->edition == 'max' or $this->config->edition == 'ipd') and $executionType == 'stage'):?> - output) ? 0 : explode(',', $plan->output);?> - - - - - - - - - - - - setCode) and $config->setCode == 1):?> - - - - - - - - - - - - - config->edition == 'max' or $this->config->edition == 'ipd') and $executionType == 'stage'):?> - - - - - - - - - - - - - -
        execution->method;?>nameAB;?>execution->code : $lang->code;?>'>programplan->PM : $lang->programplan->PMAB;?>'> - programplan->percent;?> - - - - '>programplan->attribute;?>'>programplan->acl;?>'>programplan->milestone;?>programplan->begin;?>programplan->end;?>'>programplan->realBegan;?>'>programplan->realEnd;?>'>programplan->desc;?>programplan->output;?> actions;?>
        code) ? $stage->code : '', "class='form-control'");?>>> -
        - - % -
        -
        '>model == 'ipd' ? $lang->stage->ipdTypeList : $lang->stage->typeList, $stage->type, "class='form-control'") : zget($lang->stage->typeList, $programPlan->attribute);?>'>execution->aclList, 'open', "class='form-control' $class");?>>programplan->milestoneList, 0);?>>> - - - -
        execution->typeList, $plan->type);?>'>execution->typeList, $plan->type);?>code, "class='form-control'");?>>PM, "class='form-control picker-select'");?>> -
        - - % -
        -
        '>model == 'ipd' ? $lang->stage->ipdTypeList : $lang->stage->typeList, $plan->attribute, "class='form-control'") : zget($lang->stage->typeList, $programPlan->attribute);?>>execution->aclList, $plan->acl, "class='form-control' $class");?>>programplan->milestoneList, $plan->milestone, $disabled);?>>>'>desc, "rows='1' class='form-control autosize'");?> - - - - order);?> -
        execution->typeList, '', "class='form-control chosen'");?>>> -
        - - % -
        -
        '>model == 'ipd' ? $lang->stage->ipdTypeList : $lang->stage->typeList, '', "class='form-control'") : zget($lang->stage->typeList, $programPlan->attribute);?>>execution->aclList, empty($programPlan) ? 'open' : $programPlan->acl, "class='form-control' $class");?>>programplan->milestoneList, 0);?>>>'> - - - -
        -
        - -
        -
        -
        - - - - - - setCode) and $config->setCode == 1):?> - - - - - - - - - - - - - - config->edition == 'max' or $this->config->edition == 'ipd') and $executionType == 'stage'):?> - - - - - -
        -programplan->emptyBegin); -js::set('emptyEnd', $lang->programplan->emptyEnd); -js::set('planFinishSmall', $lang->programplan->error->planFinishSmall); -js::set('errorBegin', $lang->programplan->errorBegin); -js::set('errorEnd', $lang->programplan->errorEnd); -js::set('projectBeginDate', $project->begin); -js::set('projectEndDate', $project->end); -?> - - diff --git a/module/programplan/view/edit.html.php b/module/programplan/view/edit.html.php deleted file mode 100644 index a90556f1a4..0000000000 --- a/module/programplan/view/edit.html.php +++ /dev/null @@ -1,118 +0,0 @@ - - * @package programplan - * @version $Id: edit.html.php 4903 2013-06-26 05:32:59Z wyd621@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - -stage->typeList);?> -programplan->confirmChangeAttr);?> - - -
        -
        -
        -

        - id;?> - name}>{$plan->name}";?> -

        -
        -
        - - - - - - - - - - - setCode) and $config->setCode == 1):?> - - - - - - - - - - setPercent) and $config->setPercent == 1):?> - - - - - - - - - - - setMilestone):?> - - - - - - milestone);?> - - - - grade == 2 ? "disabled='disabled'" : '';?> - - - - - - - - - - - config->qcVersion)):?> - - - - - - - - - -
        programplan->parent;?>parent, "class='form-control chosen '");?>
        programplan->name;?> name, "class='form-control'");?>
        execution->code;?> code, "class='form-control'");?>
        programplan->PM;?> PM, "class='form-control picker-select'");?>
        programplan->percent;?> -
        - percent, "class='form-control'");?> -
        % -
        -
        programplan->attribute;?> - model == 'ipd' ? $lang->stage->ipdTypeList : $lang->stage->typeList, $plan->attribute, "class='form-control'") : zget($lang->stage->typeList, $plan->attribute);?> - - model != 'ipd'):?> - - -
        programplan->milestone;?> programplan->milestoneList, $plan->milestone);?>
        project->acl;?> execution->aclList, $plan->acl, "class='form-control' $class");?>
        programplan->planDateRange;?> -
        - begin, "class='form-control form-date'");?> - project->to;?> - end, "class='form-control form-date'");?> -
        -
        programplan->realDateRange;?> -
        - realBegan, "class='form-control form-date'");?> - project->to;?> - realEnd, "class='form-control form-date'");?> -
        -
        programplan->output;?> output, "class='form-control chosen ' multiple");?>
        -
        -
        -
        - diff --git a/module/programplan/view/gantt.html.php b/module/programplan/view/gantt.html.php deleted file mode 100755 index 4dc2f50d36..0000000000 --- a/module/programplan/view/gantt.html.php +++ /dev/null @@ -1,989 +0,0 @@ - - * @package programplan - * @version $Id: gantt.html.php 4903 2013-06-26 05:32:59Z wyd621@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -model == 'ipd') js::set('reviewPoints', json_encode($reviewPoints));?> - - -createLink('programplan', 'ajaxCustom'));?> - -rawModule);?> -rawMethod);?> - -config->programplan->ganttCustom->ganttFields);?> - - - -
        - app->getModuleName() == 'programplan'):?> -
        -
        - stageBy == 'product'):?> - product->allProduct;?> - - - - {$lang->programplan->gantt}";?> - -
        -
        -
        -
        -  ", '', "class='btn btn-icon text-primary switchBtn' title='{$lang->programplan->gantt}'");?> - createLink('project', 'execution', "status=all&projectID=$projectID"),"  ", '', "class='btn btn-icon switchBtn' title='{$lang->project->bylist}'");?> -
        - programplan->full;?> - - ' . $lang->settings, '', "class='iframe btn btn-link' data-width='45%'"); - if(common::hasPriv('programplan', 'create') and empty($product->deleted)) echo html::a($this->createLink('programplan', 'create', "projectID=$projectID"), " " . $this->lang->programplan->create, '', "class='btn btn-primary'"); - ?> -
        - -
        -
        -
        - - - '; - $typeHtml .= ''; - $typeHtml .= '
        '; - ?> -
        -
        -
        - -
        -
        -
        - diff --git a/module/project/config.php b/module/project/config.php index 3703a8d5ae..c12124c5f8 100755 --- a/module/project/config.php +++ b/module/project/config.php @@ -233,7 +233,7 @@ $config->project->linkMap->projectstory['linkstory'] = array('', '', 'projectID= $config->project->linkMap->projectstory['track'] = array('projectstory', 'story', 'projectID=%s', ''); $config->project->linkMap->bug = array(); -$config->project->linkMap->bug['create'] = array('', '', 'productID=0&branch=0&extras=projectID=%s', ''); +$config->project->linkMap->bug['create'] = array('project', 'bug', 'projectID=%s', ''); $config->project->linkMap->bug['edit'] = array('project', 'bug', 'projectID=%s', ''); $config->project->linkMap->story = array(); diff --git a/module/project/control.php b/module/project/control.php index ac5cf9b1da..8f57f04ba4 100755 --- a/module/project/control.php +++ b/module/project/control.php @@ -651,9 +651,10 @@ class project extends control return $this->send(array('result' => 'success', 'load' => array('alert' => $this->lang->notFound, 'locate' => $this->createLink('project', 'browse')))); } - $products = $this->loadModel('product')->getProducts($projectID); - $projectBranches = $this->project->getBranchesByProject($projectID); - $linkedBranches = array(); + $projectBranches = $this->project->getBranchesByProject($projectID); + $linkedProductIdList = empty($projectBranches) ? '' : array_keys($projectBranches); + $products = $this->loadModel('product')->getProducts($projectID, 'all', '', true, $linkedProductIdList, false); + $linkedBranches = array(); foreach($products as $product) { $product->roadmaps = ''; diff --git a/module/project/test/lib/createwaterfall.ui.class.php b/module/project/test/lib/createwaterfall.ui.class.php index ba462739d4..b171a72174 100755 --- a/module/project/test/lib/createwaterfall.ui.class.php +++ b/module/project/test/lib/createwaterfall.ui.class.php @@ -40,7 +40,7 @@ class createWaterfallTester extends tester if(isset($waterfall['PM'])) $form->dom->PM->picker($waterfall['PM']); $form->wait(1); $form->dom->btn($this->lang->save)->click(); - $form->wait(1); + $form->wait(5); if($this->response('module') != 'programplan') { diff --git a/module/project/test/lib/executionforlite.ui.class.php b/module/project/test/lib/executionforlite.ui.class.php index 9c3e62625a..ef685dde9d 100644 --- a/module/project/test/lib/executionforlite.ui.class.php +++ b/module/project/test/lib/executionforlite.ui.class.php @@ -13,6 +13,7 @@ class executionForLiteTester extends tester public function checkTab($sort, $tab, $expectNum) { $this->switchVision('lite'); + $this->page->wait(5)->refresh(); $form = $this->initForm('project', 'execution', '', 'appIframe-project'); $status = [ 'all' => '全部', @@ -29,6 +30,7 @@ class executionForLiteTester extends tester /*添加断言,判断标签下条数是否符合预期*/ $num = $form->dom->getElement("//*[@id='featureBar']/menu/li[$sort]/a/span[2]")->element->getText(); + $form->wait(2); if($num == $expectNum) return $this->success($status[$tab] . '标签下条数显示正确'); return $this->failed($status[$tab] . '标签下条数显示不正确'); } diff --git a/module/project/test/lib/projectzen.unittest.class.php b/module/project/test/lib/projectzen.unittest.class.php index ae96cbe3da..957c5e22a2 100644 --- a/module/project/test/lib/projectzen.unittest.class.php +++ b/module/project/test/lib/projectzen.unittest.class.php @@ -111,4 +111,17 @@ class projectZenTest return callZenMethod('project', 'buildEditForm', [$projectID, $project], 'view'); } + + /** + * 处理项目列表展示数据。 + * Process project list display data. + * + * @access public + * @return array + */ + public function processProjectListDataTest(): array + { + $projectList = $this->objectModel->dao->select('*')->from(TABLE_PROJECT)->where('type')->eq('project')->fetchAll('id'); + return callZenMethod('project', 'processProjectListData', [$projectList]); + } } diff --git a/module/project/test/lib/suspendprojectforlite.ui.class.php b/module/project/test/lib/suspendprojectforlite.ui.class.php index fb1d918ff1..139127216b 100644 --- a/module/project/test/lib/suspendprojectforlite.ui.class.php +++ b/module/project/test/lib/suspendprojectforlite.ui.class.php @@ -12,6 +12,7 @@ class suspendProjectForLiteTester extends tester public function suspendProject() { $this->switchVision('lite'); + $this->page->wait(5)->refresh(); $form = $this->initForm('project', 'browse', '', 'appIframe-project'); $featureBar = (array)$this->lang->project->featureBar; $featureBar['browse'] = (array)$featureBar['browse']; @@ -28,7 +29,7 @@ class suspendProjectForLiteTester extends tester $form = $this->initForm('project', 'browse', '', 'appIframe-project'); $browsePage = $this->loadPage('project', 'browse'); $form->dom->search(array("项目名称,=,{$title}")); - $form->wait(3); + $form->wait(5); //搜索的项目状态为挂起,说明挂起成功 $featureBar['index'] = (array)$featureBar['index']; if($form->dom->browseStatus->getText() != $featureBar['index']['suspended']) return $this->fail('挂起运营项目失败'); diff --git a/module/project/test/zen/processprojectlistdata.php b/module/project/test/zen/processprojectlistdata.php new file mode 100644 index 0000000000..8825545310 --- /dev/null +++ b/module/project/test/zen/processprojectlistdata.php @@ -0,0 +1,32 @@ +#!/usr/bin/env php +loadYaml('project')->gen(5); +zenData('product')->loadYaml('product')->gen(5); +zenData('projectproduct')->loadYaml('projectproduct')->gen(10); +zenData('task')->loadYaml('task')->gen(10); +zenData('effort')->loadYaml('effort')->gen(10); +zenData('branch')->gen(0); +zenData('story')->gen(0); +zenData('user')->gen(5); +su('admin'); + +$projectTester = new projectZenTest(); +$result = $projectTester->processProjectListDataTest(); +r($result) && p('1:name,budget,storyPoints,estimate,consume,left') && e('瀑布项目2,$ 79.99万,0 h,0,0,0'); // 获取处理后的项目数据 diff --git a/module/project/view/activate.html.php b/module/project/view/activate.html.php deleted file mode 100644 index c082f743c4..0000000000 --- a/module/project/view/activate.html.php +++ /dev/null @@ -1,80 +0,0 @@ - - * @package project - * @version $Id: suspend.html.php 935 2013-01-16 07:49:24Z wwccss@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - - -
        -
        -

        - id;?> - name'>" . $project->name . '') : html::a($this->createLink('project', 'view', 'project=' . $project->id), $project->name, '_blank');?> - - arrow . $lang->{$project->type}->activate;?> - -

        -
        -
        - - - - - - - - - - - printExtendFields($project, 'table', 'columns=5');?> - - - - - - - -
        execution->beginAndEnd;?> -
        begin . ' ~ ' . $project->end;?>
        -
        -
        - - ~ - -
        -
        -
        -
        -
        -
        -
        -
        - -
        -
        -
        project->status;?>
        comment;?>
        {$project->type}->activate) . html::linkButton($lang->goback, $this->session->taskList, 'self', '', 'btn btn-wide'); ?>
        -
        -
        -
        -
        - - diff --git a/module/project/view/batchedit.html.php b/module/project/view/batchedit.html.php deleted file mode 100644 index 590539b7c0..0000000000 --- a/module/project/view/batchedit.html.php +++ /dev/null @@ -1,112 +0,0 @@ - - * @package project - * @version $Id: prjbatchedit.html.php 4769 2021-02-020 11:13:21Z $ - * @link https://www.zentao.net - */ -?> - -execution->weekend);?> -project->linkedProjectsTip);?> -project->changeProgram);?> -project->beginLessThanParent);?> -project->endGreatThanParent);?> - -systemMode);?> -project->longTime);?> -project->ignore);?> -project->edit->requiredFields;?> -
        -
        -

        project->batchEdit;?>

        -
        -
        - - - - - - - - - setCode) and $config->setCode == 1):?> - - - - - - - project->getFlowExtendFields(); - foreach($extendFields as $extendField) echo ""; - ?> - - - - $project):?> - parent) ? $lang->program->subAcls : $lang->project->acls;?> - - - - parent])):?> - - - - - - - setCode) and $config->setCode == 1):?> - - - - - - - control == 'select' or $extendField->control == 'multi-select') ? " style='overflow:visible'" : '') . ">" . $this->loadModel('flow')->getFieldControl($extendField, $project, $extendField->field . "[{$projectID}]") . "";?> - - - -
        idAB;?>project->parent;?>project->name;?>project->code;?> project->PM;?>project->begin;?>project->end;?>project->acl;?>{$extendField->name}
        - parent, "class='form-control chosen' onchange='outOfDateTip($projectID)' data-id='$projectID' data-name='{$project->name}' data-parent='{$project->parent}' disabled");?> - parent);?> - parent, "class='form-control chosen' onchange='outOfDateTip($projectID)' data-id='$projectID' data-name='{$project->name}' data-parent='{$project->parent}'");?>name, "class='form-control'");?>code, "class='form-control'");?>PM, "class='form-control chosen'");?> - begin, "class='form-control form-date' onchange='computeWorkDays(this.id);' placeholder='" . $lang->project->begin . "'");?> - - end == LONG_TIME ? 'disabled' : ''; - $end = $project->end == LONG_TIME ? $lang->project->longTime : $project->end; - echo html::input("ends[$projectID]", $end, "class='form-control form-date' onchange='computeWorkDays(this.id);' placeholder='" . $lang->project->end . "'"); - echo html::hidden("dayses[$projectID]", $project->days); - ?> - acl, "class='form-control'");?>
        - -
        - - diff --git a/module/project/view/browse.html.php b/module/project/view/browse.html.php deleted file mode 100644 index af44ca5cdb..0000000000 --- a/module/project/view/browse.html.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @package project - * @version $Id: prjbrowse.html.php 4769 2013-05-05 07:24:21Z wwccss $ - * @link https://www.zentao.net - */ -?> - - - - - diff --git a/module/project/view/browsebycard.html.php b/module/project/view/browsebycard.html.php deleted file mode 100644 index b5aa3804e0..0000000000 --- a/module/project/view/browsebycard.html.php +++ /dev/null @@ -1,210 +0,0 @@ - - * @package project - * @version $Id: browsebycard.html.php 4769 2021-07-23 11:29:21Z $ - * @link https://www.zentao.net - */ -?> - - -
        -
        -
        - -
        -

        - project->empty;?> - - ' . $lang->project->create, '', 'class="btn btn-info" data-toggle="modal"');?> - - ' . $lang->execution->create, '', 'class="btn btn-info"');?> - -

        -
        - - $project):?> -
        -
        -
        - delay) ? 'delay' : $project->status;?> - project->statusList[$status];?> -
        -
        - model, array('waterfall', 'waterfallplus'))):?> - - model === 'kanban'):?> - - model === 'agileplus'):?> - - - - - name);?> -
        -
        -
        - getClientLang(), array('zh-cn','zh-tw')) ? round((float)$project->budget / 10000, 2) . $lang->project->tenThousand : round((float)$project->budget, 2); - $budgetTitle = $project->budget != 0 ? zget($lang->project->currencySymbol, $project->budgetUnit) . ' ' . $projectBudget : $lang->project->budget . $lang->project->future; - $project->end = $project->end == LONG_TIME ? $this->lang->project->longTime : $project->end; - $project->date = str_replace('-', '.', $project->begin) . ' - ' . str_replace('-', '.', $project->end); - $canActions = (common::hasPriv('project','edit') or common::hasPriv('project','start') or common::hasPriv('project','activate') or common::hasPriv('project','suspend') or common::hasPriv('project','close')); - ?> - - date;?> -
        -
        -
        -
        -
        project->progress;?>
        - hours->progress); ?> -
        -
        - project->leftTasks;?> - leftTasks;?> -
        -
        - project->leftHours;?> - hours->totalLeft) ? '—' : $project->hours->totalLeft . $lang->execution->workHourUnit;?> -
        -
        -
        - -
        -
        -
        - -
        - show('right', 'pagerjs');?> -
        - -
        -
        diff --git a/module/project/view/bug.html.php b/module/project/view/bug.html.php deleted file mode 100644 index d5136504b2..0000000000 --- a/module/project/view/bug.html.php +++ /dev/null @@ -1,189 +0,0 @@ - - * @package project - * @version $Id: bug.html.php 4894 2013-06-25 01:28:39Z wyd621@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - - -
        - -
        -
        - -
        -

        - bug->notice->noBug;?> - - createLink('bug', 'create', "productID=$productID&branch=$branchID&extra=projectID=$project->id"), " " . $lang->bug->create, '', "class='btn btn-info' data-app='project'");?> - -

        -
        - - moduleName . ucfirst($this->methodName); - $useDatatable = (isset($config->datatable->$datatableId->mode) and $config->datatable->$datatableId->mode == 'datatable'); - ?> - > -
        - -
        - id}&productID=$productID&branch=$branchID&orderBy=%s&build=$buildID&type=$type¶m=$param&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}"; - if($useDatatable) include '../../common/view/datatable.html.php'; - else include '../../common/view/tablesorter.html.php'; - - $setting = $this->datatable->getSetting('project'); - $widths = $this->datatable->setFixedFieldWidth($setting); - $columns = 0; - - $canBatchAssignTo = common::hasPriv('bug', 'batchAssignTo'); - ?> - ';?> - ' id='bugList' data-fixed-left-width='' data-fixed-right-width=''> - - - $value) - { - if(!$project->hasProduct and $project->model != 'scrum' and $value->id == 'plan') continue; - if(!$project->hasProduct and $value->id == 'branch') continue; - - if($value->show) - { - $this->datatable->printHead($value, $orderBy, $vars, $canBatchAssignTo); - $columns ++; - } - } - ?> - - - - - - - hasProduct and $project->model != 'scrum' and $value->id == 'plan') continue; - if(!$project->hasProduct and $value->id == 'branch') continue; - $this->bug->printCell($value, $bug, $users, $builds, $branchOption, $modulePairs, $executions, $plans, $stories, $tasks, $useDatatable ? 'datatable' : 'table', $projectPairs); - } - ?> - - - -
        - ';?> - -
        - - - - - diff --git a/module/project/view/build.html.php b/module/project/view/build.html.php deleted file mode 100644 index d2dedc18e4..0000000000 --- a/module/project/view/build.html.php +++ /dev/null @@ -1,147 +0,0 @@ - - * @package project - * @version $Id: build.html.php 4262 2013-01-24 08:48:56Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -project->noDevStage)?> -project->createExecution)?> -build->confirmDelete)?> - - - -
        -
        - -
        -

        build->noBuild;?>

        -
        - -
        - - - - - - hasProduct):?> - - - - - - multiple):?> - - - - - - - - - - $builds):?> - $build):?> - - - - hasProduct):?> - - - - - - multiple):?> - execution):?> - - - - - - - - - - - - - -
        build->id;?>build->name;?>build->product;?>build->branch;?>executionCommon;?>build->url;?>build->date;?>build->builder;?>actions;?>
        id"), sprintf('%03d', $build->id), '', "data-app='project'");?> - - createLink($fromModule, 'view', "buildID=$build->id"), $build->name, '', "data-app='project' class='buildName'");?> - execution):?> - - - - productName;?>branchName;?> - - executionName;?> - executionDeleted) $executionName = "$executionName";?> - - executionDeleted):?> - build->deleted;?> - - - - - builds as $childBuild):?> - execution] = $childBuild->execution;?> - - - - - -
        - - -
        - scmPath) - { - $colorStyle = strpos($build->scmPath, 'http') === 0 ? "style='color:#2463c7;'" : ''; - echo "
        "; - echo ""; - echo $colorStyle ? html::a($build->scmPath, $build->scmPath, '_blank', $colorStyle) : $build->scmPath; - echo '
        '; - } - if($build->filePath) - { - $colorStyle = strpos($build->filePath, 'http') === 0 ? "style='color:#2463c7;'" : ''; - echo "
        "; - echo ""; - echo $colorStyle ? html::a($build->filePath, $build->filePath, '_blank', $colorStyle) : $build->filePath; - echo '
        '; - } - ?> -
        date?>builder);?>build->buildOperateMenu($build, 'browse');?>
        -
        - -
        - diff --git a/module/project/view/close.html.php b/module/project/view/close.html.php deleted file mode 100644 index 7a6b0b0a2a..0000000000 --- a/module/project/view/close.html.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @package project - * @version $Id: suspend.html.php 935 2013-01-16 07:49:24Z wwccss@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -
        -
        -

        - id;?> - name'>" . $project->name . '') : html::a($this->createLink('project', 'view', 'project=' . $project->id), $project->name, '_blank');?> - - arrow . $lang->{$project->type}->close;?> - -

        -
        -
        - - - - - - - printExtendFields($project, 'table');?> - - - - - - - - - - - - -
        project->status;?>
        project->realEnd;?> -
        - realEnd) ? $project->realEnd : date('Y-m-d')), "class='form-control form-date' required");?> -
        -
        comment;?>
        {$project->type}->close) . html::linkButton($lang->goback, $this->session->projectList, 'self', '', 'btn btn-wide'); ?>
        -
        -
        -
        -
        - diff --git a/module/project/view/create.html.php b/module/project/view/create.html.php deleted file mode 100755 index 093a95280d..0000000000 --- a/module/project/view/create.html.php +++ /dev/null @@ -1,317 +0,0 @@ - - * @package project - * @version $Id: create.html.php 4769 2013-05-05 07:24:21Z wwccss $ - * @link https://www.zentao.net - */ -?> - - - - -systemMode);?> - - - -execution->weekend);?> -project->errorSameProducts);?> -project->errorSameBranches);?> -project->errorSamePlans);?> -project->longTime);?> - - - -product->name);?> -project->manageProductPlan);?> -project->budgetOverrun);?> -project->currencySymbol)?> -project->parentBudget);?> -project->beginLessThanParent);?> -project->endGreatThanParent);?> -project->ignore);?> -project->create->requiredFields;?> - - -project->copyProject->nameTips);?> -project->copyProject->codeTips);?> -project->copyProject->endTips);?> -project->copyProject->daysTips);?> -
        -
        -
        - project->create . ' - ' . zget($lang->project->modelList, $model, '');?> -

        - -
        - edition != 'max' or $model == 'kanban'):?> - - - - -
        - -
        -
        - - '> - - app->tab == 'product' and $productID) ? 'disabled' : '';?> - - - - - - - - - - - setCode) and $config->setCode == 1):?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - printExtendFields(isset($project) ? $project : '', 'table', 'columns=3');?> - - - - - - - - - - - - - - - -
        project->parent;?> - -
        project->name;?>name : '', "class='form-control' required");?>
        project->code;?>code : '', "class='form-control' required");?>
        project->multiple;?> - project->multipleList, '1', $copyProjectID ? 'disabled' : '')); - if($copyProjectID) echo html::hidden('multiple', $copyProject->multiple); - ?> -
        project->type;?> - project->projectTypeList, '1', $copyProjectID ? 'disabled' : ''); - if($copyProjectID) echo html::hidden('hasProduct', $copyProject->hasProduct); - ?> -
        project->PM;?>
        project->budget;?> -
        - budget != 0) ? 'placeholder="' . $lang->program->parentBudget . zget($lang->project->currencySymbol, $parentProgram->budgetUnit) . $availableBudget . '"' : '';?> - - - budgetUnit);?> - - - project->defaultCurrency, "class='form-control'");?> - -
        -
        -
        - - -
        -
        project->dateRange;?> -
        - project->begin . "' required");?> - project->to;?> - project->end . "' required");?> -
        -
        project->endList, '', "onclick='computeEndDate(this.value)'");?>
        execution->days;?> -
        - - execution->day;?> -
        -
        project->manageProductPlan;?> -
        -
        -
        -
        - type != 'normal' and isset($branchGroups[$product->id]);?> -
        '> - productCommon;?> - id, "class='form-control chosen' onchange='loadBranches(this)' data-last='" . $product->id . "' data-type='" . $product->type . "'");?> -
        -
        -
        '> -
        - project->branch;?> - branches);?> - id]) ? $branchGroups[$product->id] : array(), $branchIdList, "class='form-control chosen' multiple onchange=\"loadPlans('#products{$i}', this)\"");?> -
        -
        -
        -
        -
        -
        > - product->plan;?> - id][]", isset($copyProject->productPlans[$product->id]) ? $copyProject->productPlans[$product->id] : array(), $product->plans, "class='form-control chosen' multiple");?> -
        - - > -
        -
        -
        -
        -
        project->manageProductPlan;?> -
        -
        -
        -
        -
        - productCommon;?> - - - - project->addProduct, '', "onchange=addNewProduct(this);");?> -
        -
        - -
        -
        - -
        -
        -
        -
        - product->plan;?> - -
        - - -
        -
        -
        -
        - -
        project->stageBy;?> - project->stageByList, '0');?> - -
        execution->team;?>
        project->desc;?> - -
        project->acl;?>project->aclList, $copyProjectID ? $copyProject->acl : 'private', "onclick='setWhite(this.value);'", 'block'));?>
        project->auth;?>project->authList, $copyProjectID ? $copyProject->auth : 'extend', '', 'block');?>
        - goback, '', 'class="btn btn-wide"') : html::backButton(); - ?> -
        -
        -
        -
        - - - - diff --git a/module/project/view/createguide.html.php b/module/project/view/createguide.html.php deleted file mode 100644 index cfe8e50caf..0000000000 --- a/module/project/view/createguide.html.php +++ /dev/null @@ -1,93 +0,0 @@ - - - - - - - - - - diff --git a/module/project/view/dynamic.html.php b/module/project/view/dynamic.html.php deleted file mode 100755 index 9e8ebf93ca..0000000000 --- a/module/project/view/dynamic.html.php +++ /dev/null @@ -1,130 +0,0 @@ -dynamic view file of dashboard module of ZenTaoPMS. - * - * @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com) - * @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html) - * @author Chunsheng Wang - * @package dashboard - * @version $Id: action->dynamic.html.php 1477 2011-03-01 15:25:50Z wwccss $ - * @link https://www.zentao.net - */ -?> - - - -
        - -
        -

        action->noDynamic;?>

        -
        - -
        - - $actions):?> - -
        -
        - - action->dynamic->today;?> - - - -
        -
          - - $action):?> - - major ? 'active' : '';?> - action, array('releaseddoc', 'collected'))) $class .= " {$action->action}";?> -
        • major) echo "class='$class'";?>> -
          - time?> - - actor);?> - actionLabel;?> - objectLabel;?> - objectID;?> - objectName) echo !empty($action->objectLink) ? html::a($action->objectLink, $action->objectName) : $action->objectName;?> - -
          -
        • - -
        -
        - -
        - -
        - -originalDate) + 24 * 3600); -$lastDate = substr($action->originalDate, 0, 10); -$hasPre = $this->action->hasPreOrNext($firstDate, 'pre'); -$hasNext = $this->action->hasPreOrNext($lastDate, 'next'); -$preLink = $hasPre ? inlink('dynamic', "projectID=$projectID&type=$type¶m=$param&recTotal={$pager->recTotal}&date=" . strtotime($firstDate) . '&direction=pre') : 'javascript:;'; -$nextLink = $hasNext ? inlink('dynamic', "projectID=$projectID&type=$type¶m=$param&recTotal={$pager->recTotal}&date=" . strtotime($lastDate) . '&direction=next') : 'javascript:;'; -?> - -
        - -
        - - - - diff --git a/module/project/view/edit.html.php b/module/project/view/edit.html.php deleted file mode 100755 index 90c3a12a5c..0000000000 --- a/module/project/view/edit.html.php +++ /dev/null @@ -1,250 +0,0 @@ - - * @package project - * @version $Id - * @link https://www.zentao.net - */ -?> - - - -execution->weekend);?> - -project->errorSameProducts);?> -project->errorSameBranches);?> -project->errorSamePlans);?> -parent);?> -id);?> -project->longTime);?> - - - -project->notAllowRemoveProducts);?> -project->linkedProjectsTip);?> - -parent ? $lang->project->subAclList : $lang->project->aclList;?> -project->edit->requiredFields;?> - -budget);?> -project->budgetOverrun);?> -project->currencySymbol)?> -project->parentBudget);?> -project->beginLessThanParent);?> -project->endGreatThanParent);?> -project->ignore);?> - - -project->unLinkProductTip);?> -model);?> -
        -
        -
        -

        project->edit;?>

        -
        -
        - - model != 'kanban' or $disableModel == ''):?> - - - - - - - - - parent])) - { - echo html::hidden('parent', $project->parent); - $attr = 'disabled'; - $programList = array($project->parent => $program->name); - } - ?> - - - - - - - - - - setCode) and $config->setCode == 1):?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - multiple)) unset($lang->project->endList[999]); - $deltaValue = $project->end == LONG_TIME ? 999 : (strtotime($project->end) - strtotime($project->begin)) / 3600 / 24 + 1; - ?> - - - end == LONG_TIME) echo "class='hidden'";?>> - - - - - - hasProduct and $this->config->vision != 'lite'):?> - - - - - - - - - - model == 'waterfall' or $project->model == 'waterfallplus'):?> - stageBy == 'product' and count($linkedProducts) < 2) ? 'hide' : '';?> - - - - - - - model == 'kanban'):?> - - - - - - - - - - printExtendFields($project, 'table', 'columns=3');?> - - - - - - - - - - - - - - - -
        project->model;?>project->modelList, $model, "class='form-control chosen' required $disableModel");?>
        project->parent;?>parent, "class='form-control chosen' data-lastSelected='{$project->parent}' $attr");?>
        project->name;?>name, "class='form-control' required");?>
        project->code;?>code, "class='form-control' required");?>
        project->multiple;?>project->multipleList, $project->multiple, 'disabled'));?>
        project->type;?>project->projectTypeList, $project->hasProduct, 'disabled'));?>
        project->PM;?>PM, "class='form-control chosen'" . (strpos($requiredFields, 'PM') !== false ? ' required' : ''));?>
        project->budget;?> -
        - budget != 0) ? 'placeholder="' . $lang->project->parentBudget . zget($lang->project->currencySymbol, $parentProgram->budgetUnit) . $availableBudget . '"' : '';?> - budget != 0 ? $project->budget : '', "class='form-control' onchange='budgetOverrunTips($project->id)' maxlength='10' " . (strpos($requiredFields, 'budget') !== false ? 'required ' : '') . ($project->budget == 0 ? 'disabled ' : '') . $placeholder);?> - - budgetUnit);?> - - - budgetUnit, "class='form-control w-80px'");?> - -
        -
        -
        - budget == 0) echo 'checked';?> /> - -
        -
        project->dateRange;?> -
        - begin, "class='form-control form-date' onchange='computeWorkDays();' placeholder='" . $lang->project->begin . "' required");?> - project->to;?> - end == LONG_TIME ? $lang->project->longTime : $project->end; - echo html::input('end', $end, "class='form-control form-date' onchange='computeWorkDays();' placeholder='" . $lang->project->end . "' required"); - ?> -
        -
        project->endList, $deltaValue, "onclick='computeEndDate(this.value)'");?>
        project->days;?> -
        - days, "class='form-control'");?> - execution->day;?> -
        -
        project->manageProductPlan;?> -
        -
        -
        -
        - type != 'normal' and isset($branchGroups[$product->id]);?> -
        '> - productCommon;?> - id, "class='form-control chosen' onchange='loadBranches(this)' data-last='" . $product->id . "' data-type='" . $product->type . "'");?> -
        -
        -
        '> -
        - product->branchName['branch'];?> - branches);?> - id]) ? $branchGroups[$product->id] : array(), $branchIdList, "class='form-control chosen' multiple onchange=\"loadPlans('#products{$i}', this)\"");?> -
        -
        -
        -
        -
        -
        > - product->plan;?> - id][]", isset($productPlans[$product->id]) ? $productPlans[$product->id] : array(), $product->plans, "class='form-control chosen' multiple");?> -
        - - > -
        -
        -
        -
        -
        project->stageBy;?> - project->stageByList, $project->stageBy == 'project', $disabled);?> - -
        execution->team;?>
        project->desc;?> - desc, "rows='6' class='form-control kindeditor' hidefocus='true'" . (strpos($requiredFields, 'desc') !== false ? ' required' : ''));?> -
        project->acl;?>acl, "onclick='setWhite(this.value);'", 'block'));?>
        whitelist;?> -
        - whitelist, 'class="form-control picker-select" multiple');?> - fetch('my', 'buildContactLists', "dropdownName=whitelist");?> -
        -
        project->auth;?>project->authList, $project->auth, '', 'block');?>
        - model); - echo html::submitButton(); - if(!isonlybody()) echo html::backButton(); - ?> -
        -
        -
        -
        - - - diff --git a/module/project/view/execution.html.php b/module/project/view/execution.html.php deleted file mode 100644 index c417809a3e..0000000000 --- a/module/project/view/execution.html.php +++ /dev/null @@ -1,131 +0,0 @@ - - - -edit);?> -selectAll);?> -execution->checkedExecutions);?> -app->getClientLang());?> -programplan->stageCustom->task);?> -project->disabledInputTip, $lang->edit . $lang->executionCommon));?> -edit . $lang->executionCommon);?> -project->disabledInputTip, $lang->programplan->stageCustom->task));?> -execution->checkedExecSummary);?> -execution->pageExecSummary);?> -execution->executionSummary);?> -execution->checkedExecutions);?> - - -
        - -
        -

        - execution->noExecution;?> - - - createLink('programplan', 'create', "projectID=$projectID&productID=$productID"), " " . $lang->programplan->create, '', "class='btn btn-info'");?> - - - createLink('execution', 'create', "projectID=$projectID"), " " . $lang->execution->create, '', "class='btn btn-info' data-app='execution'");?> - - - -

        -
        - - -
        - - - - - - stageBy == 'project' and $project->hasProduct) echo "";?> - - - - - - - - - - - - - - - stageBy = $project->stageBy;?> - product)) ? $execution->product : $productID;?> - execution->printNestedList($execution, false, $users, $executionProductID);?> - - -
        -
        - nameAB;?> - - - -
        -
        {$lang->project->product}project->status;?>execution->owner;?>programplan->begin;?>programplan->end;?>task->estimateAB;?>task->consumedAB;?>task->leftAB;?> project->progress;?>execution->burn;?> actions;?>
        - -
        - -
        - - - diff --git a/module/project/view/export.html.php b/module/project/view/export.html.php deleted file mode 100644 index 677cb08843..0000000000 --- a/module/project/view/export.html.php +++ /dev/null @@ -1,13 +0,0 @@ - - * @package project - * @version $Id$ - * @link https://www.zentao.net - */ -?> - diff --git a/module/project/view/group.html.php b/module/project/view/group.html.php deleted file mode 100644 index 88b44cc64e..0000000000 --- a/module/project/view/group.html.php +++ /dev/null @@ -1,78 +0,0 @@ - - * @package project - * @version $Id: prigroup.html.php 4769 2013-05-05 07:24:21Z wwccss $ - * @link https://www.zentao.net - */ -?> - - -group->confirmDelete);?> - -
        - -
        -

        - group->noGroup;?> -

        -
        - - - - - - - - - - - - - - id]);?> - - - - - - - - - -
        group->id;?>group->name;?>group->desc;?>group->users;?>actions;?>
        id;?>name;?>desc;?> - group->managepriv = $lang->group->managePrivByGroup;?> - role == 'limited' ? 'disabled' : '';?> - id", $group, 'list', 'lock', '', '', '', "data-app='project'");?> - group->managemember = $lang->group->manageMember;?> - id", $group, 'list', 'persons', '', 'iframe', 'yes', "data-width='90%'");?> - id", $group, 'list', 'edit', '', 'iframe', 'yes', "data-width='550'");?> - id", $group, 'list', 'copy', '', "iframe $disabled", 'yes', "data-width='550'");?> - role != 'limited') - { - $deleteURL = $this->createLink('group', 'delete', "groupID=$group->id&confirm=yes"); - $confirmDelete = htmlspecialchars(sprintf($lang->group->confirmDelete, $group->name)); - echo html::a("###", '', '', "onclick='ajaxDelete(\"$deleteURL\", \"groupList\", \"$confirmDelete\")' title='{$lang->group->delete}' class='btn btn-icon'"); - } - else - { - echo ""; - } - ?> -
        - -
        - diff --git a/module/project/view/kanban.html.php b/module/project/view/kanban.html.php deleted file mode 100644 index 4cda4cbb22..0000000000 --- a/module/project/view/kanban.html.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @package ZenTaoPMS - * @version $Id - */ -?> - - -config->systemMode == 'light'):?> - - - - -
        -

        project->empty;?>

        -
        - -
        - $projectGroup):?> - -
        -
        - project->typeList[$type];?> -
        -
        -
        -
        -
        - -
        - $lang->project->waitProjects, 'type' => 'waitProject'); -$kanbanColumns['doingProject'] = array('name' => $lang->project->doingProjects, 'type' => 'doingProject'); -$kanbanColumns['doingExecution'] = array('name' => $lang->project->doingExecutions, 'type' => 'doingExecution'); -$kanbanColumns['closedProject'] = array('name' => $lang->project->closedProjects, 'type' => 'closedProject'); -$userPrivs = array(); -$userPrivs['project'] = common::hasPriv('project', 'index'); -$userPrivs['execution'] = common::hasPriv('execution', 'task'); -js::set('kanbanColumns', array_values($kanbanColumns)); -js::set('userPrivs', $userPrivs); -js::set('latestExecutions', $latestExecutions); -js::set('programPairs', $programPairs); -js::set('doingText', $lang->project->statusList['doing']); -js::set('delayText', $lang->project->statusList['delay']); -js::set('priv', - array( - 'canStart' => common::hasPriv('project', 'start'), - 'canClose' => common::hasPriv('project', 'close'), - 'canActivate' => common::hasPriv('project', 'activate'), - ) -); -?> - - diff --git a/module/project/view/managemembers.html.php b/module/project/view/managemembers.html.php deleted file mode 100644 index fb69ceab4f..0000000000 --- a/module/project/view/managemembers.html.php +++ /dev/null @@ -1,147 +0,0 @@ - -id);?> - - - - - -project->unlinkExecutionMembers);?> - -
        -
        - - - - - - - - - - - - - - - account])) continue;?> - account]);?> - - - - - - - - - - - - $userName):?> - - - - - - - - - - - - - - - account])) continue;?> - - - - - - - - - account]);?> - - - - - - - - - - - - - - - - - - - - -
        team->account;?>team->role;?>team->days;?>team->hours;?>team->limited;?>actions;?>
        realname, "class='form-control' readonly");?>role, "class='form-control'");?>days, "class='form-control'");?> - hours, "class='form-control'");?> - account);?> - team->limitedList, $member->limited);?> - ", '', "onclick='addItem(this)' class='btn btn-link'");?> - ", '', "onclick='deleteItem(this)' class='btn btn-link'");?> -
        days, "class='form-control'");?>execution->defaultWorkhours, "class='form-control'");?>team->limitedList, 'no');?> - ", '', "onclick='addItem(this)' class='btn btn-link'");?> - ", '', "onclick='deleteItem(this)' class='btn btn-link'");?> -
        account, "class='form-control user-picker' onchange='setRole(this.value, $i)' data-max-list-count=" . $config->maxCount);?>role, "class='form-control'");?>days, "class='form-control'");?>hours, "class='form-control'");?>team->limitedList, 'no');?> - ", '', "onclick='addItem(this)' class='btn btn-link'");?> - ", '', "onclick='deleteItem(this)' class='btn btn-link'");?> -
        maxCount);?>days, "class='form-control'");?>execution->defaultWorkhours, "class='form-control'");?>team->limitedList, 'no');?> - ", '', "onclick='addItem(this)' class='btn btn-link'");?> - ", '', "onclick='deleteItem(this)' class='btn btn-link'");?> -
        - save, '', 'btn btn-wide btn-primary'); - } - else - { - echo html::submitButton('', '', 'hidden btn btn-wide btn-primary'); - echo html::commonButton($lang->save, 'onclick="saveMembers()" id="saveBtn"', 'btn btn-wide btn-primary'); - } - echo html::backButton(); - ?> -
        - -
        -
        -
        - - - - - - - - - - - -
        - diff --git a/module/project/view/managepriv.html.php b/module/project/view/managepriv.html.php deleted file mode 100644 index 2bbe60047a..0000000000 --- a/module/project/view/managepriv.html.php +++ /dev/null @@ -1,156 +0,0 @@ - - * @package group - * @version $Id: managepriv.html.php 4129 2013-01-18 01:58:14Z wwccss $ - * @link https://www.zentao.net - */ -?> - - - - -
        -
        - - - - - - - - resource as $moduleName => $moduleActions):?> - - group->checkMenuModule($menu, $moduleName)) continue;?> - $actionLabel) - { - if(strpos($changelogs, ",$moduleName-$actionLabel,") !== false) - { - $hasMethod = true; - break; - } - } - if(!$hasMethod) continue; - } - ?> - '> - - $moduleName->menus)):?> - - - - - - - - - -
        group->module;?>group->method;?>
        -
        - - -
        -
        - - $actionLabel):?> - $moduleName->menus) and $action == 'browse') continue;;?> - -
        - $lang->$moduleName->$actionLabel), isset($groupPrivs[$moduleName][$action]) ? $action : '', "title='{$lang->$moduleName->$actionLabel}'", 'inline');?> -
        - -
        -
        - - -
        -
        - - - -
        -
        -
        - - - - diff --git a/module/project/view/manageproducts.html.php b/module/project/view/manageproducts.html.php deleted file mode 100644 index 5568d89fe7..0000000000 --- a/module/project/view/manageproducts.html.php +++ /dev/null @@ -1,148 +0,0 @@ - - * @package project - * @version $Id - * @link https://www.zentao.net - */ -?> - - - - - - - - - - -project->unLinkProductTip);?> - -
        -
        -
        -
        -
        project->linkedProducts;?>
        -
        - - $linkedProduct):?> - - model == 'waterfall'));?> - -
        -
        '> -
        - ";?> - -
        - -
        -
        - - - - config->systemMode == 'ALM') - { - unset($currentProducts[$productID]); - } - else - { - unset($allProducts[$productID]); - } - } - - if(isset($branchGroups[$productID][$branchID])) unset($branchGroups[$productID][$branchID]); - - if(isset($branchGroups[$productID]) and empty($branchGroups[$productID])) - { - if($this->config->systemMode == 'ALM') - { - unset($currentProducts[$productID]); - } - else - { - unset($allProducts[$productID]); - } - } - ?> - - - -
        -
        -
        -
        project->unlinkedProducts;?>
        -
        - config->systemMode == 'ALM' ? $currentProducts : $allProducts; - foreach($unlinkedProducts as $productID => $productName): - ?> -
        -
        '> -
        - ";?> - -
        - -
        -
        - - -
        -
        -
        - - -
        - - config->systemMode == 'ALM'):?> - - -
        -
        -
        - -stageBy == 'product' and count($linkedProducts) == 1 and empty($executions));?> - - -project->noticeDivsion);?> -project->stageBySwitchList);?> - diff --git a/module/project/view/start.html.php b/module/project/view/start.html.php deleted file mode 100644 index 9e106503ad..0000000000 --- a/module/project/view/start.html.php +++ /dev/null @@ -1,51 +0,0 @@ - - * @package project - * @version $Id: prjstart.html.php 4769 2013-05-05 07:24:21Z wwccss $ - * @link https://www.zentao.net - */ -?> - - -
        -
        -

        - id;?> - name'>" . $project->name . '') : html::a($this->createLink('project', 'view', 'project=' . $project->id), $project->name, '_blank');?> - - arrow . $lang->{$project->type}->start;?> - -

        -
        -
        - - - - - - - - printExtendFields($project, 'table', 'columns=3');?> - - - - - - - - -
        project->realBegan;?>
        comment;?>
        - {$project->type}->start);?> -
        -
        -
        -
        - -
        -
        - diff --git a/module/project/view/suspend.html.php b/module/project/view/suspend.html.php deleted file mode 100644 index e59394453c..0000000000 --- a/module/project/view/suspend.html.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @package project - * @version $Id: suspend.html.php 935 2013-01-16 07:49:24Z wwccss@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -
        -
        -

        - id;?> - name'>" . $project->name . '') : html::a($this->createLink('project', 'view', 'project=' . $project->id), $project->name, '_blank');?> - - arrow . $lang->{$project->type}->suspend;?> - -

        -
        -
        - - - - - - printExtendFields($project, 'table');?> - - - - - - - -
        project->status;?>
        comment;?>
        {$project->type}->suspend) . html::linkButton($lang->goback, $this->session->taskList, 'self', '', 'btn btn-wide'); ?>
        -
        -
        -
        -
        - diff --git a/module/project/view/team.html.php b/module/project/view/team.html.php deleted file mode 100644 index 3e7653c59d..0000000000 --- a/module/project/view/team.html.php +++ /dev/null @@ -1,112 +0,0 @@ - - -project->confirmUnlinkMember)?> -user->error->noAccess)?> - -
        - -
        -

        - execution->noMembers;?> - user->admin) or empty($app->user->rights['rights']['my']['limited'])) && common::hasPriv('project', 'manageMembers')):?> - createLink('project', 'manageMembers', "projectID=$projectID"), " " . $lang->project->manageMembers, '', "class='btn btn-info'");?> - -

        -
        - -
        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        team->account;?>team->role;?>team->join;?>team->days;?>team->hours;?>team->totalHours;?>team->limited;?>actions;?>
        - userID]) ? $this->createLink('user', 'view', "userID={$member->userID}") : "javascript: alert(noAccess);"; - echo html::a($link, $member->realname, '', 'data-app="system"'); - } - else - { - echo $member->realname; - } - $memberHours = $member->days * $member->hours; - $totalHours += $memberHours; - ?> - role;?>join;?>days . $lang->execution->day;?>hours . $lang->execution->workHour;?>execution->workHour;?>team->limitedList[$member->limited];?> - account}\", \"{$member->userID}\")", '', '', "class='btn' title='{$lang->project->unlinkMember}'"); - } - ?> -
        - -
        - -
        - diff --git a/module/project/view/testtask.html.php b/module/project/view/testtask.html.php deleted file mode 100644 index 0d3538e9a3..0000000000 --- a/module/project/view/testtask.html.php +++ /dev/null @@ -1,136 +0,0 @@ - - * @package testtask - * @version $Id: browse.html.php 1914 2011-06-24 10:11:25Z yidong@cnezsoft.com $ - * @link https://www.zentao.net - */ -?> - -testtask->confirmDelete)?> -hasProduct):?> - - - -
        - -
        -

        - testtask->noTesttask;?> - - createLink('testtask', 'create', "product=0&executionID=0&build=0&projectID=$projectID"), " " . $lang->testtask->create, '', "class='btn btn-info' data-app={$this->app->tab}");?> - -

        -
        - -
        - - - recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?> - - '> - - - - - - - - - - - - - - $productTasks):?> - - - status == 'wait') $waitCount ++;?> - status == 'doing') $testingCount ++;?> - status == 'blocked') $blockedCount ++;?> - status == 'done') $doneCount ++;?> - > - - - - - - - - - - processStatus('testtask', $task);?> - - - - - - - - - - -
        '>testtask->product);?> - idAB);?> - testtask->name);?>testtask->build);?>testtask->owner);?>testtask->begin);?>testtask->end);?>statusAB);?>actions;?>
        '> - -
        testtask->allTasks;?>
        -
        - id);?> - createLink('testtask', 'cases', "taskID=$task->id"), $task->name, '', "data-app='project'");?>build == 'trunk' || empty($task->buildName)) ? $lang->trunk : html::a($this->createLink('build', 'view', "buildID=$task->build"), $task->buildName);?>owner);?>begin?>end?> - - - id", $task, 'list', 'sitemap'); - common::printIcon('testtask', 'linkCase', "taskID=$task->id", $task, 'list', 'link'); - common::printIcon('project', 'testreport', "projectID=$task->project&objectType=project&extra=$task->id", '', 'list', 'summary', '', '', false, "data-app='project'", $this->lang->testreport->common); - common::printIcon('testtask', 'edit', "taskID=$task->id", $task, 'list'); - common::printIcon('testtask', 'delete', "taskID=$task->id", $task, 'list', 'trash', 'hiddenwin'); - } - ?> -
        - -
        - -
        - diff --git a/module/project/view/view.html.php b/module/project/view/view.html.php deleted file mode 100644 index 4684743ede..0000000000 --- a/module/project/view/view.html.php +++ /dev/null @@ -1,301 +0,0 @@ - - * @package project - * @version $Id: view.html.php 4594 2013-03-13 06:16:02Z wyd621@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - - - -
        -
        -
        -
        -
        -
        -
        execution->latestDynamic;?>
        - model != 'kanban' and common::hasPriv('project', 'dynamic')):?> - - -
        -
        -
          - -
        • major) echo "class='active'";?>> -
          - date;?> - actor) . ' ' . "{$action->actionLabel}" . $action->objectLabel . ' ' . html::a($action->objectLink, $action->objectName, '', "title='$action->objectName'");?> -
          -
        • - -
        -
        -
        -
        -
        -
        -
        -
        execution->relatedMember;?>
        - - - -
        -
        -
        - - PM):?> - - PM]);?> -
        PM);?> (project->PM;?>)
        - - PO):?> - - PO]);?> -
        PO);?> (project->PO;?>)
        - - QD):?> - - QD]);?> -
        QD);?> (project->QD;?>)
        - - RD):?> - - RD]);?> -
        RD);?> (project->RD;?>)
        - - - - $i) break;?> -
        account);?>
        - - -
        - id", "  " . $lang->project->manageMembers, '', "class='text-muted'");?> -
        -
        -
        -
        -
        - -
        -
        - printExtendFields($project, 'div', "position=left&inForm=0");?> -
        -
        - -
        - - createLink('action', 'comment', "objectType=project&objectID=$project->id");?> - -
        -
        -
        -
        - session->projectList ? $this->session->projectList : inlink('browse');?> - - project->buildOperateMenu($project, 'view');?> -
        -
        -
        -
        -
        -
        -
        -
        - setCode) or $config->setCode == 0) ? 'hidden' : '';?> -

        id;?> code;?> name;?>

        -
        -
        -

        - vision == 'rnd'):?> - project->projectTypeList, $project->hasProduct);?> - - deleted):?> - project->deleted;?> - - execution->lifeTimeList, $project->lifetime, '');?> - delay)):?> - project->delayed;?> - - processStatus('project', $project);?> - -

        -
        -
        - -
        -
        - project->parent;?> -
        -
        -
        -
        - grade > 1):?> - - $name) - { - $names .= common::hasPriv('program', 'product') ? html::a($this->createLink('program', 'product', "programID=$id"), $name) . '/ ' : $name . '/ '; - } - echo rtrim($names, '/ '); - ?> - -
        -
        -
        -
        - - hasProduct)):?> -
        -
        - project->manageProducts;?> - id", strtoupper($lang->more), '', "class='btn btn-link pull-right muted'");?> -
        -
        -
        - $product):?> - branches as $branchID):?> - -
        - createLink('product', 'browse', "productID=$productID&branch=$branchID"), " " . $product->name . $branchName);?> -
        - - -
        -
        -
        -
        -
        execution->linkPlan;?>
        -
        -
        - $product):?> - plans as $planIDList):?> - - - -
        createLink('productplan', 'view', "planID={$planID}"), " " . $product->name . '/' . $planGroup[$productID][$planID]);?>
        - - - - -
        -
        -
        - -
        -
        execution->lblStats;?>
        -
        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        - model == 'waterfall' ? $this->project->getWaterfallProgress($project->id) : (($workhour->totalConsumed + $workhour->totalLeft) ? floor($workhour->totalConsumed / ($workhour->totalConsumed + $workhour->totalLeft) * 1000) / 1000 * 100 : 0);?> - project->progress;?> percent;?>   -
        -
        -
        -
        project->begin;?>begin;?>project->realBeganAB;?>realBegan == '0000-00-00' ? '' : $project->realBegan;?>
        project->end;?>end = $project->end == LONG_TIME ? $this->lang->project->longTime : $project->end;;?>project->realEndAB;?>realEnd == '0000-00-00' ? '' : $project->realEnd;?>
        execution->totalEstimate;?>totalEstimate . $lang->execution->workHour;?>execution->totalDays;?>days . $lang->execution->day;?>
        execution->totalConsumed;?>totalConsumed . $lang->execution->workHour;?>execution->totalHours;?>totalHours . $lang->execution->workHour;?>
        execution->totalLeft;?>totalLeft . $lang->execution->workHour;?>
        -
        -
        -
        -
        execution->basicInfo;?>
        -
        - - - hasProduct) and !empty($config->URAndSR) and $project->model !== 'kanban'):?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        story->common;?>storyCount;?>requirement->common;?>requirementCount;?>
        task->common;?>taskCount;?>bug->common;?>bugCount;?>
        project->budget;?>budget;?>
        story->common;?>storyCount;?>task->common;?>taskCount;?>
        bug->common;?>bugCount;?>project->budget;?>budget;?>
        -
        -
        -
        -
        project->acl;?>
        -
        - parent ? $lang->project->subAclList : $lang->project->aclList;?> -

        acl];?>

        -
        -
        -
        - printExtendFields($project, 'div', "position=right&inForm=0&inCell=1");?> -
        -
        -
        -
        - -
        - - diff --git a/module/project/zen.php b/module/project/zen.php index d0c0577c29..ba74023bdf 100755 --- a/module/project/zen.php +++ b/module/project/zen.php @@ -1380,7 +1380,7 @@ class projectZen extends project if($story->isParent) continue; $project->storyPoints += $story->estimate; } - $project->storyPoints .= ' ' . $this->config->hourUnit; + $project->storyPoints = helper::formatHours($project->storyPoints) . ' ' . $this->config->hourUnit; $executions = zget($executionGroup, $project->id, array()); $project->executionCount = count($executions); diff --git a/module/projectrelease/control.php b/module/projectrelease/control.php index 1d50e0ca53..9eaaf9295f 100644 --- a/module/projectrelease/control.php +++ b/module/projectrelease/control.php @@ -88,7 +88,7 @@ class projectrelease extends control $execution = $this->loadModel('execution')->getByID($executionID); $this->view->title = (isset($project->name) ? $project->name : $execution->name) . $this->lang->hyphen . $this->lang->release->browse; - $this->view->products = $this->product->getProductPairsByProject($projectID); + $this->view->products = $this->product->getPairs('all', 0, '', 'all'); $this->view->pageSummary = $this->release->getPageSummary($releases, $type); $this->view->projectID = $projectID; $this->view->executionID = $executionID; diff --git a/module/projectrelease/js/browse.ui.js b/module/projectrelease/js/browse.ui.js index 4673c33330..d217e40c12 100644 --- a/module/projectrelease/js/browse.ui.js +++ b/module/projectrelease/js/browse.ui.js @@ -1,5 +1,11 @@ window.renderCell = function(result, {col, row}) { + if(col.name == 'system' && row.data.releases) + { + result[0] = {className: 'overflow-hidden', html: result[0]}; + result[result.length] = {html:'' + integratedLabel + '', className:'flex items-end', style:{flexDirection:"column"}}; + } + if(col.name == 'name') { if(row.data.marker == 1) diff --git a/module/projectrelease/ui/browse.html.php b/module/projectrelease/ui/browse.html.php index 40a8a4f6ae..3a465e3bce 100644 --- a/module/projectrelease/ui/browse.html.php +++ b/module/projectrelease/ui/browse.html.php @@ -96,6 +96,7 @@ toolbar ); jsVar('markerTitle', $lang->release->marker); +jsVar('integratedLabel', $lang->release->integratedLabel); jsVar('canViewProjectbuild', hasPriv('projectbuild', 'view')); $cols = $this->loadModel('datatable')->getSetting('projectrelease'); diff --git a/module/projectrelease/view/browse.html.php b/module/projectrelease/view/browse.html.php deleted file mode 100644 index 5cd5378550..0000000000 --- a/module/projectrelease/view/browse.html.php +++ /dev/null @@ -1,123 +0,0 @@ - - * @package release - * @version $Id: browse.html.php 4129 2020-11-25 11:58:14Z wwccss $ - * @link https://www.zentao.net - */ -?> - - -release->confirmDelete)?> -release->pageAllSummary)?> -release->pageSummary)?> - - -
        - -
        -

        - release->noRelease;?> - - createLink('projectrelease', 'create', "projectID=$projectID"), " " . $lang->release->create, '', "class='btn btn-info'");?> - -

        -
        - - - - - - - hasProduct):?> - - - - - - - - - projectrelease->getFlowExtendFields(); - foreach($extendFields as $extendField) echo ""; - ?> - - - - - - buildInfos); - $rowspan = $buildCount > 1 ? "rowspan='$buildCount'" : ''; - if($buildCount == 0) $release->buildInfos = array(''); - foreach($release->buildInfos as $buildID => $build): - ?> - - - - - hasProduct):?> - - - - - - processStatus('release', $release);?> - - - - - - " . $this->loadModel('flow')->getFieldValue($extendField, $release) . "";?> - - - - - - - -
        release->id;?>release->name;?>projectrelease->product;?>release->includedBuild;?>release->branch;?>release->status;?>release->date;?>{$extendField->name}actions;?>
        >id"), sprintf('%03d', $release->id));?>> - marker ? " " : ''; - echo html::a(inlink('view', "release=$release->id"), $release->name, '', "data-app='$from'") . $flagIcon; - ?> - title='productName?>'>productName?> - branchName) echo "{$build->branchName} "; - echo html::a($this->createLink($build->execution ? 'build' : 'projectbuild', 'view', "buildID=$buildID"), $build->name, '', "data-app='project' title='{$build->name}'"); - } - ?> - class='c-branch text-center'>branchName; ?> class='c-status text-center' title=''> - - class='text-center'>date;?> class='c-actions'>projectrelease->buildOperateMenu($release, 'browse');?>
        - - -
        - diff --git a/module/projectstory/test/ui/viewinlite.php b/module/projectstory/test/ui/viewinlite.php index 7cc5a1b5de..83594c48a8 100755 --- a/module/projectstory/test/ui/viewinlite.php +++ b/module/projectstory/test/ui/viewinlite.php @@ -99,6 +99,6 @@ $tester = new viewInLiteTester(); $tester->login(); -r($tester->viewInLite()) && p('message') && e('目标详情页正确'); +r($tester->viewInLite()) && p('message') && e('目标详情页内容正确'); $tester->closeBrowser(); diff --git a/module/release/config.php b/module/release/config.php index 5d920a51dc..ab84229595 100644 --- a/module/release/config.php +++ b/module/release/config.php @@ -14,7 +14,7 @@ $config->release->editor->edit = array('id' => 'desc', 'tools' => 'simpleTool global $lang, $app; $config->release->actionList['linkStory']['icon'] = 'link'; $config->release->actionList['linkStory']['hint'] = $lang->release->linkStory; -$config->release->actionList['linkStory']['url'] = array('module' => 'release', 'method' => 'view', 'params' => 'releaseID={id}&type=story&link=true'); +$config->release->actionList['linkStory']['url'] = common::hasPriv('release', 'linkStory') ? array('module' => 'release', 'method' => 'view', 'params' => 'releaseID={id}&type=story&link=true') : null; $config->release->actionList['unlinkStory']['icon'] = 'unlink'; $config->release->actionList['unlinkStory']['hint'] = $lang->release->unlinkStory; @@ -22,7 +22,7 @@ $config->release->actionList['unlinkStory']['url'] = 'javascript: unlinkObject( $config->release->actionList['linkBug']['icon'] = 'bug'; $config->release->actionList['linkBug']['hint'] = $lang->release->linkBug; -$config->release->actionList['linkBug']['url'] = array('module' => 'release', 'method' => 'view', 'params' => 'releaseID={id}&type=bug&link=true'); +$config->release->actionList['linkBug']['url'] = common::hasPriv('release', 'linkBug') ? array('module' => 'release', 'method' => 'view', 'params' => 'releaseID={id}&type=bug&link=true') : null; $config->release->actionList['unlinkBug']['icon'] = 'unlink'; $config->release->actionList['unlinkBug']['hint'] = $lang->release->unlinkBug; @@ -59,7 +59,7 @@ $config->release->actionList['pause']['data-confirm'] = array('message' => $lang $config->release->actionList['edit']['icon'] = 'edit'; $config->release->actionList['edit']['text'] = $lang->release->edit; $config->release->actionList['edit']['hint'] = $lang->release->edit; -$config->release->actionList['edit']['url'] = helper::createLink('release', 'edit', 'releaseID={id}'); +$config->release->actionList['edit']['url'] = $app->tab == 'project' ? helper::createLink('projectrelease', 'edit', 'releaseID={id}') : helper::createLink('release', 'edit', 'releaseID={id}'); $config->release->actionList['notify']['icon'] = 'bullhorn'; $config->release->actionList['notify']['hint'] = $lang->release->notify; diff --git a/module/release/control.php b/module/release/control.php index d879d76a3f..d9d0d41fa3 100755 --- a/module/release/control.php +++ b/module/release/control.php @@ -91,16 +91,22 @@ class release extends control $actionURL = $this->createLink('release', 'browse', "productID={$productID}&branch={$branch}&type=bySearch&orderBy={$sort}¶m=myQueryID&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID&from=$from&blockID=$blockID"); $this->releaseZen->buildSearchForm($queryID, $actionURL, $this->view->product, $branch); - $releaseQuery = $type == 'bySearch' ? $this->releaseZen->getSearchQuery($queryID) : ''; - $releases = $this->release->getList($productID, $branch, $type, $sort, $releaseQuery, $pager); - $children = implode(',', array_column($releases, 'releases')); - - foreach($releases as $release) $release->desc = str_replace(' ', ' ', strip_tags($release->desc)); + $releaseQuery = $type == 'bySearch' ? $this->releaseZen->getSearchQuery($queryID) : ''; + $currentReleases = $this->release->getList($productID, $branch, $type, $sort, $releaseQuery, $pager); + $children = implode(',', array_column($currentReleases, 'releases')); $childReleases = $this->release->getListByCondition(explode(',', $children), 0, true); + $releases = $this->release->processReleaseListData($currentReleases, $childReleases); + foreach($releases as $release) + { + $release->desc = str_replace(' ', ' ', strip_tags($release->desc)); + $release->branchName = trim($release->branchName, ','); + $release->branch = trim($release->branch, ','); + } + $this->view->title = $this->view->product->name . $this->lang->hyphen . $this->lang->release->browse; - $this->view->releases = $this->release->processReleaseListData($releases, $childReleases); - $this->view->pageSummary = $this->release->getPageSummary($releases, $type); + $this->view->releases = $releases; + $this->view->pageSummary = $this->release->getPageSummary($currentReleases, $type); $this->view->type = $type; $this->view->orderBy = $orderBy; $this->view->param = $param; @@ -108,7 +114,7 @@ class release extends control $this->view->showBranch = $showBranch; $this->view->branchPairs = $this->loadModel('branch')->getPairs($productID); $this->view->appList = $this->loadModel('system')->getPairs(); - $this->view->childReleases = $this->release->getListByCondition(explode(',', $children), 0, true); + $this->view->childReleases = $childReleases; $this->view->from = $from; $this->view->blockID = $blockID; $this->view->idList = ''; diff --git a/module/release/js/ajaxloadsystemblock.ui.js b/module/release/js/ajaxloadsystemblock.ui.js index 8354c1f64f..c9d76d24c2 100644 --- a/module/release/js/ajaxloadsystemblock.ui.js +++ b/module/release/js/ajaxloadsystemblock.ui.js @@ -71,6 +71,8 @@ window.deleteItem = function(obj) if(trLen <= appLength) $('#systemForm tbody tr .actions-list .add-item').removeClass('hidden'); setTimeout(window.initAppPicker, 100); + + itemIndex --; }; $(function() diff --git a/module/release/js/browse.ui.js b/module/release/js/browse.ui.js index 3d9a625159..da4fb23580 100644 --- a/module/release/js/browse.ui.js +++ b/module/release/js/browse.ui.js @@ -1,5 +1,11 @@ window.renderCell = function(result, {col, row}) { + if(col.name == 'system' && row.data.releases) + { + result[0] = {className: 'overflow-hidden', html: result[0]}; + result[result.length] = {html:'' + integratedLabel + '', className:'flex items-end', style:{flexDirection:"column"}}; + } + if(col.name == 'name') { if(row.data.marker == 1) @@ -14,7 +20,7 @@ window.renderCell = function(result, {col, row}) result = []; if(!row.data.build.name) return result; - let branchLabel = showBranch ? "" + row.data.build.branchName + ' ' : ''; + let branchLabel = showBranch && typeof row.data.build.branchName != 'undefined' ? "" + row.data.build.branchName + ' ' : ''; if(isFromDoc) { result.push({html: branchLabel + row.data.build.name}); diff --git a/module/release/lang/de.php b/module/release/lang/de.php index 95b6f1787f..e17d762f9e 100755 --- a/module/release/lang/de.php +++ b/module/release/lang/de.php @@ -136,3 +136,4 @@ $lang->release->markerList[0] = 'No'; $lang->release->failTips = 'Deployment/Launch Failed'; $lang->release->versionErrorTip = 'Version number can only contain letters, numbers, hyphens (-), dots (.), and underscores (_).'; +$lang->release->integratedLabel = 'Integrated'; diff --git a/module/release/lang/en.php b/module/release/lang/en.php index 31dbfa9c94..35bd79aaad 100755 --- a/module/release/lang/en.php +++ b/module/release/lang/en.php @@ -136,3 +136,4 @@ $lang->release->markerList[0] = 'No'; $lang->release->failTips = 'Deployment/Launch Failed'; $lang->release->versionErrorTip = 'Version number can only contain letters, numbers, hyphens (-), dots (.), and underscores (_).'; +$lang->release->integratedLabel = 'Integrated'; diff --git a/module/release/lang/fr.php b/module/release/lang/fr.php index 36e23aad21..556d3810b2 100755 --- a/module/release/lang/fr.php +++ b/module/release/lang/fr.php @@ -136,3 +136,4 @@ $lang->release->markerList[0] = 'No'; $lang->release->failTips = 'Deployment/Launch Failed'; $lang->release->versionErrorTip = 'Version number can only contain letters, numbers, hyphens (-), dots (.), and underscores (_).'; +$lang->release->integratedLabel = 'Integrated'; diff --git a/module/release/lang/zh-cn.php b/module/release/lang/zh-cn.php index 58ddef616d..54ed41b819 100755 --- a/module/release/lang/zh-cn.php +++ b/module/release/lang/zh-cn.php @@ -136,3 +136,4 @@ $lang->release->markerList[0] = '否'; $lang->release->failTips = '部署/上线失败'; $lang->release->versionErrorTip = "版本号只能包含大小写英文字母、数字、减号(-)、点(.) 、下划线(_)"; +$lang->release->integratedLabel = '集成'; diff --git a/module/release/model.php b/module/release/model.php index 46938d5974..86645109a5 100755 --- a/module/release/model.php +++ b/module/release/model.php @@ -110,21 +110,29 @@ class releaseModel extends model foreach($releases as $release) $projectIdList .= trim($release->project, ',') . ','; $projectPairs = $this->dao->select('id,name')->from(TABLE_PROJECT)->where('id')->in($projectIdList)->fetchPairs(); - $builds = $this->dao->select('id,name,execution,project') - ->from(TABLE_BUILD) - ->where('deleted')->eq(0) + $builds = $this->dao->select("t1.id, t1.name, t1.project, t1.execution, IF(t2.name IS NOT NULL, t2.name, '') AS projectName, IF(t3.name IS NOT NULL, t3.name, '{$this->lang->trunk}') AS branchName") + ->from(TABLE_BUILD)->alias('t1') + ->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id') + ->leftJoin(TABLE_BRANCH)->alias('t3')->on('t1.branch = t3.id') ->fetchAll('id'); + $this->loadModel('branch'); foreach($releases as $release) { $releaseBuilds = array(); foreach(explode(',', $release->build) as $buildID) { if(!$buildID || !isset($builds[$buildID])) continue; - $releaseBuilds[] = $builds[$buildID]; + $releaseBuilds[$buildID] = $builds[$buildID]; } $release->builds = $releaseBuilds; + $branchName = array(); + foreach(explode(',', trim($release->branch, ',')) as $releaseBranch) $branchName[] = $releaseBranch === '0' ? $this->lang->branch->main : $this->branch->getByID($releaseBranch); + $branchName = implode(',', $branchName); + + $release->branchName = empty($branchName) ? $this->lang->branch->main : $branchName; + $release->projectName = array(); foreach(explode(',', trim($release->project, ',')) as $projectID) $release->projectName[$projectID] = zget($projectPairs, $projectID, ''); $release->projectName = implode(' ', $release->projectName); @@ -1386,7 +1394,7 @@ class releaseModel extends model * * @param array $releaseList * @param array $childReleases - * @param int $addActionsAndBuildLink + * @param bool $addActionsAndBuildLink * @access public * @return array */ @@ -1403,30 +1411,7 @@ class releaseModel extends model $release->rowspan = $buildCount; if($addActionsAndBuildLink) $release->actions = $this->buildActionList($release); - if(!empty($release->builds)) - { - foreach($release->builds as $build) - { - $releaseInfo = clone $release; - - if($addActionsAndBuildLink) - { - $moduleName = $build->execution ? 'build' : 'projectbuild'; - $canClickable = false; - if($moduleName == 'projectbuild' && $this->project->checkPriv((int)$build->project)) $canClickable = true; - if($moduleName == 'build' && $this->execution->checkPriv((int)$build->execution)) $canClickable = true; - $build->link = $canClickable ? helper::createLink($moduleName, 'view', "buildID={$build->id}") : ''; - } - - $releaseInfo->build = $build; - - $releases[] = $releaseInfo; - } - } - else - { - $releases[] = $release; - } + $releases = array_merge($releases, $this->processReleaseBuilds($release, $addActionsAndBuildLink)); if(empty($release->releases)) continue; @@ -1436,14 +1421,55 @@ class releaseModel extends model { $child = clone $childReleases[$childID]; $child = current($this->processReleaseListData(array($child))); - $child->rowID = "{$release->id}-{$childID}"; $child->parent = $release->id; - $releases[$child->rowID] = $child; + $releases = array_merge($releases, $this->processReleaseBuilds($child, $addActionsAndBuildLink)); } } } return $releases; } + + /** + * 处理发布构建信息。 + * Process release builds. + * + * @param object $release + * @param bool $addActionsAndBuildLink + * @access public + * @return array + */ + public function processReleaseBuilds(object $release, bool $addActionsAndBuildLink): array + { + $releases = array(); + + if(!empty($release->builds)) + { + foreach($release->builds as $build) + { + $releaseInfo = clone $release; + + if($addActionsAndBuildLink) + { + $moduleName = $build->execution ? 'build' : 'projectbuild'; + $canClickable = false; + if($moduleName == 'projectbuild' && $this->project->checkPriv((int)$build->project)) $canClickable = true; + if($moduleName == 'build' && $this->execution->checkPriv((int)$build->execution)) $canClickable = true; + $build->link = $canClickable ? helper::createLink($moduleName, 'view', "buildID={$build->id}") : ''; + } + + $releaseInfo->build = $build; + $releaseInfo->projectName = $build->projectName; + + $releases[] = $releaseInfo; + } + } + else + { + $releases[] = $release; + } + + return $releases; + } } diff --git a/module/release/test/lib/release.unittest.class.php b/module/release/test/lib/release.unittest.class.php index 7f0742455b..43bc76f5f7 100644 --- a/module/release/test/lib/release.unittest.class.php +++ b/module/release/test/lib/release.unittest.class.php @@ -347,4 +347,36 @@ class releaseTest return $this->objectModel->dao->select('*')->from(TABLE_STORY)->where('id')->eq($storyID)->fetch(); } + + /** + * 处理发布列表数据测试。 + * Process release list data test. + * + * @param int $productID + * @param string $type + * @param array $childReleases + * @param bool $addActionsAndBuildLink + * @access public + * @return void + */ + public function processReleaseListDataTest(int $productID, string $type = 'all', array $childReleases = array(), bool $addActionsAndBuildLink = true) + { + $releases = $this->objectModel->getList($productID, 0, $type); + return $this->objectModel->processReleaseListData($releases, $childReleases, $addActionsAndBuildLink); + } + + /** + * 处理发布版本数据测试。 + * Process release build data test. + * + * @param int $releaseID + * @param bool $addActionsAndBuildLink + * @access public + * @return array + */ + public function processReleaseBuildsTest(int $releaseID, bool $addActionsAndBuildLink = true): array + { + $release = $this->objectModel->getByID($releaseID); + return $this->objectModel->processReleaseBuilds($release, $addActionsAndBuildLink); + } } diff --git a/module/release/test/model/processreleasebuilds.php b/module/release/test/model/processreleasebuilds.php new file mode 100644 index 0000000000..2305e2aa9a --- /dev/null +++ b/module/release/test/model/processreleasebuilds.php @@ -0,0 +1,38 @@ +#!/usr/bin/env php +processReleaseForCreate(); +timeout=0 +cid=1 + +- 测试同步版本数据并处理空的数据 + - 第0条的name属性 @发布1 + - 第0条的project属性 @131 +- 测试同步版本数据并处理空的数据 + - 第0条的name属性 @发布2 + - 第0条的project属性 @131 +- 测试同步版本数据并处理空的数据 + - 第0条的name属性 @发布3 + - 第0条的project属性 @131 +- 测试同步版本数据并处理空的数据第0条的build属性 @~~ +*/ + +include dirname(__FILE__, 5) . '/test/lib/init.php'; +include dirname(__FILE__, 2) . '/lib/release.unittest.class.php'; + +$build = zenData('build')->loadYaml('build'); +$build->project->range('1{2},0{3}'); +$build->execution->range('0,101,0{3}'); +$build->gen(5); + +zenData('release')->loadYaml('release')->gen(5); +zenData('product')->gen(5); +su('admin'); + +$releaseTester = new releaseTest(); +r($releaseTester->processReleaseBuildsTest(1)) && p('0:name,project') && e('发布1,131'); // 测试同步版本数据并处理空的数据 +r($releaseTester->processReleaseBuildsTest(2)) && p('0:name,project') && e('发布2,131'); // 测试同步版本数据并处理空的数据 +r($releaseTester->processReleaseBuildsTest(3)) && p('0:name,project') && e('发布3,131'); // 测试同步版本数据并处理空的数据 +r($releaseTester->processReleaseBuildsTest(2, false)) && p('0:build') && e('~~'); // 测试同步版本数据并处理空的数据 diff --git a/module/release/test/model/processreleaselistdata.php b/module/release/test/model/processreleaselistdata.php new file mode 100644 index 0000000000..7f6b5a5a70 --- /dev/null +++ b/module/release/test/model/processreleaselistdata.php @@ -0,0 +1,36 @@ +#!/usr/bin/env php +processReleaseForCreate(); +timeout=0 +cid=1 + +- 测试同步版本数据并处理空的数据 + - 第0条的name属性 @发布3 + - 第0条的project属性 @131 +- 测试同步版本数据并处理空的数据 + - 第1条的name属性 @发布4 + - 第1条的project属性 @131 +- 测试同步版本数据并处理空的数据 @0 +- 测试同步版本数据并处理空的数据第0条的build属性 @~~ +*/ + +include dirname(__FILE__, 5) . '/test/lib/init.php'; +include dirname(__FILE__, 2) . '/lib/release.unittest.class.php'; + +$build = zenData('build')->loadYaml('build'); +$build->project->range('1{2},0{3}'); +$build->execution->range('0,101,0{3}'); +$build->gen(5); + +zenData('release')->loadYaml('release')->gen(5); +zenData('product')->gen(5); +su('admin'); + +$releaseTester = new releaseTest(); +r($releaseTester->processReleaseListDataTest(1)) && p('0:name,project') && e('发布3,131'); // 测试同步版本数据并处理空的数据 +r($releaseTester->processReleaseListDataTest(2)) && p('1:name,project') && e('发布4,131'); // 测试同步版本数据并处理空的数据 +r($releaseTester->processReleaseListDataTest(3)) && p() && e('0'); // 测试同步版本数据并处理空的数据 +r($releaseTester->processReleaseListDataTest(2, 'all', array(), false)) && p('0:build') && e('~~'); // 测试同步版本数据并处理空的数据 diff --git a/module/release/ui/browse.html.php b/module/release/ui/browse.html.php index 1273b36fa8..4646603e02 100644 --- a/module/release/ui/browse.html.php +++ b/module/release/ui/browse.html.php @@ -94,6 +94,7 @@ toolbar ); jsVar('markerTitle', $lang->release->marker); +jsVar('integratedLabel', $lang->release->integratedLabel); jsVar('showBranch', $showBranch); jsVar('type', $type); jsVar('isFromDoc', $isFromDoc); diff --git a/module/release/ui/create.html.php b/module/release/ui/create.html.php index b3746cd5e0..ab1f6be795 100644 --- a/module/release/ui/create.html.php +++ b/module/release/ui/create.html.php @@ -35,6 +35,11 @@ if(!empty($projectID)) formPanel ( set::title($lang->release->create), + set::titleClass('text-lg gap-0'), + to::titleSuffix + ( + btn(setClass('ghost'), icon('help'), set::hint($lang->help), set::url('https://www.zentao.net/book/zentaopms/888.html'), set::target('_blank')) + ), on::change('[name=status]')->call('changeStatus'), on::change('[name=newSystem]')->call('setSystemBox'), on::change('[name=system]')->call('loadSystemBlock'), diff --git a/module/release/view/browse.html.php b/module/release/view/browse.html.php deleted file mode 100644 index 97a0d8dca2..0000000000 --- a/module/release/view/browse.html.php +++ /dev/null @@ -1,131 +0,0 @@ - - * @package release - * @version $Id: browse.html.php 4129 2013-01-18 01:58:14Z wwccss $ - * @link https://www.zentao.net - */ -?> - - -release->confirmDelete)?> -release->pageAllSummary)?> -release->pageSummary)?> - - -
        - -
        -

        - release->noRelease;?> - - createLink('release', 'create', "productID=$product->id&branch=$branch"), " " . $lang->release->create, '', "class='btn btn-info'");?> - -

        -
        - - - - - - - - - - - - - - release->getFlowExtendFields(); - foreach($extendFields as $extendField) echo ""; - ?> - - - - - loadModel('project'); - $this->loadModel('execution'); - ?> - - - builds);?> - 1 ? "rowspan='{$buildCount}'" : '';?> - - builds = array('');?> - builds as $build):?> - - - - - - - - - - - - - - processStatus('release', $release);?> - - - " . $this->loadModel('flow')->getFieldValue($extendField, $release) . "";?> - - - - - - - -
        release->id;?>release->name;?>release->includedBuild;?>release->branch;?>release->relatedProject;?>release->status;?>release->date;?>{$extendField->name}actions;?>
        >id"), sprintf('%03d', $release->id));?>> - marker ? " " : ''; - echo html::a(inlink('view', "release=$release->id"), $release->name, '', "title='$release->name'") . $flagIcon; - ?> - '> - - type != 'normal'):?> - branchName;?> - - execution ? 'build' : 'projectbuild'; - $canClickable = false; - if($moduleName == 'projectbuild' and $this->project->checkPriv($build->project)) $canClickable = true; - if($moduleName == 'build' and $this->execution->checkPriv($build->execution)) $canClickable = true; - echo $canClickable ? html::a($this->createLink($moduleName, 'view', "buildID=$build->id"), $build->name, '', "data-app='project'") : $build->name; - ?> - - class='c-branch text-center'>branchName; ?>projectName;?>> - - >date;?>>release->buildOperateMenu($release, 'browse');?>
        - - -
        - diff --git a/module/release/view/create.html.php b/module/release/view/create.html.php deleted file mode 100644 index 9c40b3447c..0000000000 --- a/module/release/view/create.html.php +++ /dev/null @@ -1,81 +0,0 @@ - - * @package release - * @version $Id: create.html.php 4728 2013-05-03 06:14:34Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -
        -
        -
        -

        release->create;?>

        -
        -
        - - - - - - - - - - - - - - - - - - - - - - printExtendFields('', 'table');?> - - - - - - - - - - - - - - - - -
        release->name;?> -
        - - -
        - release->last . ': ' . $lastRelease->name . ')';?> -
        release->includedBuild;?>build->placeholder->multipleSelect}'");?> -
        - - -
        -
        release->date;?>
        release->status;?>
        release->desc;?>
        release->mailto;?> -
        - chooseUsersToMail}' multiple");?> -
        -
        files;?>fetch('file', 'buildform');?>
        - - -
        -
        -
        -
        - diff --git a/module/release/view/edit.html.php b/module/release/view/edit.html.php deleted file mode 100644 index 527c9a2857..0000000000 --- a/module/release/view/edit.html.php +++ /dev/null @@ -1,82 +0,0 @@ - - * @package release - * @version $Id: edit.html.php 4728 2013-05-03 06:14:34Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -
        -
        -
        -

        - icons['release']);?> id;?> - id"), $release->name);?> - arrow . ' ' . $lang->release->edit;?> -

        -
        -
        - - - - - - - - - - - - - - - - - - - - printExtendFields($release, 'table');?> - - - - - - - - - - - - - - - - -
        release->name;?>name, "class='form-control' required");?> - marker) ? "checked='checked'" : '';?> -
        - /> - -
        -
        release->includedBuild;?>build, "class='form-control chosen' multiple data-placeholder='{$lang->build->placeholder->multipleSelect}'"); ?>
        release->date;?>date, "class='form-control form-date' required");?>
        release->status;?>release->statusList, $release->status, "class='form-control'");?>
        release->desc;?>desc), "rows=10 class='form-control kindeditor' hidefocus='true'");?>
        release->mailto;?> -
        - mailto, "class='form-control picker-select' data-placeholder='{$lang->chooseUsersToMail}' multiple");?> -
        -
        files;?> - fetch('file', 'printFiles', array('files' => $release->files, 'fieldset' => 'false', 'object' => $release, 'method' => 'edit'));?> - fetch('file', 'buildform');?> -
        - - - product);?> -
        -
        -
        -
        - diff --git a/module/release/view/export.html.php b/module/release/view/export.html.php deleted file mode 100755 index 5baba84757..0000000000 --- a/module/release/view/export.html.php +++ /dev/null @@ -1,55 +0,0 @@ - - * @package file - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -
        -
        -

        export;?>

        -
        -
        - - - - - -
        -
        - setFileName;?> - - .html - release->exportTypeList, 'all', "class='form-control'")?> -
        -
        export, '', 'btn btn-primary');?>
        -
        -
        - diff --git a/module/release/view/linkbug.html.php b/module/release/view/linkbug.html.php deleted file mode 100644 index caa76d1af4..0000000000 --- a/module/release/view/linkbug.html.php +++ /dev/null @@ -1,81 +0,0 @@ - - * @package release - * @version $Id: linkbug.html.php 5096 2013-07-11 07:02:43Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> -
        -bugs : $release->leftBugs; -$formID = $type == 'leftBug' ? 'unlinkedLeftBugsForm' : 'unlinkedBugsForm'; -?> -
        '> -
        id&browseType=$browseType¶m=$param&type=$type")?>' data-ride='table'> -
        - productplan->unlinkedBugs;?> -
        - - - - - - - - - - - - - - - - - - - - - - - - - -
        - -
        - -
        - - idAB;?> -
        pri;?>>priAB;?>bug->title;?>openedByAB;?>bug->resolvedBy;?>statusAB;?>
        - id => sprintf('%03d', $bug->id)), ($type == 'leftBug' or $bug->status == 'resolved' or $bug->status == 'closed') ? $bug->id : '');?> - bug->priList, $bug->pri, $bug->pri)?>createLink('bug', 'view', "bugID=$bug->id", '', true), $bug->title, '', "data-toggle='modal' data-type='iframe' data-width='90%'");?>openedBy);?>resolvedBy);?> - processStatus('bug', $bug);?> -
        - -
        -
        - diff --git a/module/release/view/linkstory.html.php b/module/release/view/linkstory.html.php deleted file mode 100644 index d581c0f7a8..0000000000 --- a/module/release/view/linkstory.html.php +++ /dev/null @@ -1,88 +0,0 @@ - - * @package release - * @version $Id: linkstory.html.php 5096 2013-07-11 07:02:43Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> -
        -
        -
        id&browseType=$browseType¶m=$param")?>' data-ride='table'> -
        - productplan->unlinkedStories;?> -
        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        - -
        - -
        - - idAB;?> -
        pri;?>>priAB;?>story->title;?>openedByAB;?>assignedToAB;?>story->estimateAB;?>statusAB;?>story->stageAB;?>
        -
        - stage, array('developed', 'closed', 'tested'))) echo 'checked';?> /> - -
        - id);?> -
        pri;?>' title='story->priList, $story->pri)?>'>story->priList, $story->pri)?> - parent > 0) echo "{$lang->story->childrenAB}"; - echo html::a($this->createLink('story', 'view', "storyID=$story->id", '', true), $story->title, '', "data-toggle='modal' data-type='iframe' data-width='90%'"); - ?> - openedBy);?>assignedTo);?>estimate . $config->hourUnit;?>processStatus('story', $story);?>story->stageList, $story->stage);?>
        - -
        -
        - diff --git a/module/release/view/notify.html.php b/module/release/view/notify.html.php deleted file mode 100644 index bef6b93337..0000000000 --- a/module/release/view/notify.html.php +++ /dev/null @@ -1,39 +0,0 @@ - - * @package bug - * @version $Id: notify.html.php 4129 2021-12-01 01:58:14Z wwccss $ - * @link https://www.zentao.net - */ -?> - - -
        -
        -
        -

        - id;?> - name . ' - ' . $lang->release->notify;?> -

        -
        -
        - - - - - - id);?> - - - -
        release->notifyUsers;?>release->notifyList, 'FB');?>
        release->notify);?>
        -
        -
        -
        -
        -
        - diff --git a/module/release/view/view.html.php b/module/release/view/view.html.php deleted file mode 100644 index aedd27fc59..0000000000 --- a/module/release/view/view.html.php +++ /dev/null @@ -1,450 +0,0 @@ - - * @package release - * @version $Id: view.html.php 4386 2013-02-19 07:37:45Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -release->confirmUnlinkStory)?> -release->confirmUnlinkBug)?> - -SRCommon);?> -product->checkedSRSummary);?> - - -
        -
        -
        -
        - - -
        -
        ' id='stories'> - -
        id}, \"story\")", ' ' . $lang->release->linkStory, '', "class='btn btn-primary'");?>
        - - -
        ' method='post' id='linkedStoriesForm' data-ride=""> - - - id}&type=story&link=$link¶m=$param&orderBy=%s";?> - - - - - - - - - - - - - - - $story):?> - createLink('story', 'view', "storyID=$story->id", '', true);?> - children)) echo "data-children=" . count($story->children);?> data-cases='id, 0);?>'> - - - - - - - - - - - - -
        - -
        - -
        - - idAB);?> -
        story->title);?>pri;?>>priAB);?> statusAB);?> build->linkedBuild;?> openedByAB);?> story->estimateAB);?> story->stageAB);?>actions?>
        - -
        - - -
        - - id);?> -
        - parent > 0) echo "{$lang->story->childrenAB}"; - echo html::a($storyLink,$story->title, '', "class='preview'"); - ?> - pri;?>' title='story->priList, $story->pri, $story->pri);?>'>story->priList, $story->pri, $story->pri);?> - processStatus('story', $story);?> - buildName?>openedBy);?>estimate . $config->hourUnit;?>story->stageList[$story->stage];?> - createLink('release', 'unlinkStory', "releaseID=$release->id&story=$story->id"); - echo html::a($unlinkURL, '', 'hiddenwin', "class='btn' title='{$lang->release->unlinkStory}'"); - } - ?> -
        - -
        -
        -
        ' id='bugs'> - -
        id}, \"bug\")", ' ' . $lang->release->linkBug, '', "class='btn btn-primary'");?>
        - - - -
        -
        ' id='leftBugs'> - -
        id}, \"leftBug\")", ' ' . $lang->release->linkBug, '', "class='btn btn-primary'");?>
        - - - -
        - -
        ' id='releaseInfo'> -
        -
        -
        release->basicInfo?>
        -
        - - - - - - - - - - - - - - type != 'normal'):?> - - - - - - - - - - - - - - printExtendFields($release, 'table', 'inForm=0');?> - - - - -
        release->product;?>productName;?>
        release->name;?>name;?>
        release->includedBuild;?> - builds as $build) - { - $moduleName = $build->execution ? 'build' : 'projectbuild'; - $canClickable = false; - if($moduleName == 'projectbuild' and $this->loadModel('project')->checkPriv($build->project)) $canClickable = true; - if($moduleName == 'build' and $this->loadModel('execution')->checkPriv($build->execution)) $canClickable = true; - - $buildHtml[] = $canClickable ? html::a($this->createLink($moduleName, 'view', "buildID=$build->id"), $build->name, '', "data-app='project'") : $build->name; - } - echo join($lang->comma, $buildHtml); - ?> -
        release->branch;?> - branches as $branchID) - { - echo zget($branches, $branchID, ''); - if($branchID != end($release->branches)) echo ', '; - } - ?> -
        release->status;?>processStatus('release', $release);?>
        release->date;?>date;?>
        release->desc;?>desc;?>
        -
        -
        -
        -
        files?>
        -
        - files) - { - echo $this->fetch('file', 'printFiles', array('files' => $release->files, 'fieldset' => 'false', 'object' => $release, 'method' => 'view', 'showDelete' => false)); - } - if($release->builds) - { - foreach($release->builds as $build) - { - if($build->filePath) - { - echo $lang->release->filePath . html::a($release->filePath, $release->filePath, '_blank'); - } - elseif($build->scmPath) - { - echo $lang->release->scmPath . html::a($release->scmPath, $release->scmPath, '_blank'); - } - } - } - ?> -
        -
        - -
        -
        -
        -
        -
        -
        -
        - - - -id)?> - - diff --git a/module/repo/control.php b/module/repo/control.php index 813a4c6a4e..2b13d2061e 100644 --- a/module/repo/control.php +++ b/module/repo/control.php @@ -1919,6 +1919,7 @@ class repo extends control * @param int $repoID * @param int $objectID * @param string $label + * @param int $showArchived * @param string $keyword * @param string $orderBy * @param int $recTotal @@ -1927,7 +1928,7 @@ class repo extends control * @access public * @return void */ - public function browseBranch(int $repoID, int $objectID = 0, string $label = 'all', string $keyword = '', string $orderBy = 'date_desc', int $recTotal = 0, int $recPerPage = 20, int $pageID = 1) + public function browseBranch(int $repoID, int $objectID = 0, string $label = 'all', int $showArchived = 0, string $keyword = '', string $orderBy = 'date_desc', int $recTotal = 0, int $recPerPage = 20, int $pageID = 1) { $repoID = $this->repoZen->processRepoID($repoID, $objectID); $this->commonAction($repoID, $objectID); @@ -1939,8 +1940,8 @@ class repo extends control $keyword = htmlspecialchars(base64_decode($keyword)); $this->scm->setEngine($repo); - $branchList = $this->scm->branch($keyword ? $keyword : 'all', $orderBy, $recPerPage, $pageID, $label); - if(count($branchList) == 0 && $pageID != 1) $this->locate(inLink('browseBranch', "repoID=$repoID&objectID=$objectID&label=$label&keyword=$keyword&orderBy=$orderBy&recTotal=0&recPerPage=$recPerPage&pageID=1")); + $branchList = $this->scm->branch($keyword ? $keyword : 'all', $orderBy, $recPerPage, $pageID, $label, $showArchived); + if(count($branchList) == 0 && $pageID != 1) $this->locate(inLink('browseBranch', "repoID=$repoID&objectID=$objectID&label=$label&showArchived=$showArchived&keyword=$keyword&orderBy=$orderBy&recTotal=0&recPerPage=$recPerPage&pageID=1")); $this->app->loadClass('pager', true); $pager = new pager($recTotal, $recPerPage, $pageID); @@ -1969,16 +1970,17 @@ class repo extends control $branch->behind = isset($branch->divergence->behind) ? $branch->divergence->behind : 0; } - $this->view->title = $this->lang->repo->browseBranch; - $this->view->repoID = $repoID; - $this->view->objectID = $objectID; - $this->view->repo = $repo; - $this->view->pager = $pager; - $this->view->orderBy = $orderBy; - $this->view->branchList = $branchList; - $this->view->keyword = base64_encode($keyword); - $this->view->users = $this->user->getPairs('noletter'); - $this->view->label = $label; + $this->view->title = $this->lang->repo->browseBranch; + $this->view->repoID = $repoID; + $this->view->objectID = $objectID; + $this->view->repo = $repo; + $this->view->pager = $pager; + $this->view->orderBy = $orderBy; + $this->view->branchList = $branchList; + $this->view->keyword = base64_encode($keyword); + $this->view->users = $this->user->getPairs('noletter'); + $this->view->label = $label; + $this->view->showArchived = $showArchived; $this->display(); } diff --git a/module/repo/ui/browsebranch.html.php b/module/repo/ui/browsebranch.html.php index 4ef1322760..7bf4ee5eaf 100644 --- a/module/repo/ui/browsebranch.html.php +++ b/module/repo/ui/browsebranch.html.php @@ -10,7 +10,7 @@ declare(strict_types=1); */ namespace zin; -jsVar('searchUrl', createLink('repo', 'browsebranch', "repoID={$repo->id}&objectID={$objectID}&label={$label}&keyword=%s")); +jsVar('searchUrl', createLink('repo', 'browsebranch', "repoID={$repo->id}&objectID={$objectID}&label={$label}&showArchived={$showArchived}&keyword=%s")); $module = $app->tab == 'devops' ? 'repo' : $app->tab; dropmenu ( @@ -50,14 +50,15 @@ $config->repo->dtable->branch->fieldList['committer']['map'] = $users; if(!hasPriv('repo', 'revision')) unset($config->repo->dtable->branch->fieldList['commitID']['link']); $branchList = initTableData($branchList, $config->repo->dtable->branch->fieldList); $urlParams = array( - 'repoID' => $repo->id, - 'objectID' => $objectID, - 'label' => $label, - 'keyword' => urlencode($keyword), - 'orderBy' => '{name}_{sortType}', - 'recTotal' => $pager->recTotal, - 'recPerPage' => $pager->recPerPage, - 'pageID' => $pager->pageID + 'repoID' => $repo->id, + 'objectID' => $objectID, + 'label' => $label, + 'showArchived' => $showArchived, + 'keyword' => urlencode($keyword), + 'orderBy' => '{name}_{sortType}', + 'recTotal' => $pager->recTotal, + 'recPerPage' => $pager->recPerPage, + 'pageID' => $pager->pageID ); dtable ( diff --git a/module/repo/view/blame.html.php b/module/repo/view/blame.html.php deleted file mode 100644 index 5873de2b09..0000000000 --- a/module/repo/view/blame.html.php +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - -
        -
        -
        - repo->encodePath($entry);?> -
        -
        - repo->encodingList, $encoding, $lang->repo->encoding) . "", "id='encoding' data-toggle='dropdown'", 'btn dropdown-toggle')?> - -
        -
        -
        -
        - - - - - SCM != 'Subversion'):?> - - - - - - - - - - > - '; - echo $repo->SCM != 'Subversion' ? substr($blame['revision'], 0, 10) : $blame['revision']; - echo ''; - if($repo->SCM != 'Subversion') echo ''; - echo ''; - } - ?> - - - - - -
        repo->revision?>repo->commit?>repo->committer?>repo->line?>repo->code?>
        ' . zget($historys, $blame['revision'], '') . '' . $blame['committer'] . '
        -
        -
        - diff --git a/module/repo/view/browse.html.php b/module/repo/view/browse.html.php deleted file mode 100644 index fe1d0ec2ae..0000000000 --- a/module/repo/view/browse.html.php +++ /dev/null @@ -1,140 +0,0 @@ - - - - -repo);?> - - - -
        -
        - - - - - - - - - - - - - name)) continue;?> - - - - - - comment, ENT_QUOTES);?> - - - - -
        repo->name?>repo->revisions?>repo->time?>repo->committer?>repo->comment?>
        - - name, '/'); - $link = $info->kind == 'dir' ? $this->repo->createLink('browse', "repoID=$repoID&branchID=$base64BranchID&objectID=$objectID&path=" . $this->repo->encodePath($infoPath)) : $this->repo->createLink('view', "repoID=$repoID&objectID=$objectID&entry=" . $this->repo->encodePath($infoPath)); - echo html::a($link, $info->name, '', "title='{$info->name}' data-app={$app->tab}"); - ?> - SCM == 'Subversion' ? $info->revision : substr($info->revision, 0, 10);?>date, 0, 10)?>account?>
        -
        - -
        - diff --git a/module/repo/view/create.html.php b/module/repo/view/create.html.php deleted file mode 100644 index 1d9a69a2ed..0000000000 --- a/module/repo/view/create.html.php +++ /dev/null @@ -1,121 +0,0 @@ - - - - - - - - -
        -
        -
        -
        -

        repo->createAction;?>

        -
        -
        - - app->tab == 'project' or $this->app->tab == 'execution'):?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        repo->product;?>
        repo->projects;?>
        repo->type;?>repo->scmList, 'Gitlab', "onchange='scmChanged(this.value)' class='form-control chosen'");?>repo->syncTips;?>
        repo->serviceHost;?>
        repo->serviceProject;?>
        repo->name;?>
        repo->path;?> - repo->example->path->git;?> - repo->example->path->svn;?> -
        repo->encoding; ?>repo->encodingsTips;?>
        repo->client;?> - repo->example->client->git;?> - repo->example->client->svn;?> -
        repo->acl;?> -
        - repo->group?> - -
        -
        - repo->user;?> - -
        -
        repo->desc; ?>
        - - - app->tab == 'devops') echo html::a(inlink('maintain', ""), $lang->goback, '', 'class="btn btn-wide"');?> - app->tab == 'project') echo html::a("javascript: parent.window.history.back();", $lang->goback, '', 'class="btn btn-wide"');?> - -
        -
        -
        -
        -
        - diff --git a/module/repo/view/diff.html.php b/module/repo/view/diff.html.php deleted file mode 100644 index efe70661d2..0000000000 --- a/module/repo/view/diff.html.php +++ /dev/null @@ -1,184 +0,0 @@ - - - - -edition); -?> - - - - -
        -
        -
        -
        - repo->viewDiffList['inline'], "id='inline'", $arrange == 'inline' ? 'active btn btn-sm' : 'btn btn-sm')?> - repo->viewDiffList['appose'], "id='appose'", $arrange == 'appose' ? 'active btn btn-sm' : 'btn btn-sm')?> -
        -
        -
        - repo->createLink('download', "repoID=$repoID&path=" . $this->repo->encodePath($entry) . "&fromRevison=$oldRevision&toRevision=$newRevision&type=path"), $lang->repo->downloadDiff, 'hiddenwin', "class='btn btn-sm btn-download'");?> -
        - repo->encodingList, $encoding, $lang->repo->encoding) . "", "data-toggle='dropdown'", 'btn dropdown-toggle btn-sm')?> - -
        -
        -
        - -
        -
        - -
        - - - contents)) continue;?> - contents as $content):?> - oldStartLine; - $newCurrentLine = $content->newStartLine; - ?> - - - - - - - - - - - - lines as $line):?> - - - - - - - - lines as $line):?> - - type == 'old') - { - $oldlc = $line->oldlc; - $newlc = ''; - if(isset($content->new[$oldlc]) and !isset($content->new[$oldlc - 1])) - { - $newlc = $line->oldlc; - $line->type = 'custom'; - } - } - else - { - $oldlc = $line->oldlc > 0 ? $line->oldlc : ' '; - $newlc = $line->newlc; - if(!isset($content->new[$newlc])) continue; - } - ?> - - - - - old[$oldlc])) unset($content->old[$oldlc]); - if(isset($content->new[$newlc])) unset($content->new[$newlc]); - ?> - - - - -
        fileName;?>
        ......
        type != 'new' and $line->oldlc) echo $line->oldlc?>type != 'old' and $line->newlc) echo $line->newlc?>line = $repo->SCM == 'Subversion' ? htmlSpecialString($line->line) : $line->line; - echo $line->type == 'old' ? preg_replace('/^\-/', '–', $line->line) : ($line->type == 'new' ? $line->line : ' ' . $line->line); - ?>
        type?> type == 'custom') echo "line-old"?> code'>old[$oldlc])) $content->old[$oldlc] = ''; - $content->old[$oldlc] = $repo->SCM == 'Subversion' ? htmlSpecialString($content->old[$oldlc]) : $content->old[$oldlc]; - if(!empty($oldlc)) echo $line->type != 'all' ? preg_replace('/^\-/', '–', $content->old[$oldlc]) : ' ' . $content->old[$oldlc]; - ?>type?> type == 'custom') echo "line-new"?> code'>new[$newlc])) $content->new[$newlc] = ''; - $content->new[$newlc] = $repo->SCM == 'Subversion' ? htmlSpecialString($content->new[$newlc]) : $content->new[$newlc]; - if(!empty($newlc)) echo $line->type != 'all' ? $content->new[$newlc] : ' ' . $content->new[$newlc]; - ?>
        -
        - -
        - - - - - - diff --git a/module/repo/view/diffeditor.html.php b/module/repo/view/diffeditor.html.php deleted file mode 100644 index 36241af861..0000000000 --- a/module/repo/view/diffeditor.html.php +++ /dev/null @@ -1,54 +0,0 @@ -fileName : ''; -$file = $entry ? pathinfo($entry) : array(); -$showBug = isset($showBug) ? $showBug : true; -$objectID = isset($objectID) ? $objectID : 0; - -js::set('diffs', $diffs); -js::set('file', $file); -js::set('entry', $entry); -js::set('openedFiles', array($entry)); -js::set('isonlybody', isonlybody()); -js::set('urlParams', "repoID=$repoID&objectID=$objectID&entry=%s&oldRevision=$oldRevision&newRevision=$newRevision&showBug=$showBug&encoding=$encoding"); -?> - -
        - - - -
        -
        -
        - -
        - -
        - -
        -
        -
        -
        -
        -
        - -
        - - diff --git a/module/repo/view/edit.html.php b/module/repo/view/edit.html.php deleted file mode 100644 index 27fa282208..0000000000 --- a/module/repo/view/edit.html.php +++ /dev/null @@ -1,120 +0,0 @@ - - * @package repo - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - - - - - -SCM);?> - -
        -
        -
        -
        -

        repo->edit;?>

        -
        -
        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        repo->product;?>product, "class='form-control chosen' multiple");?>
        repo->projects;?>projects, "class='form-control chosen' multiple");?>
        repo->type;?>repo->scmList, $repo->SCM, "onchange='scmChanged(this.value)' class='form-control chosen'");?>repo->syncTips;?>
        repo->serviceHost;?>gitService) ? $repo->gitService : '', "class='form-control chosen'");?>
        repo->serviceProject;?>project) ? $repo->project : '', "class='form-control chosen'");?>
        repo->name; ?>name, "class='form-control'");?>
        repo->path;?>path, "class='form-control'");?> - repo->example->path->git;?> - repo->example->path->svn;?> -
        repo->encoding;?>encoding, "class='form-control'");?>repo->encodingsTips;?>
        repo->client;?>client, "class='form-control'");?> - repo->example->client->git;?> - repo->example->client->svn;?> -
        repo->acl;?> -
        - repo->group;?> - acl->groups) ? '' : join(',', $repo->acl->groups), "class='form-control picker-select' multiple");?> -
        -
        - repo->user;?> - acl->users) ? '' : join(',', $repo->acl->users), "class='form-control picker-select' multiple");?> -
        -
        repo->desc;?>desc, "rows='3' class='form-control'");?>
        - - goback, '', 'class="btn btn-wide"');?> -
        -
        -
        -
        -
        - diff --git a/module/repo/view/import.html.php b/module/repo/view/import.html.php deleted file mode 100644 index 3b6c8be869..0000000000 --- a/module/repo/view/import.html.php +++ /dev/null @@ -1,65 +0,0 @@ - - * @package repo - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -
        -
        - id);?> - - - - - - - - - - - - $repo): ?> - - - - - - - - - - - - - - -
        repo->gitlabList;?>repo->importName;?>repo->product;?>repo->projects;?>
        - id);?> - name_with_namespace;?> - - name, "class='form-control'");?> -
        - repo->import); ?> - - app->tab == 'devops') echo html::a(inlink('maintain', ""), $lang->goback, '', 'class="btn btn-wide"');?> - -
        -
        -
        - diff --git a/module/repo/view/linkbug.html.php b/module/repo/view/linkbug.html.php deleted file mode 100644 index 1f6978ce17..0000000000 --- a/module/repo/view/linkbug.html.php +++ /dev/null @@ -1,90 +0,0 @@ - - * @package mr - * @version $Id: linkbug.html.php$ - * @link https://www.zentao.net - */ -?> - - - - -
        -
        -

        repo->linkBug;?>

        -
        -
        -
        -
        '> -
        - productplan->unlinkedBugs;?> -
        - - - - - - - - - - - - - - - - - - - - - - - - - -
        - -
        - -
        - - idAB;?> -
        pri;?>>priAB;?>bug->title;?>openedByAB;?>bug->assignedToAB;?>bug->status;?>
        - id => sprintf('%03d', $bug->id)));?> - bug->priList, $bug->pri, $bug->pri)?>createLink('bug', 'view', "bugID=$bug->id", '', true), $bug->title, '', "data-toggle='modal' data-type='iframe' data-width='90%'");?>openedBy);?>assignedTo);?> - - processStatus('bug', $bug);?> - -
        - -
        - -
        -
        - diff --git a/module/repo/view/linkstory.html.php b/module/repo/view/linkstory.html.php deleted file mode 100644 index 929e54359f..0000000000 --- a/module/repo/view/linkstory.html.php +++ /dev/null @@ -1,100 +0,0 @@ - - - - - -
        -
        -

        repo->linkStory;?>

        -
        -
        -
        "> -
        - productplan->unlinkedStories;?> -
        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        - -
        - -
        - - idAB;?> -
        pri;?>>priAB;?>story->plan;?>story->module;?>story->title;?>openedByAB;?>assignedToAB;?>story->estimateAB;?>statusAB;?>story->stageAB;?>
        - id => sprintf('%03d', $story->id)));?> - pri;?>' title='story->priList, $story->pri, $story->pri)?>'>story->priList, $story->pri, $story->pri)?>planTitle;?>' class='text-left'>module, '/');?> - parent > 0) echo "story->children}>{$lang->story->childrenAB}"; - echo html::a($this->createLink('story', 'view', "storyID=$story->id", '', true), $story->title, '', "data-toggle='modal' data-type='iframe' data-width='90%'"); - ?> - openedBy);?>assignedTo);?>estimate . $config->hourUnit;?> - - processStatus('story', $story);?> - - story->stageList[$story->stage];?>
        - -
        - -
        - diff --git a/module/repo/view/linktask.html.php b/module/repo/view/linktask.html.php deleted file mode 100644 index f42008bf68..0000000000 --- a/module/repo/view/linktask.html.php +++ /dev/null @@ -1,90 +0,0 @@ - - * @package repo - * @version $Id: linktask.html.php$ - * @link https://www.zentao.net - */ -?> - - - - -
        -
        -

        repo->linkTask;?>

        -
        -
        -
        -
        '> -
        - repo->unlinkedTasks;?> -
        - - - - - - - - - - - - - - - - - - - - - - - - - -
        - -
        - -
        - - idAB;?> -
        pri;?>>priAB;?>task->name;?>task->finishedByAB;?>task->assignedToAB;?>task->status;?>
        - id => sprintf('%03d', $task->id)));?> - task->priList, $task->pri, $task->pri)?>createLink('task', 'view', "taskID=$task->id", '', true), $task->name, '', "data-toggle='modal' data-type='iframe' data-width='90%'");?>finishedBy);?>assignedTo);?> - - processStatus('task', $task);?> - -
        - -
        - -
        -
        - diff --git a/module/repo/view/log.html.php b/module/repo/view/log.html.php deleted file mode 100644 index bc7113c892..0000000000 --- a/module/repo/view/log.html.php +++ /dev/null @@ -1,97 +0,0 @@ - - - -repo->encodePath($entry) . "&revision=$revision&type=$type");?> - - -
        - -
        - - - - - - SCM != 'Subversion'):?> - - - - - - - - - - - - - SCM != 'Subversion'):?> - - - - - - - - -
        repo->revision?>repo->commit?>repo->date?>repo->committer?>repo->comment?>
        -
        - - -
        -
        repo->createLink('revision', "repoID=$repoID&objectID=$objectID&revision=" . $log->revision), substr($log->revision, 0, 10), '', "data-app='{$app->tab}'");?>commit?>time;?>committer;?>comment;?>
        - -
        -
        - diff --git a/module/repo/view/maintain.html.php b/module/repo/view/maintain.html.php deleted file mode 100644 index f896e31c27..0000000000 --- a/module/repo/view/maintain.html.php +++ /dev/null @@ -1,84 +0,0 @@ - - * @package repo - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -
        -
        - - - - recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}"; ?> - - - - - - - - - - - - - - - product)); - if(isset($productList) and $productList[0]) - { - foreach($productList as $productID) - { - if(!isset($products[$productID])) continue; - $productNames .= ' ' . zget($products, $productID, $productID); - } - } - ?> - - - - - - -
        repo->id); ?>repo->type); ?>repo->name); ?>repo->product); ?>repo->path; ?>actions;?>
        id; ?>repo->scmList, $repo->SCM); ?>createLink('repo', 'browse', "repoID={$repo->id}&branchID=&objectID=$objectID"), $repo->name);?>codePath;?> - id&objectID=$objectID", '', 'list', 'edit'); - - $jobID = 0; - $execClass = 'disabled'; - $reportClass = 'disabled'; - if(isset($sonarRepoList[$repo->id])) - { - $execClass = ''; - $jobID = $sonarRepoList[$repo->id]->id; - if(in_array($jobID, $successJobs)) $reportClass = ''; - } - common::printIcon('sonarqube', 'execJob', "jobID=$jobID", '', 'list', 'sonarqube', 'hiddenwin', $execClass); - common::printIcon('sonarqube', 'reportView', "jobID=$jobID", '', 'list', 'audit', '', "iframe $reportClass", true); - common::printIcon('repo', 'delete', "repoID=$repo->id&objectID=$objectID", '', 'list', 'trash', 'hiddenwin'); - ?> -
        - - - -
        -
        - diff --git a/module/repo/view/monaco.html.php b/module/repo/view/monaco.html.php deleted file mode 100644 index 6a024ce638..0000000000 --- a/module/repo/view/monaco.html.php +++ /dev/null @@ -1,84 +0,0 @@ - -repo->encodePath($entry); -?> - -
        - - - -
        -
        -
        - -
        - - - -
        - -
        -
        -
        -
        -
        -
        - -
        - - - diff --git a/module/repo/view/setrules.html.php b/module/repo/view/setrules.html.php deleted file mode 100644 index 0dca729bb1..0000000000 --- a/module/repo/view/setrules.html.php +++ /dev/null @@ -1,103 +0,0 @@ - - * @package repo - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
        -
        -

        repo->setRules;?>

        -
        -
        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        repo->objectRule;?> -
        - repo->rules['module'] as $module => $match):?> - {$module}->common;?> - - -
        -
        repo->objectIdRule;?> -
        - repo->rules['id'] as $method => $match):?> - repo->$method;?> - - -
        -
        repo->actionRule;?> -
        - - task->common . $space . $lang->task->start;?> - repo->rules['task']['start'], "class='form-control'");?> - task->common . $space . $lang->task->finish;?> - repo->rules['task']['finish'], "class='form-control'");?> - bug->common . $space . $lang->bug->resolve;?> - repo->rules['bug']['resolve'], "class='form-control'");?> -
        -
        repo->manHourRule;?> -
        - task->common . $space . $lang->task->logEfforts;?> - repo->rules['task']['logEfforts'], "class='form-control'");?> -
        -
        - task->consumed?> - repo->rules['task']['consumed'], "class='form-control'");?> - repo->mark?> - repo->rules['mark']['consumed'], "class='form-control'");?> - repo->ruleUnit?> - repo->rules['unit']['consumed'], "class='form-control'");?> -
        -
        - task->left?> - repo->rules['task']['left'], "class='form-control'");?> - repo->mark?> - repo->rules['mark']['left'], "class='form-control'");?> - repo->ruleUnit?> - repo->rules['unit']['left'], "class='form-control'");?> -
        -
        repo->ruleSplit;?>
        repo->rules->exampleLabel;?>
        - -
        -
        -
        -repo->rules->example);?> - diff --git a/module/repo/view/showsynccommit.html.php b/module/repo/view/showsynccommit.html.php deleted file mode 100644 index 591f7a07dc..0000000000 --- a/module/repo/view/showsynccommit.html.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @package repo - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
        -
        -
        - -
        -

        repo->notice->syncing;?>

        -
        -

        repo->notice->syncedCount?>

        -
        -
        -
        -
        - - diff --git a/module/report/test/lib/report.unittest.class.php b/module/report/test/lib/report.unittest.class.php index 5cf98d2e18..8e13dda6ee 100644 --- a/module/report/test/lib/report.unittest.class.php +++ b/module/report/test/lib/report.unittest.class.php @@ -32,11 +32,11 @@ class reportTest * 测试为单个图表创建json数据。 * Test create json data of single charts. * - * @param int $executionID + * @param int $executionID * @access public - * @return string|array + * @return bool|array */ - public function createSingleJSONTest(int $executionID): string|array + public function createSingleJSONTest(int $executionID): bool|array { global $tester; $this->execution = $tester->loadModel('execution'); @@ -49,7 +49,7 @@ class reportTest if(dao::isError()) return dao::getError(); - return implode(',', $objects); + return !empty($objects); } /** diff --git a/module/report/test/model/createsinglejson.php b/module/report/test/model/createsinglejson.php index 9ea7f71f4f..1d2f123394 100755 --- a/module/report/test/model/createsinglejson.php +++ b/module/report/test/model/createsinglejson.php @@ -1,6 +1,17 @@ #!/usr/bin/env php createSingleJSON(); +cid=1 + +- 测试获取执行 101 的json数据 @1 +- 测试获取执行 102 的json数据 @1 +- 测试获取执行 103 的json数据 @1 +- 测试获取执行 104 的json数据 @1 +- 测试获取执行 105 的json数据 @1 + +*/ include dirname(__FILE__, 5) . '/test/lib/init.php'; include dirname(__FILE__, 2) . '/lib/report.unittest.class.php'; @@ -8,32 +19,13 @@ zenData('project')->loadYaml('execution')->gen('100'); zenData('burn')->loadYaml('burn')->gen('100'); zenData('task')->loadYaml('task')->gen('100'); zenData('user')->gen(1); - su('admin'); -/** - -title=测试 reportModel->createSingleJSON(); -cid=1 - -- 测试获取执行 101 的json数据 @0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2 - -- 测试获取执行 102 的json数据 @0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2 - -- 测试获取执行 103 的json数据 @0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2 - -- 测试获取执行 104 的json数据 @0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2 - -- 测试获取执行 105 的json数据 @0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2 - -*/ - -$report = new reportTest(); - +$report = new reportTest(); $executionID = array(101, 102, 103, 104, 105); -r($report->createSingleJSONTest($executionID[0])) && p() && e('0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2'); // 测试获取执行 101 的json数据 -r($report->createSingleJSONTest($executionID[1])) && p() && e('0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2'); // 测试获取执行 102 的json数据 -r($report->createSingleJSONTest($executionID[2])) && p() && e('0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2'); // 测试获取执行 103 的json数据 -r($report->createSingleJSONTest($executionID[3])) && p() && e('0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2'); // 测试获取执行 104 的json数据 -r($report->createSingleJSONTest($executionID[4])) && p() && e('0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2'); // 测试获取执行 105 的json数据 +r($report->createSingleJSONTest($executionID[0])) && p() && e('1'); // 测试获取执行 101 的json数据 +r($report->createSingleJSONTest($executionID[1])) && p() && e('1'); // 测试获取执行 102 的json数据 +r($report->createSingleJSONTest($executionID[2])) && p() && e('1'); // 测试获取执行 103 的json数据 +r($report->createSingleJSONTest($executionID[3])) && p() && e('1'); // 测试获取执行 104 的json数据 +r($report->createSingleJSONTest($executionID[4])) && p() && e('1'); // 测试获取执行 105 的json数据 diff --git a/module/score/view/rule.html.php b/module/score/view/rule.html.php deleted file mode 100644 index 91d7b7d6a3..0000000000 --- a/module/score/view/rule.html.php +++ /dev/null @@ -1,76 +0,0 @@ - - * @package score - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -
        - - - - - - - - - - - - - score->rule as $module => $moduleRule):?> - $rule):?> - - - - - - - score->extended[$module][$method])) - { - $desc = $lang->score->extended[$module][$method]; - $descRule = explode('##', $desc); - if(!empty($descRule)) - { - foreach($descRule as $key => $value) - { - if($key % 2 == 1) - { - $match = explode(',', $value); - if(count($match) == 2) - { - $score = $config->score->ruleExtended[$module][$method][$match[0]][$match[1]]; - } - else - { - $score = $config->score->ruleExtended[$module][$method][$match[0]]; - } - $desc = str_replace('##' . $value . '##', $score, $desc); - } - } - } - } - ?> - - - - - -
        score->module;?>score->method;?>score->times;?>score->hour;?>score->score;?>score->desc;?>
        score->modules[$module];?>score->methods[$module][$method];?>score->noLimit : $rule['times'];?>score->noLimit : $rule['hour'];?>
        -
        - diff --git a/module/screen/test/model/getburndata.php b/module/screen/test/model/getburndata.php index 14a12e21c2..dffe6699a2 100755 --- a/module/screen/test/model/getburndata.php +++ b/module/screen/test/model/getburndata.php @@ -24,4 +24,4 @@ $screen = new screenTest(); $data = $screen->getBurnDataTest(); r(count($data)) && p('') && e(16); //测试生成的数据条数 -r($data) && p('104:name') && e('项目集1--项目集4'); //测试生成的数据是否正确 \ No newline at end of file +r($data) && p('104:name') && e('项目11--项目集4'); //测试生成的数据是否正确 \ No newline at end of file diff --git a/module/screen/test/model/getsysoptions.php b/module/screen/test/model/getsysoptions.php index 8f023e8861..674fea5c2c 100755 --- a/module/screen/test/model/getsysoptions.php +++ b/module/screen/test/model/getsysoptions.php @@ -63,7 +63,7 @@ $sqlList = array('', '', '', '', '', '', r($screen->getSysOptionsTest($typeList[0], $objectList[0], $fieldList[0], $sqlList[0])) && p('admin,closed') && e('A:admin,Closed'); //测试type为user,对象类型为空,字段为空,sql为空的情况下,用户列表获取是否正确。 r($screen->getSysOptionsTest($typeList[1], $objectList[1], $fieldList[1], $sqlList[1])) && p('1,10') && e('正常产品1,正常产品10'); //测试type为product,对象类型为空,字段为空,sql为空的情况下,产品列表获取是否正确。 -r($screen->getSysOptionsTest($typeList[2], $objectList[2], $fieldList[2], $sqlList[2])) && p('11,20') && e('项目集1,项目集10'); //测试type为project,对象类型为空,字段为空,sql为空的情况下,项目列表获取是否正确。 +r($screen->getSysOptionsTest($typeList[2], $objectList[2], $fieldList[2], $sqlList[2])) && p('11,20') && e('项目11,项目20'); //测试type为project,对象类型为空,字段为空,sql为空的情况下,项目列表获取是否正确。 r($screen->getSysOptionsTest($typeList[3], $objectList[3], $fieldList[3], $sqlList[3])) && p('101,110') && e('/项目集1,/项目集10'); //测试type为execution,对象类型为空,字段为空,sql为空的情况下,执行列表获取是否正确。 r($screen->getSysOptionsTest($typeList[4], $objectList[4], $fieldList[4], $sqlList[4])) && p('1,10') && e('/产品部1,/一级部门10'); //测试type为dept,对象类型为空,字段为空,sql为空的情况下,部门列表获取是否正确。 r($screen->getSysOptionsTest($typeList[5], $objectList[5], $fieldList[5], $sqlList[5])) && p('wait,doing,suspended,closed,delay') && e('未开始,进行中,已挂起,已关闭,已延期'); //测试type为dept,对象类型为空,字段为空,sql为空的情况下,项目状态获取是否正确。 diff --git a/module/screen/view/browse.html.php b/module/screen/view/browse.html.php deleted file mode 100644 index 27ee0b5b60..0000000000 --- a/module/screen/view/browse.html.php +++ /dev/null @@ -1,70 +0,0 @@ -getModuleRoot() . 'common/view/header.html.php';?> -config->edition == 'open'):?> - - - - - - -getModuleRoot() . 'common/view/footer.html.php';?> diff --git a/module/search/control.php b/module/search/control.php index 66ad4ac0f6..38f59eeca6 100644 --- a/module/search/control.php +++ b/module/search/control.php @@ -30,8 +30,8 @@ class search extends control $searchForm = $module . 'Form'; $searchParams = $module . 'searchParams'; $searchConfig = $this->search->processSearchParams($module); - $fields = $searchConfig['fields']; - $params = $searchConfig['params']; + $fields = $searchConfig['fields'] ?? []; + $params = $searchConfig['params'] ?? []; if(!$this->session->$searchForm) { diff --git a/module/search/model.php b/module/search/model.php index 573627d753..51a34056cb 100644 --- a/module/search/model.php +++ b/module/search/model.php @@ -28,7 +28,7 @@ class searchModel extends model $funcModel = $this->session->$cacheKey['funcModel'] ?? ''; $funcName = $this->session->$cacheKey['funcName'] ?? ''; $funcArgs = $this->session->$cacheKey['funcArgs'] ?? []; - if(!$funcModel || !$funcName || !$funcArgs) return $this->session->{$module . 'searchParams'} ?? []; + if(!$funcModel || !$funcName || !$funcArgs) return $_SESSION[$module . 'searchParams'] ?? []; $funcArgs['cacheSearchFunc'] = $cacheSearchFunc; return $this->loadModel($funcModel)->$funcName(...array_values($funcArgs)); // PHP 8.0以下只能展开索引数组。PHP 8.0 below can only unpack indexed arrays. @@ -122,8 +122,8 @@ class searchModel extends model /* Init vars. */ $module = $this->post->module; $searchConfig = $this->processSearchParams($module, true); - $searchFields = $searchConfig['fields']; - $fieldParams = $searchConfig['params']; + $searchFields = $searchConfig['fields'] ?? [] ; + $fieldParams = $searchConfig['params'] ?? []; $groupItems = $this->config->search->groupItems; $groupAndOr = strtoupper($this->post->groupAndOr); if($groupAndOr != 'AND' && $groupAndOr != 'OR') $groupAndOr = 'AND'; @@ -195,7 +195,7 @@ class searchModel extends model $groupAndOr = strtoupper($this->post->groupAndOr); $module = $this->post->module; $searchConfig = $this->processSearchParams($module, true); - $fieldParams = $searchConfig['params']; + $fieldParams = $searchConfig['params'] ?? []; $scoreNum = 0; if($groupAndOr != 'AND' and $groupAndOr != 'OR') $groupAndOr = 'AND'; @@ -523,6 +523,8 @@ class searchModel extends model ->remove('onMenuBar') ->get(); if($this->post->onMenuBar) $query->shortcut = '1'; + if(in_array($query->module, array('epic', 'requirement'))) $query->module = 'story'; // 用需业需保存为story + $this->dao->insert(TABLE_USERQUERY)->data($query)->autoCheck()->check('title', 'notempty')->exec(); if(dao::isError()) return false; @@ -627,6 +629,9 @@ class searchModel extends model */ public function getList(string $keywords, array|string $type, ?object $pager = null): array { + $filter = $this->app->loadClass('sqlfilter'); + $keywords = $filter->getRecommendedFilter($keywords, 'medium'); + list($words, $againstCond, $likeCondition) = $this->searchTao->getSqlParams($keywords); $allowedObjects = $this->searchTao->getAllowedObjects($type); @@ -639,9 +644,9 @@ class searchModel extends model $filterObjects[] = $object; } - $scoreColumn = "(MATCH(title, content) AGAINST('{$againstCond}' IN BOOLEAN MODE))"; - $stmt = $this->dao->select("*, {$scoreColumn} as score")->from(TABLE_SEARCHINDEX) - ->where("(MATCH(title,content) AGAINST('{$againstCond}' IN BOOLEAN MODE) >= 1 {$likeCondition})") + $table = "SELECT *, (MATCH(title, content) AGAINST('{$againstCond}' IN BOOLEAN MODE)) AS score FROM " . TABLE_SEARCHINDEX; + $stmt = $this->dao->select('*')->from("({$table})")->alias('t1') + ->where("(score >= 1 {$likeCondition})") ->andWhere('((vision')->eq($this->config->vision) ->andWhere('objectType')->in($allowedObjects) ->markRight(1) diff --git a/module/search/tao.php b/module/search/tao.php index 2501b997b8..8ec532ecc2 100644 --- a/module/search/tao.php +++ b/module/search/tao.php @@ -411,7 +411,7 @@ class searchTao extends searchModel if(is_numeric($word) && strpos($word, '.') === false && strlen($word) == 5) $againstCond .= "(-\" $word \") "; } - $likeCondition = trim($keywords) ? "OR title like '%{$keywords}%' OR content like '%{$keywords}%'" : ''; + $likeCondition = trim($keywords) ? 'OR title LIKE ' . $this->dbh->quote("%{$keywords}%") . ' OR content LIKE ' . $this->dbh->quote("%{$keywords}%") : ''; $words = str_replace('"', '', $against); $words = str_pad($words, 5, '_'); diff --git a/module/search/test/lib/search.unittest.class.php b/module/search/test/lib/search.unittest.class.php index a8754ad501..d0354966cb 100755 --- a/module/search/test/lib/search.unittest.class.php +++ b/module/search/test/lib/search.unittest.class.php @@ -65,7 +65,7 @@ class searchTest * 测试生成查询表单数据。 * Process query form datas test. * - * @param object $fieldParams + * @param array $fieldParams * @param string $field * @param string $andOrName * @param string $operatorName @@ -73,23 +73,11 @@ class searchTest * @access public * @return object */ - public function processQueryFormDatasTest(object $postData, string $field, string $andOrName, string $operatorName, string $valueName): object + public function processQueryFormDatasTest(array $fieldParams, string $field, string $andOrName, string $operatorName, string $valueName): array { - $_POST = (array)$postData; + $_POST = $fieldParams; - global $tester; - $tester->loadModel('bug'); - - $fieldParams = json_decode(json_encode($tester->config->bug->search['params'])); - - list($andOr, $operator, $value) = $this->objectModel->processQueryFormDatas($fieldParams, $field, $andOrName, $operatorName, $valueName); - - $queryFormData = new stdclass(); - $queryFormData->andOr = $andOr; - $queryFormData->operator = $operator; - $queryFormData->value = $value; - - return $queryFormData; + return $this->objectModel->processQueryFormDatas($fieldParams, $field, $andOrName, $operatorName, $valueName); } /** diff --git a/module/search/test/model/savequery.php b/module/search/test/model/savequery.php index 2169832617..5099856235 100755 --- a/module/search/test/model/savequery.php +++ b/module/search/test/model/savequery.php @@ -12,6 +12,9 @@ cid=1 - 标题非空测试第title条的0属性 @『标题』不能为空。 - 测试保存的查询的模块属性module @bug +- 业需使用需求的模块名属性module @story +- 用需使用需求的模块名属性module @story +- 需求使用需求的模块名属性module @story */ @@ -65,5 +68,8 @@ include($app->getModuleRoot() . '/search/control.php'); $app->control = new search(); $search = new searchTest(); -r($search->saveQueryTest($module, $title[0], $where, $queryForm)) && p('title:0') && e('『标题』不能为空。'); //标题非空测试 -r($search->saveQueryTest($module, $title[1], $where, $queryForm)) && p('module') && e('bug'); //测试保存的查询的模块 +r($search->saveQueryTest($module, $title[0], $where, $queryForm)) && p('title:0') && e('『标题』不能为空。'); //标题非空测试 +r($search->saveQueryTest($module, $title[1], $where, $queryForm)) && p('module') && e('bug'); //测试保存的查询的模块 +r($search->saveQueryTest('epic', $title[1], $where, $queryForm)) && p('module') && e('story'); //业需使用需求的模块名 +r($search->saveQueryTest('requirement', $title[1], $where, $queryForm)) && p('module') && e('story'); //用需使用需求的模块名 +r($search->saveQueryTest('story', $title[1], $where, $queryForm)) && p('module') && e('story'); //需求使用需求的模块名 \ No newline at end of file diff --git a/module/search/test/model/setdefaultparams.php b/module/search/test/model/setdefaultparams.php index eee3ef7fe6..ef257afca5 100755 --- a/module/search/test/model/setdefaultparams.php +++ b/module/search/test/model/setdefaultparams.php @@ -8,10 +8,15 @@ timeout=0 cid=1 - 测试设置 products 的默认参数 @1,2,3,4,5,6,7,8,9,10,null -- 测试设置 users 的默认参数 @,admin,user1,user2,user3,user4,$me,null + +- 测试设置 users 的默认参数 @admin,user1,user2,user3,user4,$me,null + - 测试设置 executions 的默认参数 @,null + - 测试设置 空数组 的默认参数 @,null + - 测试设置 空字符串 的默认参数 @0,null + - 测试设置 array(1) 的默认参数 @ZERO - 测试设置 nonull 的默认参数 @0 @@ -44,9 +49,9 @@ $params7 = array('product' => array('values' => array(''), 'nonull' => true)) $search = new searchTest(); r($search->setDefaultParamsTest($fields1, $params1)) && p('0') && e('1,2,3,4,5,6,7,8,9,10,null'); // 测试设置 products 的默认参数 -r($search->setDefaultParamsTest($fields2, $params2)) && p('0') && e(',admin,user1,user2,user3,user4,$me,null'); // 测试设置 users 的默认参数 +r($search->setDefaultParamsTest($fields2, $params2)) && p('0') && e('admin,user1,user2,user3,user4,$me,null'); // 测试设置 users 的默认参数 r($search->setDefaultParamsTest($fields3, $params3)) && p('0') && e(',null'); // 测试设置 executions 的默认参数 r($search->setDefaultParamsTest($fields4, $params4)) && p('0') && e(',null'); // 测试设置 空数组 的默认参数 r($search->setDefaultParamsTest($fields5, $params5)) && p('0') && e('0,null'); // 测试设置 空字符串 的默认参数 r($search->setDefaultParamsTest($fields6, $params6)) && p('0') && e('ZERO'); // 测试设置 array(1) 的默认参数 -r($search->setDefaultParamsTest($fields7, $params7)) && p('0') && e('0'); // 测试设置 nonull 的默认参数 +r($search->setDefaultParamsTest($fields7, $params7)) && p('0') && e('0'); // 测试设置 nonull 的默认参数 \ No newline at end of file diff --git a/module/search/test/model/setsearchparams.php b/module/search/test/model/setsearchparams.php index 29ce3a71ee..763049266e 100755 --- a/module/search/test/model/setsearchparams.php +++ b/module/search/test/model/setsearchparams.php @@ -12,13 +12,15 @@ timeout=0 cid=1 - 测试module的值属性module @bug -- 测试searchFields的值属性searchFields @{"title":"Bug Title"} -- 测试fieldParams的值 - - 属性fieldParams @{"title":{"operator":"include"\\ - 测试actionURL的值属性actionURL @/index.php?m=bug&f=browse&productID=110&branch=0&browseType=bySearch&queryID=myQueryID - 测试onMenuBar的值属性onMenuBar @yes - 测试queryID的值属性queryID @0 - 测试style的值属性style @full +- 测试searchFields的值属性title @Bug Title +- 测试fieldParams的值 + - 第title条的operator属性 @include + - 第title条的control属性 @input + - 第title条的value属性 @~~ */ @@ -36,10 +38,13 @@ $searchConfig['onMenuBar'] = 'yes'; $searchConfig['actionURL'] = '/index.php?m=bug&f=browse&productID=110&branch=0&browseType=bySearch&queryID=myQueryID'; $searchConfig['queryID'] = 0; -r($search->setSearchParams($searchConfig)) && p('module') && e('bug'); //测试module的值 -r($search->setSearchParams($searchConfig)) && p('searchFields') && e('{"title":"Bug Title"}'); //测试searchFields的值 -r($search->setSearchParams($searchConfig)) && p('fieldParams', ';') && e('{"title":{"operator":"include","control":"input","value":""}}'); //测试fieldParams的值 -r($search->setSearchParams($searchConfig)) && p('actionURL') && e('/index.php?m=bug&f=browse&productID=110&branch=0&browseType=bySearch&queryID=myQueryID'); //测试actionURL的值 -r($search->setSearchParams($searchConfig)) && p('onMenuBar') && e('yes'); //测试onMenuBar的值 -r($search->setSearchParams($searchConfig)) && p('queryID') && e('0'); //测试queryID的值 -r($search->setSearchParams($searchConfig)) && p('style') && e('full'); //测试style的值 +$result = $search->setSearchParams($searchConfig); + +r($result) && p('module') && e('bug'); //测试module的值 +r($result) && p('actionURL') && e('/index.php?m=bug&f=browse&productID=110&branch=0&browseType=bySearch&queryID=myQueryID'); //测试actionURL的值 +r($result) && p('onMenuBar') && e('yes'); //测试onMenuBar的值 +r($result) && p('queryID') && e('0'); //测试queryID的值 +r($result) && p('style') && e('full'); //测试style的值 + +r($result['fields']) && p('title') && e('Bug Title'); //测试searchFields的值 +r($result['params']) && p('title:operator,control,value') && e('include,input,~~'); //测试fieldParams的值 \ No newline at end of file diff --git a/module/search/test/tao/getsqlparams.php b/module/search/test/tao/getsqlparams.php index 45eecd47ba..efc2594be9 100755 --- a/module/search/test/tao/getsqlparams.php +++ b/module/search/test/tao/getsqlparams.php @@ -9,7 +9,6 @@ cid=1 - 测试获取搜索 test 关键词的 unicode @test_ - 测试获取搜索 test 关键词的查询语句的 against 条件属性1 @(+"test_") -- 测试获取搜索 test 关键词的查询语句的 like 条件属性2 @OR title like '%test%' OR content like '%test%' - 测试获取搜索 测试 关键词的 unicode @27979 35797 - 测试获取搜索 测试 关键词的查询语句的 against 条件属性1 @(+"27979 35797") - 测试获取搜索 12345 关键词的 unicode @|12345| @@ -24,10 +23,9 @@ su('admin'); $keywords = array('test', '测试', '12345'); $search = new searchTest(); -r($search->getSqlParamsTest($keywords[0])) && p('0') && e('test_'); //测试获取搜索 test 关键词的 unicode -r($search->getSqlParamsTest($keywords[0])) && p('1') && e('(+"test_")'); //测试获取搜索 test 关键词的查询语句的 against 条件 -r($search->getSqlParamsTest($keywords[0])) && p('2') && e("OR title like '%test%' OR content like '%test%'"); //测试获取搜索 test 关键词的查询语句的 like 条件 -r($search->getSqlParamsTest($keywords[1])) && p('0') && e('27979 35797'); //测试获取搜索 测试 关键词的 unicode -r($search->getSqlParamsTest($keywords[1])) && p('1') && e('(+"27979 35797")'); //测试获取搜索 测试 关键词的查询语句的 against 条件 -r($search->getSqlParamsTest($keywords[2])) && p('0') && e('|12345|'); //测试获取搜索 12345 关键词的 unicode -r($search->getSqlParamsTest($keywords[2])) && p('1') && e('(+"|12345|") (-" 12345 ")'); //测试获取搜索 12345 关键词的查询语句的 against 条件 \ No newline at end of file +r($search->getSqlParamsTest($keywords[0])) && p('0') && e('test_'); //测试获取搜索 test 关键词的 unicode +r($search->getSqlParamsTest($keywords[0])) && p('1') && e('(+"test_")'); //测试获取搜索 test 关键词的查询语句的 against 条件 +r($search->getSqlParamsTest($keywords[1])) && p('0') && e('27979 35797'); //测试获取搜索 测试 关键词的 unicode +r($search->getSqlParamsTest($keywords[1])) && p('1') && e('(+"27979 35797")'); //测试获取搜索 测试 关键词的查询语句的 against 条件 +r($search->getSqlParamsTest($keywords[2])) && p('0') && e('|12345|'); //测试获取搜索 12345 关键词的 unicode +r($search->getSqlParamsTest($keywords[2])) && p('1') && e('(+"|12345|") (-" 12345 ")'); //测试获取搜索 12345 关键词的查询语句的 against 条件 \ No newline at end of file diff --git a/module/search/test/tao/processqueryformdatas.php b/module/search/test/tao/processqueryformdatas.php index 7ad2ddc186..1305f55d39 100755 --- a/module/search/test/tao/processqueryformdatas.php +++ b/module/search/test/tao/processqueryformdatas.php @@ -8,21 +8,21 @@ timeout=0 cid=1 - 测试 andOr,operator,value 的值 - - 属性andOr @AND - - 属性operator @include - - 属性value @测试 + - @AND + - 属性1 @include + - 属性2 @测试 - 测试 andOr,operator,value 的值 - - 属性andOr @OR - - 属性operator @= - - 属性value @1 + - @OR + - 属性1 @= + - 属性2 @1 - 测试 andOr,operator,value 的值 - - 属性andOr @AND - - 属性operator @= - - 属性value @~~ + - @AND + - 属性1 @= + - 属性2 @~~ - 测试 andOr,operator,value 的值 - - 属性andOr @AND - - 属性operator @= - - 属性value @0 + - @AND + - 属性1 @= + - 属性2 @0 */ @@ -31,38 +31,19 @@ include dirname(__FILE__, 2) . '/lib/search.unittest.class.php'; su('admin'); -$fields = array('title', 'id', 'status', 'activatedCount'); $andOrName = 'andOr1'; $operatorName = 'operator1'; $valueName = 'value1'; -$postDatas = array(); -$postData1 = new stdClass(); -$postData1->$andOrName = 'and'; -$postData1->$operatorName = 'include'; -$postData1->$valueName = '测试'; +$postDatas[] =[$andOrName => 'and', $operatorName => 'include', $valueName => '测试']; +$postDatas[] =[$andOrName => 'or', $operatorName => '=', $valueName => '1']; +$postDatas[] =[$andOrName => '', $operatorName => '']; +$postDatas[] =[$andOrName => '', $operatorName => '', $valueName => 'ZERO']; -$postData2 = new stdClass(); -$postData2->$andOrName = 'or'; -$postData2->$operatorName = '='; -$postData2->$valueName = '1'; - -$postData3 = new stdClass(); -$postData3->$andOrName = ''; -$postData3->$operatorName = ''; - -$postData4 = new stdClass(); -$postData4->$andOrName = ''; -$postData4->$operatorName = ''; -$postData4->$valueName = 'ZERO'; - -$postDatas[] = $postData1; -$postDatas[] = $postData2; -$postDatas[] = $postData3; -$postDatas[] = $postData4; +$fields = array('title', 'id', 'status', 'activatedCount'); $search = new searchTest(); -r($search->processQueryFormDatasTest($postDatas[0], $fields[0], $andOrName, $operatorName, $valueName)) && p('andOr,operator,value') && e('AND,include,测试'); //测试 andOr,operator,value 的值 -r($search->processQueryFormDatasTest($postDatas[1], $fields[1], $andOrName, $operatorName, $valueName)) && p('andOr,operator,value') && e('OR,=,1'); //测试 andOr,operator,value 的值 -r($search->processQueryFormDatasTest($postDatas[2], $fields[2], $andOrName, $operatorName, $valueName)) && p('andOr,operator,value') && e('AND,=,~~'); //测试 andOr,operator,value 的值 -r($search->processQueryFormDatasTest($postDatas[3], $fields[3], $andOrName, $operatorName, $valueName)) && p('andOr,operator,value') && e('AND,=,0'); //测试 andOr,operator,value 的值 +r($search->processQueryFormDatasTest($postDatas[0], $fields[0], $andOrName, $operatorName, $valueName)) && p('0,1,2') && e('AND,include,测试'); // 测试 andOr,operator,value 的值 +r($search->processQueryFormDatasTest($postDatas[1], $fields[1], $andOrName, $operatorName, $valueName)) && p('0,1,2') && e('OR,=,1'); // 测试 andOr,operator,value 的值 +r($search->processQueryFormDatasTest($postDatas[2], $fields[2], $andOrName, $operatorName, $valueName)) && p('0,1,2') && e('AND,=,~~'); // 测试 andOr,operator,value 的值 +r($search->processQueryFormDatasTest($postDatas[3], $fields[3], $andOrName, $operatorName, $valueName)) && p('0,1,2') && e('AND,=,0'); // 测试 andOr,operator,value 的值 diff --git a/module/serverroom/view/browse.html.php b/module/serverroom/view/browse.html.php deleted file mode 100644 index b67c302ced..0000000000 --- a/module/serverroom/view/browse.html.php +++ /dev/null @@ -1,97 +0,0 @@ - - * @package serverRoom - * @version $Id$ - * @link https://www.zentao.net - */ -?> -getModuleRoot() . 'common/view/header.html.php';?> -serverroom->confirmDelete)?> - - -
        ' data-module='serverroom'>
        -
        - -
        -

        - serverroom->empty;?> - ' . $lang->serverroom->create, '', 'class="btn btn-info"');?> -

        -
        - - - - recTotal}&recPerPage={$pager->recPerPage}";?> - - - - - - - - - - - - - - - - - - - - - - serverroom->providerList, $serverRoom->provider);?> - - - - - - - - -
        idAB);?> serverroom->name);?>serverroom->city);?> serverroom->line);?> serverroom->bandwidth);?>serverroom->provider);?>serverroom->owner);?>serverroom->createdBy);?>serverroom->createdDate);?>actions?>
        id;?>inlink('view', "id=$serverRoom->id", 'html', true), $serverRoom->name, '', "class='iframe'");?>serverroom->cityList, $serverRoom->city)?>serverroom->lineList, $serverRoom->line);?>bandwidth;?>owner);?>createdBy);?>createdDate;?> - id", $serverRoom, '', 'edit'); - if(common::hasPriv('serverroom', 'delete', $serverRoom)) - { - $deleteURL = $this->createLink('serverroom', 'delete', "id=$serverRoom->id"); - echo html::a("javascript:ajaxDelete(\"$deleteURL\", \"mainContent\", confirmDelete)", '', '', "class='btn' title='{$lang->serverroom->delete}'"); - } - ?> -
        - - -
        - -getModuleRoot() . 'common/view/footer.html.php';?> diff --git a/module/serverroom/view/create.html.php b/module/serverroom/view/create.html.php deleted file mode 100644 index bcd9917375..0000000000 --- a/module/serverroom/view/create.html.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @package serverRoom - * @version $Id$ - * @link https://www.zentao.net - */ -?> -getModuleRoot() . 'common/view/header.html.php';?> -
        -
        -

        serverroom->create?>

        -
        -
        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        serverroom->name?>
        serverroom->city?>serverroom->cityList, '', "class='form-control chosen'")?>
        serverroom->line?>serverroom->lineList, '', "class='form-control chosen'")?>
        serverroom->bandwidth?>
        serverroom->provider;?>serverroom->providerList, '', "class='form-control chosen'")?>
        serverroom->owner;?>
        - - -
        -
        -
        -getModuleRoot() . 'common/view/footer.html.php';?> diff --git a/module/serverroom/view/edit.html.php b/module/serverroom/view/edit.html.php deleted file mode 100644 index 42267faf9b..0000000000 --- a/module/serverroom/view/edit.html.php +++ /dev/null @@ -1,58 +0,0 @@ - - * @package serverRoom - * @version $Id$ - * @link https://www.zentao.net - */ -?> -getModuleRoot() . 'common/view/header.html.php';?> -
        -
        -

        - id;?> - name;?> - arrow . $lang->serverroom->edit?> -

        -
        -
        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        serverroom->name?>name", "class='form-control'")?>
        serverroom->city?>serverroom->cityList, $serverRoom->city, "class='form-control chosen'")?>
        serverroom->line?>serverroom->lineList, "$serverRoom->line", "class='form-control chosen'")?>
        serverroom->bandwidth?>bandwidth", "class='form-control'")?>
        serverroom->provider;?>serverroom->providerList, $serverRoom->provider, "class='form-control chosen'")?>
        serverroom->owner;?>owner, "class='form-control chosen'")?>
        - - -
        -
        -
        -getModuleRoot() . 'common/view/footer.html.php';?> diff --git a/module/serverroom/view/view.html.php b/module/serverroom/view/view.html.php deleted file mode 100644 index 9723366599..0000000000 --- a/module/serverroom/view/view.html.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @package serverroom - * @version $Id$ - * @link https://www.zentao.net - */ -?> -getModuleRoot() . 'common/view/header.html.php';?> -serverroom->confirmDelete)?> -
        -
        -

        serverroom->view;?>

        -
        -
        -
        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        serverroom->name;?>name;?>
        serverroom->city;?>serverroom->cityList, $serverRoom->city)?>
        serverroom->line;?>serverroom->lineList, $serverRoom->line);?>
        serverroom->bandwidth;?>bandwidth;?>
        serverroom->provider;?>serverroom->providerList, $serverRoom->provider);?>
        serverroom->owner;?>owner);?>
        serverroom->createdBy;?>createdBy);?>
        serverroom->createdDate;?>createdDate;?>
        -
        - getModuleRoot() . 'common/view/action.html.php'?> -
        -
        - -
        - id", " " . $lang->edit, '', "class='btn'", '', '', $serverRoom); - if(!isonlybody()) common::printLink('serverroom', 'browse', "", " " . $lang->goback, '', "class='btn'"); - ?> -
        -
        -
        -getModuleRoot() . 'common/view/footer.html.php';?> diff --git a/module/sonarqube/view/browse.html.php b/module/sonarqube/view/browse.html.php deleted file mode 100644 index 3db3a71c21..0000000000 --- a/module/sonarqube/view/browse.html.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @package sonarqube - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - - -
        -

        - noData;?> - - createLink('sonarqube', 'create'), " " . $lang->sonarqube->create, '', "class='btn btn-info'");?> - -

        -
        - -
        -
        - - - - recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?> - - - - - - - - $sonarqube): ?> - - - - - - - - -
        sonarqube->id);?>sonarqube->name);?>sonarqube->url);?>actions;?>
        name;?>url, $sonarqube->url, '_blank');?> - ", '',"title='{$lang->sonarqube->browseProject}' class='btn btn-primary'"); - common::printLink('sonarqube', 'edit', "sonarqubeID=$id", " ", '',"title='{$lang->sonarqube->edit}' class='btn btn-primary'"); - if(common::hasPriv('sonarqube', 'delete')) echo html::a($this->createLink('sonarqube', 'delete', "sonarqubeID=$id"), '', 'hiddenwin', "title='{$lang->sonarqube->delete}' class='btn'"); - ?> -
        - - - -
        -
        - - diff --git a/module/sonarqube/view/browseissue.html.php b/module/sonarqube/view/browseissue.html.php deleted file mode 100644 index 1c41423aed..0000000000 --- a/module/sonarqube/view/browseissue.html.php +++ /dev/null @@ -1,87 +0,0 @@ - - * @package sonarqube - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - - -
        -

        - noData;?> -

        -
        - -
        -
        - - recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?> - - - - - - - - - - - - - - - $sonarqubeIssue): ?> - - - - - - - - - - - - - -
        sonarqube->issue->message);?>sonarqube->issue->severity);?>sonarqube->issue->type);?>sonarqube->issue->status);?>sonarqube->issue->file);?>sonarqube->issue->line);?>sonarqube->issue->effort);?>sonarqube->issue->creationDate);?>actions;?>
        url, '/') . "/project/issues?id=$projectKey&issues={$sonarqubeIssue->key}&open={$sonarqubeIssue->key}", $sonarqubeIssue->message, '_target');?>severity;?>type;?>status;?>file;?>line;?>effort;?>creationDate;?> - key; - $attr = isset($bugs[$issueKey]) ? 'disabled' : ''; - common::printLink('bug', 'create', "productID=$productID&branch=&extra=from=sonarqube,sonarqubeID=$sonarqubeID,issueKey={$sonarqubeIssue->key}", " ", '', "title='{$lang->sonarqube->createBug}' class='btn' $attr data-app='qa'"); - ?> -
        - - - -
        -
        - - diff --git a/module/sonarqube/view/browseproject.html.php b/module/sonarqube/view/browseproject.html.php deleted file mode 100644 index 38189dd0b7..0000000000 --- a/module/sonarqube/view/browseproject.html.php +++ /dev/null @@ -1,81 +0,0 @@ - - * @package sonarqube - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - - -
        -

        - noData;?> - - createLink('instance', 'manage', "sonarqubeID=$sonarqubeID"), " " . $lang->sonarqube->createProject, '', "class='btn btn-info'");?> - -

        -
        - -
        -
        - - recPerPage}&pageID={$pager->pageID}";?> - - - - - - - - - - $sonarqubeProject): ?> - - - - - - - - -
        sonarqube->projectKey);?>sonarqube->projectName);?>sonarqube->projectlastAnalysis);?>actions;?>
        key;?>name;?>lastAnalysisDate, 0, 10);?> - key); - common::printLink('sonarqube', 'deleteProject', "sonarqubeID=$sonarqubeID&project=$projectKey", " ", 'hiddenwin', "title='{$lang->sonarqube->deleteProject}' class='btn btn-primary'"); - if(isset($projectJobPairs[$sonarqubeProject->key])) - { - $jobID = $projectJobPairs[$sonarqubeProject->key]; - common::printIcon('sonarqube', 'execJob', "jobID=$jobID", '', 'list', 'sonarqube', 'hiddenwin'); - if(in_array($jobID, $successJobs)) common::printIcon('sonarqube', 'reportView', "jobID=$jobID", '', 'list', 'audit', '', 'iframe', true); - } - ?> -
        - - - -
        -
        - - diff --git a/module/sonarqube/view/create.html.php b/module/sonarqube/view/create.html.php deleted file mode 100644 index 4b41cb25dc..0000000000 --- a/module/sonarqube/view/create.html.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @package sonarqube - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
        -
        -
        -
        -

        sonarqube->createServer;?>

        -
        -
        - - - - - - - - - - - - - - - - - - - - -
        sonarqube->name;?>sonarqube->placeholder->name}'");?>
        sonarqube->url;?>sonarqube->placeholder->url}'");?>
        sonarqube->account;?>sonarqube->placeholder->account}'");?>
        sonarqube->password;?>
        - - goback, '', 'class="btn btn-wide"');?> -
        -
        -
        -
        -
        - diff --git a/module/sonarqube/view/createproject.html.php b/module/sonarqube/view/createproject.html.php deleted file mode 100644 index 4cdd8f9d0b..0000000000 --- a/module/sonarqube/view/createproject.html.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @package sonarqube - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
        -
        -
        -
        -

        sonarqube->createProject;?>

        -
        -
        - - - - - - - - - - - - - -
        sonarqube->projectName;?>sonarqube->placeholder->projectName}'");?>
        sonarqube->projectKey;?>sonarqube->placeholder->projectKey . '"');?>
        - - goback, '', 'class="btn btn-wide"');?> -
        -
        -
        -
        -
        - diff --git a/module/sonarqube/view/edit.html.php b/module/sonarqube/view/edit.html.php deleted file mode 100644 index b634e26590..0000000000 --- a/module/sonarqube/view/edit.html.php +++ /dev/null @@ -1,50 +0,0 @@ - - * @package sonarqube - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
        -
        -
        -
        -

        sonarqube->editServer;?>

        -
        -
        - - - - - - - - - - - - - - - - - - - - - -
        sonarqube->name;?>name) ? $sonarqube->name : '', "class='form-control' placeholder='{$lang->sonarqube->placeholder->name}'");?>
        sonarqube->url;?>url) ? $sonarqube->url : '', "class='form-control' placeholder='{$lang->sonarqube->placeholder->url}'");?>
        sonarqube->account;?>account) ? $sonarqube->account : '', "class='form-control' placeholder='{$lang->sonarqube->placeholder->account}'");?>
        sonarqube->password;?>password) ? $sonarqube->password : '', "class='form-control'");?>
        - - goback, '', 'class="btn btn-wide"');?> -
        -
        -
        -
        -
        - diff --git a/module/sonarqube/view/reportview.html.php b/module/sonarqube/view/reportview.html.php deleted file mode 100644 index 42c26533e6..0000000000 --- a/module/sonarqube/view/reportview.html.php +++ /dev/null @@ -1,60 +0,0 @@ - - * @package sonarqube - * @version $Id: reprotview.html.php 935 2022-01-25 10:52:24Z liyuchun@easycorp.ltd $ - * @link https://www.zentao.net - */ -?> - -
        - - -
        -

        sonarqube->noReport;?>

        -
        - -
        -
        - -

        - createLink('sonarqube', 'browseIssue', "sonarqubeID={$sonarqubeID}&project=" . str_replace('-', '*', $projectKey)), $projectName, '_parent') : $projectName;?> - projectStatus->status) and $qualitygate->projectStatus->status != 'NONE'):?> - - sonarqube->qualitygateList, $qualitygate->projectStatus->status);?> - - -

        -
        -
        -
        - - - - - - - - - - - - - - - - - - - - - - - -
        " . $lang->sonarqube->report->bugs;?>" . $lang->sonarqube->report->vulnerabilities;?>" . $lang->sonarqube->report->security_hotspots_reviewed;?>" . $lang->sonarqube->report->code_smells;?>sonarqube->report->coverage;?>sonarqube->report->duplicated_lines_density;?>sonarqube->report->ncloc;?>
        - -
        diff --git a/module/space/test/lib/spacezen.unittest.class.php b/module/space/test/lib/spacezen.unittest.class.php new file mode 100644 index 0000000000..2c8bb3476f --- /dev/null +++ b/module/space/test/lib/spacezen.unittest.class.php @@ -0,0 +1,33 @@ +tester = $tester; + $tester->app->setModuleName('space'); + $tester->loadModel('space'); + + $this->spaceZenTest = initReference('space'); + } + + /** + * 获取空间下的应用实例 (zen版本)。 + * Get space instances (zen version). + * + * @param string $browseType + * @access public + * @return array + */ + public function getSpaceInstancesZenTest(string $browseType = 'all'): bool + { + $method = $this->spaceZenTest->getMethod('getSpaceInstances'); + $method->setAccessible(true); + + $instances = $method->invokeArgs($this->spaceZenTest->newInstance(), array("all")); + if(dao::isError()) return dao::getError(); + return count($instances) > 0; + } +} diff --git a/module/space/test/zen/getspaceinstances.php b/module/space/test/zen/getspaceinstances.php new file mode 100755 index 0000000000..1b32253ea7 --- /dev/null +++ b/module/space/test/zen/getspaceinstances.php @@ -0,0 +1,30 @@ +#!/usr/bin/env php +getSpaceInstances(); +cid=1 + +- 测试 browseType='' 时的返回结果 @1 +- 测试 browseType='all' 时的返回结果 @1 +- 测试 browseType='running' 时的返回结果 @1 +- 测试 browseType='aksjdfj' 时的返回结果 @1 +- 测试 browseType='abc' 时的返回结果 @1 + +*/ + +include dirname(__FILE__, 5) . '/test/lib/init.php'; +include dirname(__FILE__, 2) . '/lib/spacezen.unittest.class.php'; + +zenData('user')->gen(5); +zenData('space')->loadYaml('space')->gen(5); +zenData('instance')->loadYaml('instance')->gen(10); +zenData('pipeline')->loadYaml('pipeline')->gen(5); + +$spaceZenTester = new spaceZenTest(); +r($spaceZenTester->getSpaceInstancesZenTest()) && p() && e('1'); +r($spaceZenTester->getSpaceInstancesZenTest('all')) && p() && e('1'); +r($spaceZenTester->getSpaceInstancesZenTest('running')) && p() && e('1'); +r($spaceZenTester->getSpaceInstancesZenTest('aksjdfj')) && p() && e('1'); +r($spaceZenTester->getSpaceInstancesZenTest('abc')) && p() && e('1'); diff --git a/module/space/view/browse.html.php b/module/space/view/browse.html.php deleted file mode 100644 index 61df67f3ce..0000000000 --- a/module/space/view/browse.html.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @package space - * @version $Id$ - * @link https://www.zentao.net - */ -?> -app->getModuleRoot() . '/common/view/header.html.php';?> -instance->notices);?> - - -
        - -
        -app->getModuleRoot() . '/common/view/footer.html.php';?> diff --git a/module/space/zen.php b/module/space/zen.php index d08ec3cea6..bf0106050e 100644 --- a/module/space/zen.php +++ b/module/space/zen.php @@ -46,7 +46,7 @@ class spaceZen extends space foreach($pipelines as $key => $pipeline) { $maxID ++; - if($pipeline->createdBy == 'system') unset($pipelines[$key]); + if($pipeline->createdBy == 'system' && !$this->config->inCompose) unset($pipelines[$key]); $pipeline->createdAt = $pipeline->createdDate; $pipeline->appName = zget($this->lang->space->appType, $pipeline->type); diff --git a/module/stage/view/batchcreate.html.php b/module/stage/view/batchcreate.html.php deleted file mode 100644 index ba652ab0a7..0000000000 --- a/module/stage/view/batchcreate.html.php +++ /dev/null @@ -1,51 +0,0 @@ - - * @package stage - * @version $Id: batchCreate.html.php 4903 2013-06-26 05:32:59Z wyd621@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -
        -
        -

        stage->batchCreate;?>

        -
        -
        - - - - - - setPercent) and $config->setPercent == 1):?> - - - - - - - - - - - setPercent) and $config->setPercent == 1):?> - - - - - - - - - -
        stage->id;?>stage->name;?>stage->percent;?>stage->type;?>
        '') + $lang->stage->typeList, '', "class='form-control chosen'");?>
        - -
        -
        -
        - diff --git a/module/stage/view/browse.html.php b/module/stage/view/browse.html.php deleted file mode 100644 index 7fc2001dc3..0000000000 --- a/module/stage/view/browse.html.php +++ /dev/null @@ -1,70 +0,0 @@ - - * @package stage - * @version $Id: browse.html.php 4903 2013-06-26 05:32:59Z wyd621@gmail.com $ - * @link https://www.zentao.net - */ -?> - -
        - -
        -

        - stage->noStage;?> - - createLink('stage', 'create', "type={$type}"), " " . $lang->stage->create, '', "class='btn btn-info'");?> - -

        -
        - -
        - - - - - - - - setPercent) and $config->setPercent == 1):?> - - - - - - - - - - - - setPercent) and $config->setPercent == 1):?> - - - - - - - -
        stage->id);?>stage->name);?>stage->percent);?>stage->type);?>actions;?>
        id;?>name;?>percent;?>stage->typeList, $stage->type);?> - id", "", "list"); - common::printIcon('stage', 'delete', "stageID=$stage->id", "", "list", 'trash', 'hiddenwin'); - ?> -
        -
        - -
        - diff --git a/module/stage/view/create.html.php b/module/stage/view/create.html.php deleted file mode 100644 index 0b76b2e993..0000000000 --- a/module/stage/view/create.html.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @package stage - * @version $Id: create.html.php 4903 2013-06-26 05:32:59Z wyd621@gmail.com $ - * @link https://www.zentao.net - */ -?> - -
        -
        -
        -

        stage->create;?>

        -
        -
        - - - - - - - - - setPercent) and $config->setPercent == 1):?> - - - - - - - - - - - - - - -
        stage->name;?>
        stage->percent;?> -
        - - % -
        -
        stage->type;?>stage->typeList, '', "class='form-control chosen'");?>
        - -
        -
        -
        -
        - diff --git a/module/stage/view/edit.html.php b/module/stage/view/edit.html.php deleted file mode 100644 index e8ad574620..0000000000 --- a/module/stage/view/edit.html.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @package stage - * @version $Id: edit.html.php 4903 2013-06-26 05:32:59Z wyd621@gmail.com $ - * @link https://www.zentao.net - */ -?> - -
        -
        -
        -

        stage->edit;?>

        -
        -
        - - - - - - - - - setPercent) and $config->setPercent == 1):?> - - - - - - - - - - - - - - -
        stage->name;?>name, "class='form-control'");?>
        stage->percent;?> -
        - percent, "class='form-control'");?> - % -
        -
        stage->type;?>stage->typeList, $stage->type, "class='form-control chosen'");?>
        - -
        -
        -
        - diff --git a/module/stage/view/settype.html.php b/module/stage/view/settype.html.php deleted file mode 100644 index 5cc27cf097..0000000000 --- a/module/stage/view/settype.html.php +++ /dev/null @@ -1,82 +0,0 @@ - - * @package stage - * @version $Id: setType.html.php 4903 2013-06-26 05:32:59Z wyd621@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - - - - - - - - - - - -EOT; -?> - -
        -
        -
        - - - - - - - - - - $value):?> - - - - - - - - - - -
        custom->key;?>custom->value;?>
        - - - - - -
        - $lang->custom->currentLang, 'all' => $lang->custom->allLang); - echo html::radio('lang', $appliedTo, $lang2Set); - echo html::submitButton(); - if(common::hasPriv('custom', 'restore')) echo html::linkButton($lang->custom->restore, $this->createLink('custom', 'restore', "module=stage&field=typeList"), 'hiddenwin', '', 'btn btn-wide'); - ?> -
        -
        -
        -
        - - diff --git a/module/stakeholder/view/batchcreate.html.php b/module/stakeholder/view/batchcreate.html.php deleted file mode 100644 index 6a44ba6eda..0000000000 --- a/module/stakeholder/view/batchcreate.html.php +++ /dev/null @@ -1,102 +0,0 @@ - - * @package product - * @version $Id: browse.html.php 5096 2013-07-11 07:02:43Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - -
        -
        - - - - - - - - - - user])) continue;?> - user]);?> - - - - - - - - account])) continue;?> - - - - - - - $userName):?> - - - - - - - - - - - - - - - - -
        team->account;?> actions;?>
        - - - - - -
        account, "class='form-control chosen'");?> - - -
        - - -
        - - -
        -
        -
        -
        - - - - - - -
        - diff --git a/module/stakeholder/view/browse.html.php b/module/stakeholder/view/browse.html.php deleted file mode 100644 index 9b4a834e10..0000000000 --- a/module/stakeholder/view/browse.html.php +++ /dev/null @@ -1,102 +0,0 @@ - - * @package product - * @version $Id: browse.html.php 5096 2013-07-11 07:02:43Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - -stakeholder->confirmDelete);?> - -
        -
        - -
        - - - - recTotal}&recPerPage={$pager->recPerPage}";?> - - - - - - - - - - - - - - - name = $stakeholder->companyName ? $stakeholder->companyName . '/' . $stakeholder->name : $stakeholder->name;?> - key ? " " : '';?> - key ? $stakeholder->name . '(' . $lang->stakeholder->isKey . ')' : $stakeholder->name;?> - - - - - - - - - - - - - - -
        - idAB);?> - stakeholder->name;?>stakeholder->from;?>stakeholder->phone;?>stakeholder->qq;?>stakeholder->weixin;?>actions;?>
        - id);?> - createLink('stakeholder', 'view', "id=$stakeholder->id"), $stakeholder->name . $isKey, '', "title={$stakeholder->name}");?>name . $isKey;?>'>stakeholder->fromList, $stakeholder->from, '');?>phone;?>qq;?>weixin;?>email;?> - id", $stakeholder, 'list', 'chat-line', '', 'iframe', 'yes'); - common::printIcon('stakeholder', 'expect', "id=$stakeholder->id", $stakeholder, 'list', 'flag', '', 'iframe', 'yes'); - if(in_array($this->config->edition, array('max', 'ipd')) and $stakeholder->projectModel == 'waterfall') common::printIcon('stakeholder', 'userIssue', "account=$stakeholder->id", $stakeholder, 'list', 'list-alt', '', 'iframe', 'yes'); - common::printIcon('stakeholder', 'edit', "id=$stakeholder->id", $stakeholder, 'list', '', '', '', ''); - $deleteClass = common::hasPriv('stakeholder', 'delete') ? 'btn' : 'btn disabled'; - echo html::a($this->createLink('stakeholder', 'delete', "id=$stakeholder->id"), '', 'hiddenwin', "title='{$lang->stakeholder->delete}' class='{$deleteClass}'"); - ?> -
        - - - -
        - -
        noData;?>
        - -
        -
        - diff --git a/module/stakeholder/view/communicate.html.php b/module/stakeholder/view/communicate.html.php deleted file mode 100644 index 8b5ceb046c..0000000000 --- a/module/stakeholder/view/communicate.html.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @package task - * @version $Id: complete.html.php 935 2010-07-06 07:49:24Z jajacn@126.com $ - * @link https://www.zentao.net - */ -?> - - -
        -
        -
        -

        - id;?> - name'>" . $user->name . '') : html::a($this->createLink('task', 'view', 'task=' . $user->id), $user->name);?> -

        -
        -
        - - - - - - - - -
        stakeholder->communicate;?>
        - -
        -
        -
        -
        -
        -
        - diff --git a/module/stakeholder/view/create.html.php b/module/stakeholder/view/create.html.php deleted file mode 100644 index 0b65ea8499..0000000000 --- a/module/stakeholder/view/create.html.php +++ /dev/null @@ -1,93 +0,0 @@ - - * @package product - * @version $Id: browse.html.php 5096 2013-07-11 07:02:43Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - - -
        -
        -
        -

        stakeholder->create;?>

        -
        -
        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        stakeholder->from;?>stakeholder->fromList, "team");?>
        stakeholder->isKey;?>stakeholder->keyList);?>
        stakeholder->user;?> -
        - - -
        -
        stakeholder->nature;?>
        stakeholder->analysis;?>
        stakeholder->strategy;?>
        -
        -
        -
        - diff --git a/module/stakeholder/view/edit.html.php b/module/stakeholder/view/edit.html.php deleted file mode 100644 index 12076a2be0..0000000000 --- a/module/stakeholder/view/edit.html.php +++ /dev/null @@ -1,62 +0,0 @@ - - -
        -
        -
        -

        stakeholder->edit;?>

        -
        -
        - - - - - - - type == 'outside'):?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        stakeholder->isKey;?>stakeholder->keyList, $stakeholder->key);?>
        stakeholder->nature;?>nature, "class='form-control'");?>
        stakeholder->analysis;?>analysis, "class='form-control'");?>
        stakeholder->strategy;?>strategy, "class='form-control'");?>
        -
        -
        -
        -user);?> - diff --git a/module/stakeholder/view/expect.html.php b/module/stakeholder/view/expect.html.php deleted file mode 100644 index 9cd50743a2..0000000000 --- a/module/stakeholder/view/expect.html.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @package task - * @version $Id: complete.html.php 935 2010-07-06 07:49:24Z jajacn@126.com $ - * @link https://www.zentao.net - */ -?> - - -
        -
        -
        -

        - id;?> - name'>" . $user->name . '') : html::a($this->createLink('task', 'view', 'task=' . $user->id), $user->name);?> -

        -
        -
        - - - - - - - - - - - - -
        stakeholder->expect;?>
        stakeholder->progress;?>
        - -
        -
        -
        -
        - diff --git a/module/stakeholder/view/userissue.html.php b/module/stakeholder/view/userissue.html.php deleted file mode 100644 index aeec9bfff3..0000000000 --- a/module/stakeholder/view/userissue.html.php +++ /dev/null @@ -1,58 +0,0 @@ - - * @package company - * @version $Id: edit.html.php 4488 2013-02-27 02:54:49Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - -
        -
        -
        -

        - stakeholder->userIssue;?> -

        -
        - user, " " . $lang->issue->create, '', "class='btn btn-primary'");?> -
        -
        -
        -
        - -

        stakeholder->emptyTip;?>

        - -
        - - - - - - - - - - - - - - - - - - - - - - - -
        issue->title;?>issue->type;?>issue->severity;?>issue->pri;?>issue->status;?>issue->createdDate;?>
        title;?>issue->typeList, $issue->type);?>issue->severityList, $issue->severity);?>pri;?>issue->statusList, $issue->status);?>createdDate;?>
        -
        - -
        -
        - diff --git a/module/stakeholder/view/view.html.php b/module/stakeholder/view/view.html.php deleted file mode 100644 index 740cf60580..0000000000 --- a/module/stakeholder/view/view.html.php +++ /dev/null @@ -1,135 +0,0 @@ - - * @package company - * @version $Id: edit.html.php 4488 2013-02-27 02:54:49Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -createLink('stakeholder', 'browse', "projectID=$user->objectID"); -$createLink = $this->createLink('stakeholder', 'create', "projectID=$user->objectID"); -?> - -
        -
        -
        -
        -
        stakeholder->nature;?>
        -
        - nature) ? $user->nature : '
        ' . $lang->noData . '
        ';?> -
        -
        -
        -
        stakeholder->analysis;?>
        -
        - analysis) ? $user->analysis : '
        ' . $lang->noData . '
        ';?> -
        -
        -
        -
        stakeholder->strategy;?>
        -
        - strategy) ? $user->strategy : '
        ' . $lang->noData . '
        ';?> -
        -
        -
        - -
        -
        -
        stakeholder->expect . "($expect->createdDate)";?>
        -
        - expect) ? $expect->expect : '
        ' . $lang->noData . '
        ';?> -
        -
        -
        -
        stakeholder->progress . "($expect->createdDate)";?>
        -
        - progress) ? $expect->progress : '
        ' . $lang->noData . '
        ';?> -
        -
        -
        - - createLink('action', 'comment', "objectType=stakeholder&objectID=$user->id");?> -
        -
        -
        -
        -
        - -
        -
        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        stakeholder->name;?>name?>
        lang->stakeholder->type;?>stakeholder->typeList, $user->type, '');?>
        lang->stakeholder->company;?>companyName;?>
        lang->stakeholder->phone;?>phone;?>
        lang->stakeholder->qq;?>qq;?>
        lang->stakeholder->weixin;?>weixin;?>
        lang->stakeholder->email;?>email;?>
        lang->stakeholder->isKey;?>stakeholder->keyList, $user->key, '');?>
        lang->stakeholder->from;?>stakeholder->fromList, $user->from, '');?>
        -
        -
        -
        -
        -
        -
        - - diff --git a/module/store/view/appview.html.php b/module/store/view/appview.html.php deleted file mode 100644 index bf75f298a5..0000000000 --- a/module/store/view/appview.html.php +++ /dev/null @@ -1,107 +0,0 @@ - - * @package store - * @version $Id$ - * @link https://www.zentao.net - */ -?> -app->getModuleRoot() . '/common/view/header.html.php';?> -instance->notices);?> - - -
        -
        -
        - - -
        - -
        -
        -
        -
        - -
        -

        store->empty;?>

        -
        - -
        -
        -

        store->appBasicInfo;?>

        -

        desc;?>

        - - - - - - - - - - - - - - - -
        store->appVersion;?>:app_version;?>store->author;?>:author;?>
        store->releaseDate;?>:publish_time))->format('Y-m-d');?>store->appType;?>:categories, 'alias')), '/');?>
        -

        store->screenshots;?>

        -
        - screenshot_urls))):?> -
        store->noScreenshot;?>
        - - screenshot_urls);?> - - -
        - -
        - - -
        -
        -
        -

        store->appDynamic;?>

        -
        - - - - - - - - -
        store->noDynamicArticle;?>
        url, $article->title, "target='_blank'");?>
        - - - -
        -
        -
        - -
        -
        -
        -app->getModuleRoot() . '/common/view/footer.html.php';?> diff --git a/module/store/view/browse.html.php b/module/store/view/browse.html.php deleted file mode 100644 index 9a134af713..0000000000 --- a/module/store/view/browse.html.php +++ /dev/null @@ -1,76 +0,0 @@ - - * @package store - * @version $Id$ - * @link https://www.zentao.net - */ -?> -app->getModuleRoot() . '/common/view/header.html.php';?> -
        - -
        -
        -
        - store->sortTypes as $sortCode => $sortLabel):?> - - $sortLabel";?> - - -
        -
        - -
        -

        store->empty;?>

        -
        - - - - -
        -
        -app->getModuleRoot() . '/common/view/footer.html.php';?> diff --git a/module/story/model.php b/module/story/model.php index ba6cf6b920..eb8c2d91ab 100644 --- a/module/story/model.php +++ b/module/story/model.php @@ -2439,6 +2439,7 @@ class storyModel extends model { $now = helper::now(); $childIdList = $this->getAllChildId($storyID, false); + $childList = $this->getByList($childIdList); $this->dao->update(TABLE_STORY) ->set('status')->eq('closed') ->set('stage')->eq('closed') @@ -2453,7 +2454,13 @@ class storyModel extends model ->exec(); $this->loadModel('action'); - foreach($childIdList as $childID) $this->action->create('story', $childID, 'closedbyparent'); + foreach($childList as $child) + { + $preStatus = $child->status; + $isChanged = !empty($child->changedBy) ? true : false; + if($preStatus == 'reviewing') $preStatus = $isChanged ? 'changing' : 'draft'; + $this->loadModel('action')->create('story', $child->id, 'closedbyparent', '', ucfirst($closedReason) . "|$preStatus"); + } } /** @@ -2764,10 +2771,11 @@ class storyModel extends model $products = empty($executionID) ? $this->product->getList(0, 'all', 0, 0, 'all') : $this->product->getProducts($executionID); } - $this->loadModel('search')->setQuery('story', $queryID); + $type = in_array($type, array('requirement', 'epic')) ? $type : 'story'; + $this->loadModel('search')->setQuery($type, $queryID); $allProduct = "`product` = 'all'"; - $queryVar = in_array($type, array('requirement', 'epic')) ? "{$type}Query" : 'storyQuery'; + $queryVar = "{$type}Query"; $storyQuery = $this->session->{$queryVar}; $queryProductID = $productID; if(strpos($storyQuery, $allProduct) !== false) @@ -4988,7 +4996,7 @@ class storyModel extends model public function getActivateStatus(int $storyID, bool $hasTwins = true): string { $status = 'active'; - $action = 'closed,reviewrejected,closedbysystem'; + $action = 'closed,reviewrejected,closedbysystem,closedbyparent'; $action = $hasTwins ? $action . ',synctwins' : $action; $lastRecord = $this->dao->select('action,extra')->from(TABLE_ACTION) ->where('objectType')->eq('story') @@ -5001,7 +5009,7 @@ class storyModel extends model /* Set the status of the story to previous status in latest action log. */ $lastAction = $lastRecord->action; - if(strpos(',closed,reviewrejected,', ",$lastAction,") !== false) + if(strpos(',closed,reviewrejected,closedbyparent,', ",$lastAction,") !== false) { $status = strpos($lastRecord->extra, '|') !== false ? substr($lastRecord->extra, strpos($lastRecord->extra, '|') + 1) : 'active'; if($status == 'closed') $status = 'active'; /* Set the status to active if last status before close it is closed as well. */ diff --git a/module/story/tao.php b/module/story/tao.php index e5765a4bf8..671a75c053 100644 --- a/module/story/tao.php +++ b/module/story/tao.php @@ -576,26 +576,22 @@ class storyTao extends storyModel $rawQuery = $this->dao->get(); /* 获取阶段序列和关联的多分支产品需求。 */ - $stageOrderList = implode(',', array_keys($this->lang->story->stageList)); - $branchStoryList = $this->dao->select('t1.*,t2.branch as productBranch')->from(TABLE_PROJECTSTORY)->alias('t1') + $branches = $this->dao->select('t1.story, t2.branch')->from(TABLE_PROJECTSTORY)->alias('t1') ->leftJoin(TABLE_PROJECTPRODUCT)->alias('t2')->on('t1.project = t2.project') ->leftJoin(TABLE_PRODUCT)->alias('t3')->on('t1.product = t3.id') ->where('t1.story')->in(array_keys($stories)) ->andWhere('t1.branch')->eq(BRANCH_MAIN) ->andWhere('t3.type')->ne('normal') - ->fetchAll(); + ->fetchGroup('branch', 'story'); - /* 对需求做分组。 */ - $branches = array(); - foreach($branchStoryList as $story) $branches[$story->productBranch][$story->story] = $story->story; - - /* Take the earlier stage. */ - foreach($branches as $branchID => $storyIdList) + /* Replace branch stage with the story stage. */ + foreach($branches as $branchID => $branchList) { - $stages = $this->dao->select('*')->from(TABLE_STORYSTAGE)->where('story')->in($storyIdList)->andWhere('branch')->eq((int)$branchID)->fetchPairs('story', 'stage'); + $stages = $this->dao->select('*')->from(TABLE_STORYSTAGE)->where('story')->in(array_keys($branchList))->andWhere('branch')->eq((int)$branchID)->fetchPairs('story', 'stage'); foreach($stages as $storyID => $stage) { - if(strpos($stageOrderList, $stories[$storyID]->stage) > strpos($stageOrderList, $stage)) $stories[$storyID]->stage = $stage; + if($stories[$storyID]->branch != $branchID) continue; + $stories[$storyID]->stage = $stage; } } diff --git a/module/story/test/model/getstories2link.php b/module/story/test/model/getstories2link.php index f4b4aea229..0176fefa0c 100755 --- a/module/story/test/model/getstories2link.php +++ b/module/story/test/model/getstories2link.php @@ -18,8 +18,8 @@ cid=0 */ include dirname(__FILE__, 5) . '/test/lib/init.php'; -su('admin'); +zenData('userview')->gen(0); zenData('storyspec')->gen(60); zenData('product')->gen(20); $story = zenData('story'); @@ -39,10 +39,12 @@ $relation->gen(24); $_SESSION = array(); global $tester; + +su('admin'); $stories1 = $tester->loadModel('story')->getStories2Link(1, 'bySearch', 0); $stories2 = $tester->loadModel('story')->getStories2Link(2); -r(count($stories1)) && p() && e('18'); // 获取需求1可关联的需求数量 -r(count($stories2)) && p() && e('18'); // 获取需求2可关联的需求数量 +r(count($stories1)) && p() && e('9'); // 获取需求1可关联的需求数量 +r(count($stories2)) && p() && e('9'); // 获取需求2可关联的需求数量 r($stories1) && p('12:type,product') && e('story,1'); // 获取需求12可关联的需求id、product -r($stories2) && p('14:type,product') && e('story,1'); // 获取需求3可关联的需求id、product \ No newline at end of file +r($stories2) && p('14:type,product') && e('story,1'); // 获取需求3可关联的需求id、product diff --git a/module/story/ui/view.html.php b/module/story/ui/view.html.php index 6b569c8c1d..7b27567bfd 100644 --- a/module/story/ui/view.html.php +++ b/module/story/ui/view.html.php @@ -225,9 +225,8 @@ foreach($actions as $key => $action) if(isset($action['icon']) && $action['icon'] == 'split') { - $canBatchCreateStory = $story->grade < $maxGradeGroup[$story->type] && empty($story->hasOtherTypeChild); $objectID = $app->tab == 'project' ? ($project->multiple ? $projectID : $executionID) : $executionID; - if($canBatchCreateStory) + if($story->grade < $maxGradeGroup[$story->type] && empty($story->hasOtherTypeChild) && common::hasPriv($story->type, 'batchCreate')) { $actions[$key]['url'] = createLink($story->type, 'batchCreate', "productID=$story->product&branch=$story->branch&moduleID=$story->module&storyID=$story->id&executionID=$objectID"); } diff --git a/module/story/view/activate.html.php b/module/story/view/activate.html.php deleted file mode 100644 index 2b32191ec2..0000000000 --- a/module/story/view/activate.html.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @package story - * @version $Id: activate.html.php 4129 2013-01-18 01:58:14Z wwccss $ - * @link https://www.zentao.net - */ -?> - -
        -
        -
        -

        - id;?> - title'>" . $story->title . '') : html::a($this->createLink('story', 'view', "storyID=$story->id"), $story->title);?> - - arrow . $lang->story->activate;?> - -

        -
        -
        - - - - - - twins)):?> - - - - - - printExtendFields($story, 'table');?> - - - - - - - -
        story->assignedTo;?>closedBy, 'class="form-control chosen"');?>
        story->activateSyncTip;?>
        story->comment;?>
        - story->activate, '', 'btn btn-wide btn-primary'); - echo html::linkButton($lang->goback, $app->session->storyList ? $app->session->storyList : inlink('view', "storyID=$story->id"), 'self', '', 'btn btn-wide'); - ?> -
        -
        -
        -
        -
        -
        - diff --git a/module/story/view/affected.html.php b/module/story/view/affected.html.php deleted file mode 100644 index 23f1651269..0000000000 --- a/module/story/view/affected.html.php +++ /dev/null @@ -1,145 +0,0 @@ -story->currentBranch = sprintf($this->lang->story->currentBranch, $this->lang->product->branchName[$product->type]); - unset($twins[$story->id]); -}?> -
        - -
        -
        - executions as $executionID => $execution):?> -
        name ?>   - teams[$executionID])):?> - teams[$executionID] as $member) echo zget($users, $member->account) . ' ';?> - -
        - - - - - - - - - - - - tasks[$executionID])):?> - - tasks[$executionID] as $task):?> - - - - - - - - - - - -
        task->id;?>task->name;?>task->assignedTo;?>task->status;?>task->consumed;?>task->left;?>
        id;?>createLink('task', 'view', "taskID=$task->id"), $task->name, '_blank');?>assignedTo);?> - processStatus('task', $task);?> - consumed;?>left;?>
        - -
        -
        - - - - - - - - - - - - - - bugs as $bug):?> - - - - - - - - - - - -
        idAB;?>bug->title;?>statusAB;?>bug->openedBy;?>bug->resolvedBy;?>bug->resolution;?>bug->lastEditedBy;?>
        id;?>createLink('bug', 'view', "bugID=$bug->id"), $bug->title, '_blank');?> - processStatus('bug', $bug);?> - openedBy);?>resolvedBy);?>bug->resolutionList[$bug->resolution];?>lastEditedBy);?>
        -
        -
        - - - - - - - - - - - - cases as $case):?> - - - - - - - - - -
        idAB;?>testcase->title;?>statusAB;?>testcase->openedBy;?>testcase->lastEditedBy;?>
        id;?>createLink('testcase', 'view', "caseID=$case->id"), $case->title, '_blank');?> - processStatus('testcase', $case);?> - openedBy);?>lastEditedBy);?>
        -
        - -
        - - - - - - - - - - - - - - - branch]) ? $branches[$twin->branch] : ''; - $labelClass = $story->branch == $twin->branch ? 'label-primary' : ''; - ?> - - - - - - - - - - - -
        idAB;?>story->branch;?>story->title;?>statusAB;?>story->stageAB;?>story->openedBy;?>story->lastEditedByAB;?>
        id;?>createLink('story', 'view', "id=$twin->id", '', true), "$twin->title", '', "class='$twinsClass viewlink'") : "$twin->title");?>processStatus('story', $twin);?>story->stageList[$twin->stage];?>openedBy);?>lastEditedBy);?>
        -
        - -
        -
        diff --git a/module/story/view/assignto.html.php b/module/story/view/assignto.html.php deleted file mode 100644 index d97fb61097..0000000000 --- a/module/story/view/assignto.html.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @package story - * @version $Id: complete.html.php 935 2010-07-06 07:49:24Z jajacn@126.com $ - * @link https://www.zentao.net - */ -?> - - -
        -
        -
        -

        - id;?> - title'>" . $story->title . '') : html::a($this->createLink('story', 'view', 'story=' . $story->id), $story->title);?> - - arrow . $lang->story->assignTo;?> - -

        -
        -
        - - - - - - twins)):?> - - - - - - - - - - printExtendFields($story, 'table');?> - - - - - - - -
        story->assign;?>assignedTo, "class='form-control chosen'");?>
        story->assignSyncTip;?>
        story->status;?>status);?>
        comment;?>
        - - goback, $this->session->storyList, '', '', 'btn btn-wide');?> -
        -
        -
        - -
        -
        - diff --git a/module/story/view/batchclose.html.php b/module/story/view/batchclose.html.php deleted file mode 100755 index fc7adede7c..0000000000 --- a/module/story/view/batchclose.html.php +++ /dev/null @@ -1,75 +0,0 @@ - - * @package story - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -tab);?> -
        -
        -

        SRCommon : $lang->URCommon) . $lang->hyphen . $lang->story->batchClose;?>

        -
        - -
        - -
        "> - - - - - - - - - - - $story):?> - - - - - - - - - - - -
        idAB;?>story->title;?>story->status;?>story->closedReason;?>story->comment;?>
        - title;?> - twins)):?> - story->twins}:"?> id]?> - - processStatus('story', $story);?> - - - - - - -
        - status == 'draft' ? array_diff_key($reasonList, array('cancel' => '')) : $reasonList; - echo html::select("closedReasons[$storyID]", $closedReasonList, 'done', "class=form-control onchange=setDuplicateAndChild(this.value,$storyID) style='min-width: 80px'"); - ?> - ' closedReason != 'duplicate') echo "style='display:none'";?>> - searchAB}'");?> - ' closedReason != 'subdivided') echo "style='display:none'";?>> - idAB}'");?> -
        -
        - - -
        -
        - -
        - diff --git a/module/story/view/batchcreate.html.php b/module/story/view/batchcreate.html.php deleted file mode 100755 index ac1501bdd4..0000000000 --- a/module/story/view/batchcreate.html.php +++ /dev/null @@ -1,286 +0,0 @@ - - * @package story - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -story->create->requiredFields .= ',review';?> - -story->create->requiredFields);?> - -
        -
        -

        lang->story->subdivide : $this->lang->story->batchCreate;?>

        -
        - createLink('file', 'uploadImages', 'module=story¶ms=' . helper::safe64Encode("productID=$productID&branch=$branch&moduleID=$moduleID&storyID=$storyID&executionID=$executionID&plan=&type=$type")), $lang->uploadImages, '', "data-toggle='modal' data-type='iframe' class='btn btn-primary' data-width='70%'")?> - - createLink('custom', 'ajaxSaveCustomFields', 'module=story§ion=custom&key=batchCreateFields')?> - - -
        - - -
        -
        - story->create->requiredFields) as $field) - { - if($field) - { - $requiredFields[$field] = ''; - if(strpos(",{$config->story->list->customBatchCreateFields},", ",{$field},") !== false) $visibleFields[$field] = ''; - } - } - unset($visibleFields['module']); - ?> -
        -
        - - - - - - - - - type == 'kanban'):?> - - - - - - - - - - - - - - story->getFlowExtendFields(); - foreach($extendFields as $extendField) - { - $required = strpos(",$extendField->rules,", ',1,') !== false ? 'required' : ''; - echo ""; - } - ?> - - - - - - - - - - - type == 'kanban'):?> - - - - - - - - - - - loadModel('flow'); - foreach($extendFields as $extendField) echo "control == 'select' or $extendField->control == 'multi-select') ? " style='overflow:visible'" : '') . ">" . $this->flow->getFieldControl($extendField, '', $extendField->field . '[$id]') . ""; - ?> - - - - - - - - -
        branchBox'>product->branch;?>'>story->module;?> planBox'>story->plan;?>kanbancard->region;?>kanbancard->lane;?>story->title;?> specBox'>story->spec;?> sourceBox'>story->source;?> sourceBox'>story->sourceNote;?> verifyBox'>story->verify;?>story->category;?> priBox'>story->pri;?> estimateBox'>story->estimate;?> reviewBox'>story->reviewedBy;?> keywordsBox'>story->keywords;?>{$extendField->name}actions;?>
        branchBox'> planBox' style='overflow:visible'> - - - -
        -
        - -
        - - - -
        -
        - - - -
        -
        specBox'> sourceBox'> sourceBox'> verifyBox'>story->categoryList, 'feature', "class='form-control chosen'");?> priBox' style='overflow:visible'> estimateBox'> reviewBox'> -
        - - story->ditto;?> -
        -
        keywordsBox'> - - -
        - save, "id='saveButton'", 'btn btn-primary btn-wide');?> - story->saveDraft, "id='saveDraftButton'", 'btn btn-secondary btn-wide');?> - -
        -
        -
        -
        -
        - - - - - - - type == 'kanban'):?> - - - - - - - - - - - loadModel('flow'); - foreach($extendFields as $extendField) echo "control == 'select' or $extendField->control == 'multi-select') ? " style='overflow:visible'" : '') . ">" . $this->flow->getFieldControl($extendField, '', $extendField->field . "[$i]") . ""; - ?> - - - -
        - - - - - - - - - diff --git a/module/story/view/batchedit.html.php b/module/story/view/batchedit.html.php deleted file mode 100644 index 4ba1a84462..0000000000 --- a/module/story/view/batchedit.html.php +++ /dev/null @@ -1,165 +0,0 @@ - - * @package story - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -lang->story->dittoNotice);?> - -app->tab);?> - - -
        -
        -

        - story->common . $lang->hyphen . $lang->story->batchEdit;?> -

        -
        - createLink('custom', 'ajaxSaveCustomFields', 'module=story§ion=custom&key=batchEditFields')?> - -
        -
        - -
        - - -
        " id="batchEditForm"> -
        - - - - - - - - - - - - - - - - - - - - - - - - story->getFlowExtendFields(); - foreach($extendFields as $extendField) echo ""; - ?> - - - - $story):?> - - - - - - - - - - - - - - - - - source == 'meeting' or $story->source == 'researchreport') - { - $objects = $story->source == 'meeting' ? $meetings : $researchReports; - $html = html::select("sourceNote[$storyID]", $objects, $story->sourceNote, "class='form-control picker-select' data-drop-width='auto' id='sourceNote_$storyID'"); - } - else - { - $html = html::input("sourceNote[$storyID]", $story->sourceNote, "class='form-control' id='sourceNote_$storyID'"); - } - ?> - - - - - - status == 'closed'):?> - - - - - - control == 'select' or $extendField->control == 'multi-select') ? " style='overflow: visible'" : '') . ">" . $this->loadModel('flow')->getFieldControl($extendField, $story, $extendField->field . "[{$storyID}]") . "";?> - - - - - - - - -
        idAB;?>'>story->branch;?>story->module;?> col-plan'>story->planAB;?>story->title;?>'> story->estimateAB;?>story->category;?>' title=story->pri;?>> priAB;?>'> story->assignedTo;?>'> story->source;?>'> story->sourceNote;?>story->status;?>'> story->stageAB;?>'>story->closedBy;?>'> story->closedReason;?>'>story->keywords;?>{$extendField->name}
        '> - product]->type == 'normal' ? "disabled='disabled'" : '';?> - product]->type == 'normal') $branchTagOption[$story->product] = array();?> - product], $story->branch, "class='form-control picker-select' data-drop-width='auto' onchange='loadBranches($story->product, this.value, $storyID);' $disabled");?> - '> - id, array(0 => '/')), $story->module, "class='form-control picker-select' data-drop-width='auto'");?> - '> - parent < 0 ? "disabled='disabled'" : '';?> - product][$story->branch]) ? array('' => '') + $plans[$story->product][$story->branch] : array(), $story->plan, "class='form-control picker-select' data-drop-width='auto' $planDisabled");?> - -
        -
        - title, "class='form-control input-story-title' disabled"); ?> - title); ?> - -
        - - - color, "class='colorpicker' data-wrapper='input-control-icon-right' data-icon='color' data-btn-tip='{$lang->story->colorTag}' data-update-color='#titles\\[{$storyID}\\]'");?> -
        -
        -
        -
        >estimate, "class='form-control'"); ?>story->categoryList, $story->category, 'class="form-control picker-select" data-drop-width="auto"');?>>pri, 'class=form-control');?>'>assignedTo, "class='form-control picker-select' data-drop-width='auto'");?>>source, "class='form-control picker-select' data-drop-width='auto' id='source_$storyID'");?>' data-id="sourceNote;?>">processStatus('story', $story);?>>stage, 'class="form-control"' . ($story->status == 'draft' ? ' disabled="disabled"' : ''));?>'>closedBy, "class='form-control" . ($story->status == 'closed' ? " picker-select' data-drop-width='auto'" : "' disabled='disabled'"));?>> - - - - - - -
        - closedReason, "class=form-control onchange=setDuplicateAndChild(this.value,$storyID) style='min-width: 70px'");?> - ' closedReason != 'duplicate') echo "style='display: none'";?>> - product][$story->branch], $story->duplicateStory, "class='form-control' placeholder='{$lang->idAB}'");?> - ' closedReason != 'subdivided') echo "style='display: none'";?>> - idAB}'");?> -
        -
        >closedReason, 'class="form-control" disabled="disabled"');?>>keywords, 'class="form-control"');?>
        - - app->tab == 'product' or $this->app->tab == 'execution') ? html::a($this->session->storyList, $lang->goback, '', "class='btn btn-back btn-wide'") : html::backButton();?> -
        -
        -
        - - diff --git a/module/story/view/batchtotask.html.php b/module/story/view/batchtotask.html.php deleted file mode 100755 index 79409c9689..0000000000 --- a/module/story/view/batchtotask.html.php +++ /dev/null @@ -1,202 +0,0 @@ - - * @package story - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -task->ditto);?> - - - -task->create->requiredFields) as $field) -{ - if($field) $requiredFields[$field] = ''; -} -?> -
        -
        -

        story->batchToTask;?>

        -
        -
        -
        - - - - - - - - - - - - - - - - - - - $story):?> - status) !== false) continue; - - $currentStory = $storyID; - $pri = 3; - $storyPairs = zget($storyGroup, $story->module, array()); - $estimate = $hourPointValue ? $story->estimate * $hourPointValue : $story->estimate; - if($i == 1) - { - $moduleID = 0; - $type = $assignedTo = ''; - } - else - { - $type = $assignedTo = $moduleID = 'ditto'; - $storyPairs['ditto'] = $lang->task->ditto; - $members['ditto'] = $lang->task->ditto; - $modules['ditto'] = $lang->task->ditto; - $lang->task->typeList['ditto'] = $lang->task->ditto; - } - - if(in_array('module', $syncFields)) $moduleID = $story->module; - if(in_array('pri', $syncFields)) $pri = $story->pri; - if(in_array('assignedTo', $syncFields)) $assignedTo = $story->assignedTo ? $story->assignedTo : $assignedTo; - ?> - - - - - - - - - - - - - - - - - - - - - -
        idAB;?>'>task->module?>'>task->story;?>task->name;?>typeAB;?>'>task->assignedTo;?>'>task->estimateAB;?>'>task->estStarted;?>'>task->deadline;?>'>task->pri;?>actions;?>
        - - - - -
        - title, "class='form-control title-import'");?> -
        - - - -
        -
        -
        task->typeList, $taskType, 'class=form-control');?> -
        - 1 ? "checked" : '') . " /> {$lang->task->ditto}"; - ?> -
        -
        -
        - 1 ? "checked" : '') . " /> {$lang->task->ditto}"; - ?> -
        -
        task->priList, $pri, 'class=form-control');?> - - 1):?> - - -
        - - - -
        -
        -
        -
        - -
        - - - - - - - - - - - - - - - - -
        - diff --git a/module/story/view/bugs.html.php b/module/story/view/bugs.html.php deleted file mode 100644 index 8101b47228..0000000000 --- a/module/story/view/bugs.html.php +++ /dev/null @@ -1,40 +0,0 @@ - -
        -
        -

        - icons['report']);?> - story->bugs;?> -

        -
        -
        - - - - - - - - - - - - - - - $bug):?> - - - - - - - - - - - - -
        idAB;?> bug->title;?>story->pri;?>>priAB;?> bug->type;?> statusAB;?> bug->assignedTo;?> bug->resolvedBy;?>bug->resolution;?>
        id;?>title;?>bug->priList, $bug->pri, $bug->pri)?>'>pri == '0' ? '' : zget($lang->bug->priList, $bug->pri, $bug->pri);?>bug->typeList[$bug->type];?>processStatus('bug',$bug);?>assignedTo, $bug->assignedTo);?>resolvedBy, $bug->resolvedBy);?>bug->resolutionList[$bug->resolution];?>
        -
        -
        - diff --git a/module/story/view/cases.html.php b/module/story/view/cases.html.php deleted file mode 100644 index d36a419aef..0000000000 --- a/module/story/view/cases.html.php +++ /dev/null @@ -1,40 +0,0 @@ - -
        -
        -

        - icons['report']);?> - story->cases;?> -

        -
        -
        - - - - - - - - - - - - - - - $case):?> - - - - - - - - - - - - -
        idAB;?> testcase->title;?>story->pri;?>>priAB;?> testcase->type;?>statusAB;?> testcase->lastRunner;?> testcase->lastRunDate;?>testcase->lastRunResult;?>
        id;?>title;?>testcase->priList, $case->pri, $case->pri)?>'>pri == '0' ? '' : zget($lang->case->priList, $case->pri, $case->pri);?>testcase->typeList[$case->type];?>processStatus('testcase', $case);?>lastRunner, $case->lastRunner);?>lastRunDate)) echo date(DT_MONTHTIME1, strtotime($case->lastRunDate));?>lastRunResult ? $lang->testcase->resultList[$case->lastRunResult] : '';?>
        -
        -
        - diff --git a/module/story/view/change.html.php b/module/story/view/change.html.php deleted file mode 100644 index b7e990ec49..0000000000 --- a/module/story/view/change.html.php +++ /dev/null @@ -1,119 +0,0 @@ - - * @package story - * @version $Id: change.html.php 4129 2013-01-18 01:58:14Z wwccss $ - * @link https://www.zentao.net - */ -?> - - -
        -
        -
        -

        - id;?> - createLink('story', 'view', "storyID=$story->id"), $story->title, '', 'class="story-title"');?> - arrow . ' ' . $lang->story->change;?> -

        -
        -
        - - - - - - - - - - printExtendFields($story, 'table');?> - - - - - - - - - - - - - - - - - - - - - config->vision != 'or'):?> - - - - - - - - - -
        story->reviewedBy;?> -
        - story->checkForceReview() ? ' required' : ''));?> - story->checkForceReview()):?> - - story->needNotReview, '', "id='needNotReview' {$needReview}");?> - - -
        -
        story->status;?>status);?>
        story->title;?> - twins) ? '' : 'title-group';?> -
        -
        - title, 'class="form-control story-title"');?> -
        - - - -
        -
        - twins)):?> -
        - story->relievedTwinsRelation, '', "id='relievedTwins' title='{$lang->story->changeRelievedTwinsTips}'");?> -
        - -
        -
        story->spec;?>spec), 'rows=8 class="form-control"');?>story->specTemplate;?>
        story->verify;?>verify), 'rows=6 class="form-control"');?>
        story->comment;?>
        attach;?> - fetch('file', 'printFiles', array('files' => $story->files, 'fieldset' => 'false', 'object' => $story, 'method' => 'edit'));?> - fetch('file', 'buildform');?> -
        story->checkAffection;?>
        - lastEditedDate); - echo html::commonButton($lang->save, "id='saveButton'", 'btn btn-primary btn-wide'); - echo html::commonButton($lang->story->doNotSubmit, "id='saveDraftButton'", 'btn btn-secondary btn-wide'); - if(!isonlybody()) echo html::backButton(); - ?> -
        -
        -
        -
        - -
        -
        -
        -id);?> -title);?> -spec);?> -verify);?> - -type);?> -app->rawModule);?> -app->rawMethod);?> - diff --git a/module/story/view/close.html.php b/module/story/view/close.html.php deleted file mode 100644 index 713b4b3afd..0000000000 --- a/module/story/view/close.html.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @package story - * @version $Id: close.html.php 4129 2013-01-18 01:58:14Z wwccss $ - * @link https://www.zentao.net - */ -?> - -
        -
        -
        -

        - id;?> - title'>" . $story->title . '') : html::a($this->createLink('story', 'view', "storyID=$story->id"), $story->title);?> - - arrow . $lang->story->close;?> - -

        -
        -
        - - - - - - - - - - - - - - - - - - - printExtendFields($story, 'table');?> - - - - - - - -
        story->closedReason;?> -
        - - -
        -
        -
        story->status;?>
        story->comment;?>
        - - session->storyList ? $app->session->storyList : inlink('view', "storyID=$story->id"), $lang->goback, '', 'class="btn btn-wide"');?> -
        -
        -
        -
        -
        -
        - diff --git a/module/story/view/create.html.php b/module/story/view/create.html.php deleted file mode 100644 index de5e730a23..0000000000 --- a/module/story/view/create.html.php +++ /dev/null @@ -1,427 +0,0 @@ - - * @package story - * @version $Id: create.html.php 4902 2013-06-26 05:25:58Z wyd621@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -story->placeholder); ?> - -story->feedbackSource); ?> - -story->create->requiredFields);?> - - - -story->create->requiredFields) as $field) -{ - if($field and strpos($showFields, $field) === false) $showFields .= ',' . $field; -} -?> - - - - -
        -
        -
        -

        story->create;?>

        - story->checkForceReview()):?> -
        -
        - /> - -
        -
        - -
        - createLink('custom', 'ajaxSaveCustomFields', 'module=story§ion=custom&key=createFields')?> - -
        -
        -
        - - - - - - - - - - - - - - switchBranch' > - - - 1):?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - config->URAndSR):?> - - - - - - - > - - - - - - - - - - - - - - - - - - - - - - - - - printExtendFields('', 'table', 'columns=4');?> - - - - - - - - - - - - - - - - - - - - -
        story->module : $lang->story->product;?> -
        - - - -
        -
        -
        -
        story->assignedTo;?>
        - -
        -
        switchBranch'> switchBranch'> -
        - -
        story->module;?>
        - - "; - echo html::a($this->createLink('tree', 'browse', "rootID=$productID&view=story¤tModuleID=0&branch=$branch", '', true), $lang->tree->manage, '', "class='text-primary' data-toggle='modal' data-type='iframe' data-width='90%'"); - echo '  '; - echo html::a("javascript:void(0)", $lang->refreshIcon, '', "class='refresh' title='refresh' onclick='loadProductModules($productID)'"); - echo '
        '; - } - ?> - -
        product->branchName[$product->type];?> -
        -
        -
        - product->branch, $lang->product->branchName[$product->type])?> - -
        -
        -
        -
        - story->module?> - story->create->requiredFields, 'module') === false ? '' : 'required';?> - -
        -
        -
        -
        - story->plan;?> - -
        -
        -
        -
        -
        - -
        -
        story->planAB;?> -
        - "; - echo html::a($this->createLink('productplan', 'create', "productID=$productID&branch=$branch", '', true), "", '', "class='btn btn-icon' data-toggle='modal' data-type='iframe' data-width='95%' title='{$lang->productplan->create}'"); - echo '
        '; - echo "
        "; - echo html::a("javascript:void(0)", "", '', "class='btn btn-icon refresh' data-toggle='tooltip' title='{$lang->refresh}' onclick='loadProductPlans($productID)'"); - echo '
        '; - } - ?> - -
        story->assignedTo;?>' id='assignedToBox'> -
        - -
        story->assignedTo;?>
        - - -
        -
        story->source;?> - story->sourceList, $source, "class='form-control chosen'");?> - -
        -
        story->sourceNote;?>
        - -
        -
        '> -
        -
        -
        story->feedbackBy;?>
        - - story->notifyEmail;?> - -
        -
        -
        story->assignedTo;?> - - -
        -
        -
        story->source;?>
        - story->sourceList, $source, "class='form-control chosen'");?> - story->sourceNote;?> - -
        -
        -
        story->reviewedBy;?> -
        - story->checkForceReview() ? 'required' : '';?> - story->checkForceReview() ? '' : html::hidden('needNotReview', 1);?> -
        - PO : '', "class='form-control picker-select' multiple $required");?> -
        -
        -
        story->parent : $lang->story->requirement;?> -
        - - story->loadAllStories, "class='btn btn-default' onclick='loadURS(true)' data-toggle='tooltip'");?> -
        -
        > -
        - -
        story->parent;?>
        - - -
        -
        story->parent;?>
        kanbancard->region;?> - -
        -
        kanbancard->lane;?>
        - -
        -
        story->title;?> -
        -
        -
        - -
        - - - -
        -
        -
        - -
        -
        - story->category;?> - story->categoryList, $category, "class='form-control chosen'");?> -
        -
        -
        -
        - story->pri;?> - story->priList as $priKey => $priValue) - { - if(!empty($priKey) and (string)$priKey != (string)$priValue) - { - $hasCustomPri = true; - break; - } - } - - $priList = $lang->story->priList; - if(end($priList)) unset($priList[0]); - if(!isset($priList[$pri])) - { - reset($priList); - $pri = key($priList); - } - ?> - - - -
        - - -
        - -
        -
        - -
        -
        - story->estimateAB;?> - -
        -
        -
        -
        story->spec;?> - fetch('user', 'ajaxPrintTemplates', 'type=story&link=spec');?> - story->specTemplate . "\n" . $lang->noticePasteImg) . "'");?> -
        story->verify;?>
        story->legendAttach;?>fetch('file', 'buildform');?>
        story->mailto;?> -
        - chooseUsersToMail}' multiple");?> - fetch('my', 'buildContactLists');?> -
        -
        story->keywords;?> - -
        - - - - - save, "id='saveButton'", 'btn btn-primary btn-wide');?> - story->saveDraft, "id='saveDraftButton'", 'btn btn-secondary btn-wide');?> - - goback, '', 'class="btn btn-wide"') : html::backButton('', $source == 'bug' ? 'data-app=qa' : '');?> -
        -
        -
        -
        - - - - - - - - - - -story->module);?> -story->plan);?> - - - - diff --git a/module/story/view/edit.html.php b/module/story/view/edit.html.php deleted file mode 100644 index 95de9a0e1c..0000000000 --- a/module/story/view/edit.html.php +++ /dev/null @@ -1,364 +0,0 @@ - - * @package story - * @version $Id: edit.html.php 4645 2013-04-11 08:32:09Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -product);?> -id);?> -children));?> -story->moveChildrenTips);?> -app->rawModule);?> - -story->module);?> - -story->notice->reviewerNotEmpty);?> -story->feedbackSource); ?> -status);?> - -twins)?> -story->relievedTwinsTip)?> -
        -
        -
        -

        - id;?> - createLink('story', 'view', "storyID=$story->id"), $story->title, '', 'class="story-title"');?> - arrow . ' ' . $lang->story->edit;?> -

        -
        -
        -
        -
        -
        -
        -
        - - - -
        - title, 'class="form-control disabled story-title"' . (strpos('draft,changing', $story->status) !== false ? '' : ' disabled="disabled"'));?> -
        -
        - status) !== false):?> -
        -
        story->reviewers;?>
        -
        -
        - story->checkForceReview()):?> -
        - -
        -
        - -
        - /> - -
        -
        -
        - -
        - -
        - -
        -
        -
        - -
        -
        story->legendSpec;?>
        -
        - status) !== false ? html::textarea('spec', htmlSpecialString($story->spec), "rows='5' class='form-control'") : $story->spec;?> -
        -
        -
        -
        story->verify;?>
        -
        - status) !== false ? html::textarea('verify', htmlSpecialString($story->verify), "rows='5' class='form-control'") : $story->verify;?> -
        -
        - status) === false and empty($story->files)) ? false : true;?> - -
        -
        attach;?>
        -
        - status) !== false ? true : false;?> - fetch('file', 'printFiles', array('files' => $story->files, 'fieldset' => 'false', 'object' => $story, 'method' => 'edit', 'showDelete' => $canChangeFile));?> - fetch('file', 'buildform') : '';?> -
        -
        - - printExtendFields($story, 'div', 'position=left');?> - -
        -
        - story->changeSyncTip;?> - -
        -
        -
        -
          - -
        -
        -
        -
        - -
        -
        story->comment;?>
        -
        - -
        -
        -
        - lastEditedDate); - if(strpos('draft,changing', $story->status) !== false) - { - echo html::commonButton($lang->save, "id='saveButton'", 'btn btn-primary btn-wide'); - echo html::commonButton($story->status == 'changing' ? $lang->story->doNotSubmit : $lang->story->saveDraft, "id='saveDraftButton'", 'btn btn-secondary btn-wide'); - } - else - { - echo html::submitButton($lang->save); - } - if(!isonlybody()) echo html::backButton(); - ?> -
        -
        - -
        -
        -
        -
        -
        -
        story->legendBasicInfo;?>
        - - parent <= 0):?> - - - - - type != 'normal'):?> - - - - - - - - - - parent >= 0 and $story->type == 'story'):?> - - - - - - - - - - - - - - - - - - - - - - type == 'story'):?> - - - - - - - - - - - - - - - - - - '> - - - - '> - - - - - - - - - - - -
        story->product;?> -
        - - product, "onchange='loadProduct(this.value);' class='form-control chosen control-product $class'");?> - - type != 'normal') echo html::select('branch', $branchTagOption, $story->branch, "onchange='loadBranch();' class='form-control chosen control-branch'");?> -
        -
        product->branch = sprintf($lang->product->branch, $lang->product->branchName['branch']);?> -
        type != 'normal') echo html::select('branch', $branchTagOption, $story->branch, "onchange='loadBranch();' class='form-control chosen control-branch'");?>
        -
        story->module;?> -
        - module, "class='form-control chosen'"); - if(count($moduleOptionMenu) == 1) - { - echo ""; - echo html::a($this->createLink('tree', 'browse', "rootID=$story->product&view=story¤tModuleID=0&branch=$story->branch", '', true), $lang->tree->manage, '', "class='text-primary' data-toggle='modal' data-type='iframe' data-width='95%'"); - echo '  '; - echo html::a("javascript:void(0)", $lang->refreshIcon, '', "class='refresh' title='$lang->refresh' onclick='loadProductModules($story->product)'"); - echo ''; - } - ?> -
        -
        story->parent;?>parent, "class='form-control chosen'");?>
        story->plan;?> -
        - planTitle) ? count($story->planTitle) : 0?> - session->currentProductType != 'normal' and empty($story->branch) and $planCount > 1) ? 'multiple' : '';?> - plan, "class='form-control chosen' " . $multiple); - if(count($plans) == 1) - { - echo ""; - echo html::a($this->createLink('productplan', 'create', "productID=$story->product&branch=$story->branch", '', true), $lang->productplan->create, '', "class='text-primary' data-toggle='modal' data-type='iframe' data-width='95%'"); - echo html::a("javascript:void(0)", $lang->refresh, '', "class='refresh' onclick='loadProductPlans($story->product)'"); - echo ''; - } - ?> -
        -
        story->source;?>story->sourceList, $story->source, "class='form-control chosen'");?>
        story->sourceNote;?>sourceNote, "class='form-control'");?> -
        story->status;?> - processStatus('story', $story);?> - status);?> -
        story->stage;?> - stage; - $stageList = implode(',', array_keys($this->lang->story->stageList)); - $maxStagePos = strpos($stageList, $maxStage); - if($story->stages and $branchTagOption) - { - foreach($story->stages as $branch => $stage) - { - if(strpos($stageList, $stage) !== false and strpos($stageList, $stage) > $maxStagePos) - { - $maxStage = $stage; - $maxStagePos = strpos($stageList, $stage); - } - } - } - echo html::select('stage', $lang->story->stageList, $maxStage, "class='form-control chosen'"); - ?> -
        story->category;?>story->categoryList, $story->category, "class='form-control chosen'");?>
        story->pri;?>story->priList, $story->pri, "class='form-control chosen'");?>
        story->estimate;?>parent >= 0 ? html::input('estimate', $story->estimate, "class='form-control'") : $story->estimate;?>
        story->feedbackBy;?>feedbackBy, "class='form-control'");?>
        story->notifyEmail;?>notifyEmail, "class='form-control'");?>
        story->keywords;?>keywords, "class='form-control'");?>
        story->mailto;?> -
        - mailto, "class='form-control picker-select' multiple");?> - fetch('my', 'buildContactLists');?> -
        -
        -
        -
        -
        story->legendLifeTime;?>
        - - - - - - - - status == 'closed' ? $users + array('closed' => 'Closed') : $users;?> - - - status == 'reviewing'):?> - - - - - - status == 'closed'):?> - - - - - - - - - -
        story->openedBy;?>openedBy);?>
        story->assignedTo;?>assignedTo, 'class="form-control chosen"');?>
        story->reviewers;?>
        story->closedBy;?>closedBy, 'class="form-control chosen"');?>
        story->closedReason;?>story->reasonList, $story->closedReason, "class='form-control' onchange='setStory(this.value)'");?>
        -
        - - printExtendFields($story, 'div', 'position=right');?> - -
        -
        story->legendMisc;?>
        - - status == 'closed'):?> - - - - - - - - - - - - - -
        story->duplicateStory;?> '') + $productStories, $story->duplicateStory ? $story->duplicateStory : '', "class='form-control' placeholder='{$lang->bug->placeholder->duplicate}'"); ?>
        type == 'story' ? $lang->requirement->linkStory : $lang->story->linkStory;?> - type == 'story') echo html::a("#", $lang->story->linkStoriesAB, '', "class='btn btn-info' id='linkStoriesLink'");?> - type == 'requirement') echo html::a("#", $lang->story->linkRequirementsAB, '', "class='btn btn-info' id='linkStoriesLink'");?> -
        -
          - type == 'story' ? 'linkStories' : 'linkRequirements'; - if(isset($story->linkStoryTitles)) - { - foreach($story->linkStoryTitles as $linkStoryID => $linkStoryTitle) - { - echo "
        • "; - echo ""; - echo ""; - echo '
        • '; - } - } - ?> - -
        -
        -
        -
        -
        -
        -
        -
        -type);?> - - diff --git a/module/story/view/export.html.php b/module/story/view/export.html.php deleted file mode 100644 index 6960798527..0000000000 --- a/module/story/view/export.html.php +++ /dev/null @@ -1,13 +0,0 @@ - - * @package story - * @version $Id$ - * @link https://www.zentao.net - */ -?> - diff --git a/module/story/view/linkstory.html.php b/module/story/view/linkstory.html.php deleted file mode 100644 index 20fdb49797..0000000000 --- a/module/story/view/linkstory.html.php +++ /dev/null @@ -1,104 +0,0 @@ - - * @package story - * @version $Id: linkstory.html.php 4129 2016-03-09 08:58:13Z chenfei $ - * @link https://www.zentao.net - */ -?> - - - -
        -
        -

        - id;?> - title'>" . $story->title . '') : html::a($this->createLink('story', 'view', "storyID=$story->id"), $story->title);?> - - arrow . $lang->story->linkStory;?> - -

        -
        -
        - -
        -

        - story->noRequirement : $lang->story->noStory;?> -

        -
        - -
        - - - - - - - - - type == 'requirement'):?> - - - - - - - - - - createLink('story', 'view', "storyID=$story2Link->id"); - if($app->tab == 'project') $storyLink = $this->createLink('projectstory', 'view', "storyID=$story2Link->id"); - ?> - type, 'view');?> - - - - - - type == 'requirement'):?> - - - - - - - - -
        -
        - -
        - idAB;?> -
        story->pri;?>>priAB;?>story->title;?>story->status;?>story->stage;?>openedByAB;?>story->estimateAB;?>
        -
        - - -
        - id)) : sprintf('%03d', $story2Link->id);?> -
        pri?>' title='story->priList, $story2Link->pri, $story2Link->pri);?>'>story->priList, $story2Link->pri, $story2Link->pri);?>title) : $story2Link->title;?>processStatus('story', $story2Link);?>story->stageList, $story2Link->stage);?>openedBy);?>estimate;?>
        - - -
        - -
        - - diff --git a/module/story/view/processstorychange.html.php b/module/story/view/processstorychange.html.php deleted file mode 100644 index 7fd5223473..0000000000 --- a/module/story/view/processstorychange.html.php +++ /dev/null @@ -1,47 +0,0 @@ - - -
        -
        -
        -

        - id;?> - title . '">' . $story->title . '';?> - arrow . $lang->story->URChanged;?> -

        -
        - - - - - - - - - - - - - - - - - - - - - -
        story->id;?>story->title;?>story->status;?>story->version;?>story->openedBy;?>
        id;?>title;?>story->changed;?>version;?>openedBy);?>
        -
        - story->changeTips;?> -
        -
        - story->changeList['no'], '', "class='btn btn-secondary'");?> - story->changeList['yes'], '', "class='btn btn-primary showinonlybody'");?> -
        -
        -
        - diff --git a/module/story/view/report.html.php b/module/story/view/report.html.php deleted file mode 100644 index e0c5516640..0000000000 --- a/module/story/view/report.html.php +++ /dev/null @@ -1,93 +0,0 @@ - - * @package product - * @version $Id: report.html.php 1594 2011-03-13 07:27:55Z wwccss $ - * @link https://www.zentao.net - */ -?> - - -
        -
        -
        -
        -
        story->report->select;?>
        -
        -
        -
        -
        - story->report->charts['storiesPerPlan']);?> - story->report->charts, $checkedCharts, '', 'block');?> -
        -
        - - story->report->create, '', 'btn btn-primary');?> -
        -
        -
        -
        -
        -
        -
        -
        - report->typeList['default']);?> - report->typeList as $type => $typeName):?> - " . $typeName, '', "class='btn btn-link " . ($type == $chartType ? 'btn-active-line' : '') . "'")?> - -
        -
        product->unclosed . $lang->story->common, $lang->report->notice->help);?>
        - $chartOption):?> -
        -
        -
        -

        story->report->charts[$chartType];?>

        -
        -
        -
        -
        -
        - - - - - - - - - $data):?> - - - - - - - -
        story->report->$chartType->item;?>story->report->value;?>report->percent;?>
        name;?>value;?>percent * 100) . '%';?>
        -
        -
        -
        - -
        -
        -
        - - - - - - - diff --git a/module/story/view/review.html.php b/module/story/view/review.html.php deleted file mode 100644 index be89235500..0000000000 --- a/module/story/view/review.html.php +++ /dev/null @@ -1,90 +0,0 @@ - - * @package story - * @version $Id: review.html.php 4129 2013-01-18 01:58:14Z wwccss $ - * @link https://www.zentao.net - */ -?> - - -
        -
        -
        -

        - id;?> - createLink('story', 'view', "storyID=$story->id"), $story->title);?> - arrow . $lang->story->review;?> -

        -
        -
        - - - - - - - - - - > - - - - - - - - - - - - - - - - - - - - - - - - - - - - printExtendFields($story, 'table');?> - - - - - config->vision != 'or'):?> - - - - - - - - -
        story->reviewedDate;?>
        story->reviewResult;?>story->resultList, '', 'class="form-control chosen" onchange="switchShow(this.value)"');?>
        story->assignedTo;?>assignedTo, "class='form-control picker-select'");?>
        story->pri;?>story->priList, $story->pri,"class='form-control'");?>
        story->estimate;?>estimate, "class='form-control'");?>
        story->duplicateStory;?>
        story->childStories;?>
        story->status;?>status);?>
        story->comment;?>
        story->checkAffection;?>
        - - -
        -
        -
        -
        -
        -
        -id);?> -type);?> -app->rawModule);?> - - - diff --git a/module/story/view/submitreview.html.php b/module/story/view/submitreview.html.php deleted file mode 100644 index 2689705367..0000000000 --- a/module/story/view/submitreview.html.php +++ /dev/null @@ -1,66 +0,0 @@ - - * @package story - * @version $Id: submitreview.html.php 935 2022-07-20 09:49:24Z $ - * @link https://www.zentao.net - */ -?> - - - -
        -
        -
        -

        - id;?> - title'>" . $story->title . '') : html::a($this->createLink('story', 'view', 'story=' . $story->id), $story->title);?> - - arrow . $lang->story->submitReview;?> - -

        -
        -
        - - - - - - - - -
        story->reviewedBy;?>story->checkForceReview() or !empty($story->reviewer)) echo "class='required'";?>> -
        - story->checkForceReview()):?> -
        - reviewer, "class='form-control picker-select' multiple");?> -
        -
        - -
        - /> - -
        -
        -
        - -
        - reviewer, "class='form-control picker-select' multiple");?> -
        - -
        -
        - id);?> - - goback, $this->session->storyList, '', '', 'btn btn-wide');?> -
        -
        -
        - -
        -
        - diff --git a/module/story/view/tasks.html.php b/module/story/view/tasks.html.php deleted file mode 100644 index a1f9e2e247..0000000000 --- a/module/story/view/tasks.html.php +++ /dev/null @@ -1,77 +0,0 @@ - -
        -
        -

        - icons['report']);?> - story->tasks;?> -

        -
        -
        - - - - - - - - - - - - - - - - $task):?> - - - - - - - - - - - - children)):?> - - children as $key => $child):?> - - children)) ? ' table-child-bottom' : '';?> - - - - - - - - - - - - - - - - - - - - - -
        idAB;?> task->name;?>story->pri;?>>priAB;?> statusAB;?> task->assignedToAB;?>task->estimateAB;?>task->consumedAB;?> task->leftAB;?>task->progress;?>
        id;?>name;?>task->priList, $task->pri, $task->pri)?>'>pri == '0' ? '' : zget($lang->task->priList, $task->pri, $task->pri);?>processStatus('task', $task);?>assignedTo, $task->assignedTo);?>estimate;?>consumed;?>left;?> -
        -
        progress;?>
        -
        -
        id;?>lang->task->children . '">' . $this->lang->task->childrenAB . '' ?>name;?>task->priList, $child->pri, $child->pri)?>'>pri == '0' ? '' : zget($lang->task->priList, $child->pri, $child->pri);?>processStatus('task', $child);?>assignedTo, $child->assignedTo);?>estimate;?>consumed;?>left;?> -
        -
        progress;?>
        -
        -
        -
        -
        - diff --git a/module/story/view/view.html.php b/module/story/view/view.html.php deleted file mode 100644 index 3232e5be40..0000000000 --- a/module/story/view/view.html.php +++ /dev/null @@ -1,711 +0,0 @@ - - * @package story - * @version $Id: view.html.php 4952 2013-07-02 01:14:58Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -session->storyList ? $app->session->storyList : $this->createLink('product', 'browse', "productID=$story->product");?> - -type);?> -app->rawMethod);?> - - -app->getViewType() == 'xhtml'):?> -
        - - -
        -
        -
        -
        -
        story->legendSpec;?>
        -
        spec;?>
        -
        -
        -
        story->legendVerify;?>
        -
        verify;?>
        -
        - - fetch('file', 'printFiles', array('files' => $story->files, 'fieldset' => 'true', 'object' => $story, 'method' => 'view', 'showDelete' => false));?> - createLink('action', 'comment', "objectType=story&objectID=$story->id"); - ?> - children)):?> -
        -
        lang->story->children;?>
        -
        - - - - - - - - - - - - - - children as $child):?> - - - - - - - - - - - -
        story->id;?>story->pri;?>>priAB;?>story->title;?>story->assignedTo;?> story->estimate;?> story->status;?>actions;?>
        id;?> - pri ? 'label-pri label-pri-' . $child->pri : ''; - echo ""; - echo $child->pri == '0' ? '' : zget($this->lang->story->priList, $child->pri, $child->pri); - echo ""; - ?> - id&version=0¶m=0&storyType=$child->type", '', true); ?>">title;?>assignedTo);?>estimate . $config->hourUnit;?>processStatus('story', $child);?> - id&from=&storyType=$child->type", $child, 'list', 'alter'); - common::printIcon('story', 'review', "storyID=$child->id&from=product&storyType=$child->type", $child, 'list', 'search', '', 'iframe showinonlybody', true); - common::printIcon('story', 'assignTo', "storyID=$child->id&kanbanGroup=default&from=&storyType=$child->type", $child, 'list', '', '', 'iframe showinonlybody', true); - common::printIcon('story', 'close', "storyID=$child->id&from=&storyType=$child->type", $child, 'list', '', '', 'iframe showinonlybody', true); - common::printIcon('story', 'activate', "storyID=$child->id&storyType=$child->type", $child, 'list', '', '', 'iframe showinonlybody', true); - common::printIcon('story', 'edit', "storyID=$child->id&kanbanGroup=default&storyType=$child->type", $child, 'list'); - common::printIcon('testcase', 'create', "productID=$child->product&branch=$child->branch&module=0&from=¶m=0&story={$child->id}", $child, 'list', 'sitemap'); - ?> -
        -
        -
        - -
        - printExtendFields($story, 'div', "position=left&inForm=0&inCell=1");?> - app->getViewType() != 'xhtml'):?> -
        - -
        -
        - -
        ";?> - deleted) echo $this->story->buildOperateMenu($story, 'view', $project);?> -
        -
        -
        -
        -
        -
        - -
        -
        - - - shadow):?> - - - - - - type != 'normal'):?> - - - - - - - - branch and isset($branches[$storyModule->branch])) - { - $moduleTitle .= $branches[$storyModule->branch] . '/'; - echo $branches[$storyModule->branch] . $lang->arrow; - } - - foreach($modulePath as $key => $module) - { - $moduleTitle .= $module->name; - if($product->shadow) - { - echo $module->name; - } - else - { - common::printLink('product', 'browse', "productID=$story->product&branch=$story->branch&browseType=byModule¶m=$module->id", $module->name, '', "data-app='product'"); - } - if(isset($modulePath[$key + 1])) - { - $moduleTitle .= '/'; - echo $lang->arrow; - } - } - } - $printModule = ob_get_contents(); - ob_end_clean(); - ?> - - - type != 'requirement' and $story->parent != -1 and !$hiddenPlan):?> - - - - - - - - - - - - - - - - - - type != 'requirement'):?> - - - - - - - - - - - - - - - - - - source, $config->story->feedbackSource)):?> - - - - - - - - - - - - - - - - - - -
        story->product;?>createLink('product', 'view', "productID=$story->product"), $product->name, '', "data-app='product'");?>
        product->branch;?>product&branch=$story->branch", $branches[$story->branch], '', "data-app='product'");?>
        story->module;?>
        story->plan;?> - planTitle)) - { - foreach($story->planTitle as $planID => $planTitle) - { - if(!common::printLink('productplan', 'view', "planID=$planID", $planTitle, '', "data-app='product'")) echo $planTitle; - echo '
        '; - } - } - ?> -
        story->source;?>story->sourceList[$story->source];?>
        story->sourceNote;?>sourceNote;?>
        story->status;?> processStatus('story', $story);?>
        story->stage;?> - stage; - $stageList = implode(',', array_keys($this->lang->story->stageList)); - $maxStagePos = strpos($stageList, $maxStage); - if($story->stages and $branches) - { - foreach($story->stages as $branch => $stage) - { - if(strpos($stageList, $stage) !== false and strpos($stageList, $stage) > $maxStagePos) - { - $maxStage = $stage; - $maxStagePos = strpos($stageList, $stage); - } - } - } - echo $lang->story->stageList[$maxStage]; - ?> -
        story->category;?>story->categoryList, $story->category, $story->category)?>
        story->pri;?> - pri):?> - pri;?>' title='story->priList, $story->pri)?>'>story->priList, $story->pri)?> - -
        story->estimate;?>estimate . $config->hourUnit;?>
        story->feedbackBy;?>feedbackBy;?>
        story->notifyEmail;?>notifyEmail;?>
        story->keywords;?>keywords;?>
        story->legendMailto;?> - mailto)) - { - foreach(explode(',', $story->mailto) as $account) - { - if(empty($account)) continue; - echo "" . zget($users, trim($account)) . '  '; - } - } - ?> -
        -
        -
        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        story->openedBy;?>openedBy) . $lang->at . $story->openedDate;?>
        story->assignedTo;?>assignedTo) echo zget($users, $story->assignedTo) . $lang->at . $story->assignedDate;?>
        story->reviewers;?> - $result) - { - echo !empty($result) ? ' ' . zget($users, $reviewer) . '' : ' ' . zget($users, $reviewer) . ''; - } - } - ?> -
        story->reviewedDate;?>reviewedBy) echo $story->reviewedDate;?>
        story->closedBy;?>closedBy) echo zget($users, $story->closedBy) . $lang->at . $story->closedDate;?>
        story->closedReason;?> - closedReason) echo $lang->story->reasonList[$story->closedReason]; - if(isset($story->extraStories[$story->duplicateStory])) - { - echo html::a(inlink('view', "storyID=$story->duplicateStory"), '#' . $story->duplicateStory . ' ' . $story->extraStories[$story->duplicateStory], '', "title='{$story->extraStories[$story->duplicateStory]}'"); - } - ?> -
        story->lastEditedBy;?>lastEditedBy) echo zget($users, $story->lastEditedBy) . $lang->at . $story->lastEditedDate;?>
        -
        -
        -
        -
        -
        -
        - -
        - -
        -
          - -
        -
        - - config->URAndSR and !$hiddenURS):?> -
        ' id='legendStories'> -
          - type == 'story' ? 'requirement' : 'story'; - $canViewLinkStory = common::hasPriv($relationType, 'view', null, "storyType=$relationType"); - foreach($relations as $item) $relation[$item->id] = $item->title; - foreach($relation as $id => $title) - { - echo "
        • " . ($canViewLinkStory ? html::a($this->createLink('story', 'view', "id=$id&version=0¶m=0&storyType=$relationType", '', true), "#$id $title", '', "class='iframe' data-width='80%'") : "#$id $title"); - echo html::a($this->createLink('story', 'linkStory', "storyID=$story->id&type=remove&linkedID=$id&browseType=&queryID=0&storyType=$story->type"), '', 'hiddenwin', "class='hide removeButton'"); - } - ?> - type == 'story') ? $lang->story->requirement : $lang->story->story;?> -
        • type, 'linkStory')) echo html::a($this->createLink('story', 'linkStory', "storyID=$story->id&type=linkStories&linkedID=0&browseType=&queryID=0&storyType=$story->type", '', true), $lang->story->link . $linkLang, '', "class='btn btn-info iframe' data-width='95%' id='linkButton'");?> -
        -
        - - - type == 'story'):?> -
        -
          - tasks as $executionTasks) - { - foreach($executionTasks as $task) - { - if(!isset($executions[$task->execution])) continue; - $execution = isset($story->executions[$task->execution]) ? $story->executions[$task->execution] : ''; - $executionLink = !empty($execution->multiple) ? $this->createLink('execution', 'view', "executionID=$task->execution") : $this->createLink('project', 'view', "projectID=$task->project"); - $executionName = $executions[$task->execution]; - $taskInfo = $task->id . ' ' . $this->lang->task->statusList[$task->status] . ' ' . $task->name; - $class = isonlybody() ? 'showinonlybody' : 'iframe'; - $execName = (isset($execution->type) and $execution->type == 'kanban' and isonlybody()) ? $executionName : html::a($executionLink, $executionName, '', "class='text-muted'"); - echo "
        • " . $execName . html::a($this->createLink('task', 'view', "taskID=$task->id", '', true), $taskInfo, '', "class=$class data-width='90%'") . '
        • '; - } - } - foreach($story->executions as $executionID => $execution) - { - if(!$execution->multiple) continue; - if(!isset($executions[$executionID])) continue; - if(isset($story->tasks[$executionID])) continue; - - $execName = ($execution->type == 'kanban' and isonlybody()) ? $executions[$executionID] : html::a($this->createLink('execution', 'view', "executionID=$executionID"), $executions[$executionID], '', "class='text-muted'"); - echo "
        • " . $execName . '
        • '; - } - ?> -
        -
        - -
        - - - type == 'story'):?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - type == 'story' and helper::hasFeature('devops')):?> - - - - - - - - - - -
        story->legendFromBug;?> -
          - id $fromBug->title'>" . html::a($this->createLink('bug', 'view', "bugID=$fromBug->id", '', true), "#$fromBug->id $fromBug->title", '', "class='iframe' data-width='80%'") . '';?> -
        -
        story->legendBugs;?> -
          - id" . ' ' . $this->lang->bug->statusList[$bug->status] . ' ' . $bug->title; - echo "
        • " . html::a($this->createLink('bug', 'view', "bugID=$bug->id", '', true), $bugInfo, '', "class='iframe' data-width='80%'") . '
        • '; - } - ?> -
        -
        story->legendCases;?> -
          - title'>" . html::a($this->createLink('testcase', 'view', "caseID=$case->id", '', true), "#$case->id $case->title", '', $misc) . ''; - } - ?> -
        -
        story->legendBuilds;?> -
          - tab == 'product' ? 'project' : $app->tab; - foreach($builds as $build) - { - $link = common::hasPriv('build', 'view') ? html::a($this->createLink('build', 'view', "buildID=$build->id"), "#$build->id $build->name", '', "data-app='{$tab}'") : "#$build->id $build->name"; - echo "
        • $link
        • "; - } - ?> -
        -
        story->legendReleases;?> -
          - tab == 'execution' ? 'product' : $app->tab; - $releaseModule = $app->tab == 'project' ? 'projectrelease' : 'release'; - foreach($releases as $release) - { - $link = common::hasPriv($releaseModule, 'view') ? html::a($this->createLink($releaseModule, 'view', "release=$release->id"), "#$release->id $release->name", '', "data-app='{$tab}'") : "#$release->id $release->name"; - echo "
        • $link
        • "; - } - ?> -
        -
        story->linkStories;?> -
          - linkStoryTitles)) - { - $iframe = isonlybody() ? '' : 'iframe'; - foreach($story->linkStoryTitles as $linkStoryID => $linkStoryTitle) - { - if($app->user->admin or strpos(",{$app->user->view->products},", ",{$storyProducts[$linkStoryID]},") !== false) - { - $storyLink = html::a($this->createLink('story', 'view', "storyID=$linkStoryID&version=0¶m=0&storyType=$story->type", '', true), "#$linkStoryID $linkStoryTitle", '', "class='{$iframe}' data-width='80%' title='$linkStoryTitle'") . '
          '; - } - else - { - $storyLink = "#$linkStoryID $linkStoryTitle"; - } - echo "
        • $storyLink
        • "; - } - } - ?> -
        -
        story->linkMR;?> -
          - $linkMRTitle) - { - if($mrPriv) - { - echo "
        • " . html::a($this->createLink('mr', 'view', "MRID=$MRID"), "#$MRID $linkMRTitle") . '
        • '; - } - else - { - echo "
        • " . "#$MRID $linkMRTitle" . '
        • '; - } - } - ?> -
        -
        story->linkCommit;?> -
          - revision, 0, 10); - $commitTitle = $revision . ' ' . $commit->comment; - if($canViewRevision) - { - echo "'; - } - else - { - echo "'; - } - } - ?> -
        -
        -
        -
        -
        -
        - printExtendFields($story, 'div', "position=right&inForm=0&inCell=1");?> -
        -
        -app->getViewType() == 'xhtml'):?> -
        - - - - -
        - -
        -story->create); -js::set('productID', $story->product); -js::set('branch', $story->branch); -js::set('moduleID', $story->module); -js::set('storyType', $story->type); -js::set('unlink', $lang->story->unlink); -js::set('cancel', $lang->cancel); -js::set('rawModule', $this->app->rawModule); -?> - - - diff --git a/module/svn/view/cat.html.php b/module/svn/view/cat.html.php deleted file mode 100644 index 18a2fc31f2..0000000000 --- a/module/svn/view/cat.html.php +++ /dev/null @@ -1,18 +0,0 @@ - - * @package file - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
        -
        -
        <?php echo $code;?>
        -
        - diff --git a/module/svn/view/diff.html.php b/module/svn/view/diff.html.php deleted file mode 100644 index 7108dcfa42..0000000000 --- a/module/svn/view/diff.html.php +++ /dev/null @@ -1,19 +0,0 @@ - - * @package file - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -loadModel('repo')->buildURL('cat', $url, $revision);?> -
        -
        -
        <?php echo $diff;?>
        -
        - diff --git a/module/system/config.php b/module/system/config.php index 6d8e9df604..faa57ae01d 100644 --- a/module/system/config.php +++ b/module/system/config.php @@ -9,7 +9,6 @@ $config->system->edit = new stdclass(); $config->system->edit->requiredFields = 'name'; $config->system->groupPrivs = array(); -$config->system->groupPrivs['dashboard'] = 'backup|index'; $config->system->groupPrivs['deletebackup'] = 'backup|delete'; $config->system->groupPrivs['restorebackup'] = 'backup|restore'; diff --git a/module/system/ui/create.html.php b/module/system/ui/create.html.php index 3c3a8407e8..fb539cd77c 100644 --- a/module/system/ui/create.html.php +++ b/module/system/ui/create.html.php @@ -15,6 +15,11 @@ formPanel ( set::id('systemCreateForm'), set::title($lang->system->create), + set::titleClass('text-lg gap-0'), + to::titleSuffix + ( + btn(setClass('ghost'), icon('help'), set::hint($lang->help), set::url('https://www.zentao.net/book/zentaopms/888.html'), set::target('_blank')) + ), set::submitBtnText($lang->save), set::labelWidth(common::checkNotCN() ? '160px' : '100px'), formGroup diff --git a/module/system/view/dashboard.html.php b/module/system/view/dashboard.html.php deleted file mode 100644 index 55149e68a2..0000000000 --- a/module/system/view/dashboard.html.php +++ /dev/null @@ -1,20 +0,0 @@ - - * @package my - * @version $Id$ - * @link https://www.zentao.net - */ -?> -app->getModuleRoot() . '/common/view/header.html.php';?> -
        -
        -
        -
        -
        -
        -app->getModuleRoot() . '/common/view/footer.html.php';?> diff --git a/module/system/view/dblist.html.php b/module/system/view/dblist.html.php deleted file mode 100644 index 08ccd8e872..0000000000 --- a/module/system/view/dblist.html.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @package system - * @version $Id$ - * @link https://www.zentao.net - */ -?> -app->getModuleRoot() . '/common/view/header.html.php';?> - -
        -
        -
        -

        system->dbList;?>

        -
        - - - - - - - - - - - - - - - -
        system->dbName;?>system->dbType;?>system->dbStatus;?>system->action?>
        name;?>db_type?>instance->statusList, $db->status);?>system->printDBAction($db);?>
        -
        -
        -app->getModuleRoot() . '/common/view/footer.html.php';?> - diff --git a/module/system/view/domainview.html.php b/module/system/view/domainview.html.php deleted file mode 100644 index 4e73e1aabc..0000000000 --- a/module/system/view/domainview.html.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @package system - * @version $Id$ - * @link https://www.zentao.net - */ -?> -app->getModuleRoot() . '/common/view/header.html.php';?> - -
        -
        -
        -

        system->domain->common;?>

        -
        - inLink('editDomain'), $lang->system->domain->editDomain, '', "class='btn btn-primary'");?> -
        -
        - - - - - - - - - - - - - -
        system->domain->currentDomain;?>
        system->domain->expiredDate;?>
        -
        -
        -app->getModuleRoot() . '/common/view/footer.html.php';?> diff --git a/module/system/view/editdomain.html.php b/module/system/view/editdomain.html.php deleted file mode 100644 index ff486a29f9..0000000000 --- a/module/system/view/editdomain.html.php +++ /dev/null @@ -1,97 +0,0 @@ - - * @package system - * @version $Id$ - * @link https://www.zentao.net - */ -?> -app->getModuleRoot() . '/common/view/header.html.php';?> - -system->errors);?> -system->notices);?> - -
        -
        -
        -

        system->domain->config;?>

        -
        -
        - - - - - - - - - - - - - - - - - - -
        system->domain->oldDomain;?>loadModel('cne')->sysDomain();?> system->domain->notReuseOldDomain;?>
        system->domain->newDomain;?> - -
        - system->domain->setDNS;?> - system->domain->dnsHelperLink, '_blank', "class='text-primary'");?> -
        -
        -

        - - $lang->system->domain->uploadCert), $domainSettings->https, ($domainUsed ? "onclick='return false;'" : ''));?> -

        -
        - - - - - - - - - - - - - - - - - - -
        system->certPem;?>
        system->certKey;?>
        - system->verify, "id='validateCertBtn'");?> - -
        -
        save, "id='submitBtn'", "btn btn-primary");?>
        -
        -
        -
        - -app->getModuleRoot() . '/common/view/footer.html.php';?> - diff --git a/module/system/view/index.html.php b/module/system/view/index.html.php deleted file mode 100644 index 8540fe66c9..0000000000 --- a/module/system/view/index.html.php +++ /dev/null @@ -1,76 +0,0 @@ - - * @package system - * @version $Id$ - * @link https://www.zentao.net - */ -?> -app->getModuleRoot() . '/common/view/header.html.php';?> - -app->getModuleRoot() . '/common/view/footer.html.php';?> diff --git a/module/system/view/ossview.html.php b/module/system/view/ossview.html.php deleted file mode 100644 index d5829332e9..0000000000 --- a/module/system/view/ossview.html.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @package system - * @version $Id$ - * @link https://www.zentao.net - */ -?> -app->getModuleRoot() . '/common/view/header.html.php';?> -system->copySuccess);?> - -
        -
        -
        -

        system->oss->common;?>

        -
        - system->oss->manage, "id='ossManage'", "btn label label-outline label-primary label-lg");?> -
        -
        - - - - - - - - - - - - - - - - -
        system->oss->apiURL;?>extra_hosts, 'api', '');?>
        system->oss->accessKey;?>username;?>
        system->oss->secretKey;?> - - system->copy, "id='copySKBtn'");?> -
        -
        -
        - -app->getModuleRoot() . '/common/view/footer.html.php';?> diff --git a/module/task/model.php b/module/task/model.php index d8066a9b6c..55fc34ba3e 100755 --- a/module/task/model.php +++ b/module/task/model.php @@ -486,6 +486,12 @@ class taskModel extends model return false; } + if(!empty($task->left) && $task->left < 0) + { + dao::$errors['left'] = sprintf($this->lang->task->error->recordMinus, $this->lang->task->left); + return false; + } + /* Update parent task status. */ if($oldTask->parent > 0) $this->updateParentStatus($task->id); diff --git a/module/task/test/lib/activatetask.ui.class.php b/module/task/test/lib/activatetask.ui.class.php new file mode 100644 index 0000000000..2d86137dc3 --- /dev/null +++ b/module/task/test/lib/activatetask.ui.class.php @@ -0,0 +1,51 @@ +initForm('task', 'view', array('taskID' => $id), 'appIframe-execution'); + + $form->dom->xpath['taskAssignedTo'] = "//*[@title='{$this->lang->task->assignedTo}']/../div[2]"; + $form->dom->xpath['taskStatus'] = "//*[@title='{$this->lang->task->status}']/..//span"; + $form->dom->xpath['taskLeft'] = "//*[@title='{$this->lang->task->left}']/../div[2]"; + $form->dom->xpath['activateBtn'] = "//a[@title='{$this->lang->task->activate}']"; + + if(!in_array($status, array('done', 'cancel', 'closed'))) + { + if(is_object($form->dom->activateBtn)) return $this->failed('错误的显示了激活按钮'); + return $this->success('没有显示激活按钮'); + } + + $form->dom->activateBtn->click(); + $form->wait(1); + /* 输入激活任务表单内容 */ + if(!empty($assignedTo)) $form->dom->assignedTo->picker($assignedTo); + $form->dom->left->setValue($left); + $form->dom->submitBtn->click(); + $form->wait(1); + + if(empty($left) || $left == '0') + { + if(!is_object($form->dom->leftTip)) return $this->failed('预计剩余为空或0时没有提示'); + if($form->dom->leftTip->getText() != sprintf($this->lang->error->notempty, $this->lang->task->left)) return $this->failed('预计剩余为空或0时提示错误'); + return $this->success('预计剩余为空或0时提示正确'); + } + $form->wait(1); + if($form->dom->taskAssignedTo->getText() != $assignedTo) return $this->failed('激活任务后指派给错误'); + if(floatval($form->dom->taskLeft->getText()) != $left) return $this->failed('激活任务后预计剩余错误'); + if($form->dom->taskStatus->getText() != $this->lang->task->statusList->doing) return $this->failed('激活任务后任务状态错误'); + return $this->success('激活任务成功'); + } +} diff --git a/module/task/test/lib/assignto.ui.class.php b/module/task/test/lib/assignto.ui.class.php new file mode 100644 index 0000000000..3ffb8da0e3 --- /dev/null +++ b/module/task/test/lib/assignto.ui.class.php @@ -0,0 +1,62 @@ +initForm('task', 'view', array('taskID' => $taskID), 'appIframe-execution'); + + $form->dom->xpath['assignTo'] = "//*[@title='{$this->lang->task->assignedTo}']/../div[2]"; + $form->dom->xpath['taskLeft'] = "//*[@title='{$this->lang->task->left}']/../div[2]"; + $form->dom->xpath['assignBtn'] = "//a[@title='{$this->lang->task->assign}']"; + + if($form->dom->taskStatus->getText() == $this->lang->task->statusList->closed) + { + if(is_object($form->dom->assignBtn)) return $this->failed('已关闭的任务详情页错误的显示了指派按钮'); + + /* 查看任务列表中已关闭任务的指派 */ + $taskForm = $this->initForm('execution', 'task', array('executionID' => '2', 'status' => 'all'), 'appIframe-execution'); + $taskForm->dom->xpath['status'] = "//div[@id='tasks']//*[@data-row='{$taskID}' and @data-type='status']//span"; + $taskForm->dom->xpath['assign'] = "//div[@id='tasks']//*[@data-row='{$taskID}' and @data-type='assign']//span"; + $taskForm->dom->xpath['assignAttr'] = "//div[@id='tasks']//*[@data-row='{$taskID}' and @data-type='assign']//a"; + + if($taskForm->dom->assign->getText()!== 'Closed') return $this->failed('任务列表已关闭的任务指派人不是Closed'); + if($taskForm->dom->assignAttr->attr('class') != 'dtable-assign-btn disabled') return $this->failed('任务列表已关闭的任务指派按钮可点击'); + return $this->success('已关闭的任务没有显示指派按钮'); + } + /* 已取消的任务目前列表可以指派,详情页未显示指派按钮 */ + if($form->dom->taskStatus->getText() == $this->lang->task->statusList->cancel) + { + if(!is_object($form->dom->assignBtn)) return $this->success('已取消的任务详情页没有显示指派按钮'); + } + /* 指派弹窗 */ + $form->dom->assignBtn->click(); + $form->wait(1); + if(empty($account)) $form->dom->assignedToDelBtn->click(); + if(!empty($account)) $form->dom->assignedTo->picker($account); + if($form->dom->taskStatus->getText() != $this->lang->task->statusList->done) $form->dom->left->setValue($left); + $form->dom->submitBtn->click(); + $form->wait(1); + /* 校验预计剩余错误校验 */ + if(floatval($left) <= 0) + { + if(!is_object($form->dom->leftTip)) return $this->failed('预计剩余内容错误没有提示'); + if(!is_object($form->dom->leftTip->getText()) != sprintf($this->lang->error->notempty, $this->lang->task->left)) return $this->failed('预计剩余内容错误提示错误'); + return $this->success('预计剩余内容错误提示正确'); + } + if($form->dom->assignTo->getText() != $account) return $this->failed('指派人错误'); + if($form->dom->taskStatus->getText() != $this->lang->task->statusList->done && floatval($form->dom->taskLeft->getText()) != floatval($left)) return $this->failed('预计剩余错误'); + return $this->success('指派任务成功'); + } +} diff --git a/module/task/test/lib/canceltask.ui.class.php b/module/task/test/lib/canceltask.ui.class.php index f05667688f..1403229d4e 100644 --- a/module/task/test/lib/canceltask.ui.class.php +++ b/module/task/test/lib/canceltask.ui.class.php @@ -15,7 +15,6 @@ class cancelTaskTester extends tester { $form = $this->initForm('task', 'view', array('taskID' => $id), 'appIframe-execution'); $form->dom->xpath['cancelBtn'] = "//a[@title='{$this->lang->task->cancel}']"; - $form->dom->xpath['taskStatus'] = "//*[@title='{$this->lang->task->status}']/..//span"; if(in_array($status, array('done', 'cancel', 'closed'))) { if(is_object($form->dom->cancelBtn)) return $this->failed('错误的显示了取消按钮'); diff --git a/module/task/test/lib/closetask.ui.class.php b/module/task/test/lib/closetask.ui.class.php index 65777a7329..de2a2fec4e 100644 --- a/module/task/test/lib/closetask.ui.class.php +++ b/module/task/test/lib/closetask.ui.class.php @@ -15,7 +15,6 @@ class closeTaskTester extends tester { $form = $this->initForm('task', 'view', array('taskID' => $id), 'appIframe-execution'); $form->dom->xpath['closeBtn'] = "//a[@title='{$this->lang->task->close}']"; - $form->dom->xpath['taskStatus'] = "//*[@title='{$this->lang->task->status}']/..//span"; if(!in_array($status, array('done', 'cancel'))) { if(is_object($form->dom->closeBtn)) return $this->failed('错误的显示了关闭按钮'); diff --git a/module/task/test/lib/finishtask.ui.class.php b/module/task/test/lib/finishtask.ui.class.php index 8a95f4b412..042a721825 100644 --- a/module/task/test/lib/finishtask.ui.class.php +++ b/module/task/test/lib/finishtask.ui.class.php @@ -18,7 +18,6 @@ class finishTaskTester extends tester $form = $this->initForm('task', 'view', array('taskID' => $id), 'appIframe-execution'); $form->dom->xpath['taskAssignedTo'] = "//*[@title='{$this->lang->task->assignedTo}']/../div[2]"; - $form->dom->xpath['taskStatus'] = "//*[@title='{$this->lang->task->status}']/..//span"; $form->dom->xpath['taskConsumed'] = "//*[@title='{$this->lang->task->consumed}']/../div[2]"; $form->dom->xpath['taskLeft'] = "//*[@title='{$this->lang->task->left}']/../div[2]"; $form->dom->xpath['finishBtn'] = "//a[@title='{$this->lang->task->finish}']"; diff --git a/module/task/test/lib/pausetask.ui.class.php b/module/task/test/lib/pausetask.ui.class.php index fa1c4477ea..8df7bb31dd 100644 --- a/module/task/test/lib/pausetask.ui.class.php +++ b/module/task/test/lib/pausetask.ui.class.php @@ -15,7 +15,6 @@ class pauseTaskTester extends tester { $form = $this->initForm('task', 'view', array('taskID' => $id), 'appIframe-execution'); $form->dom->xpath['pauseBtn'] = "//a[@title='{$this->lang->task->pause}']"; - $form->dom->xpath['taskStatus'] = "//*[@title='{$this->lang->task->status}']/..//span"; if($status != 'doing') { if(is_object($form->dom->pauseBtn)) return $this->failed('错误的显示了暂停按钮'); diff --git a/module/task/test/lib/restarttask.ui.class.php b/module/task/test/lib/restarttask.ui.class.php index 36bc018d86..1917edc774 100644 --- a/module/task/test/lib/restarttask.ui.class.php +++ b/module/task/test/lib/restarttask.ui.class.php @@ -17,7 +17,6 @@ class restartTaskTester extends tester { $form = $this->initForm('task', 'view', array('taskID' => $id), 'appIframe-execution'); - $form->dom->xpath['taskStatus'] = "//*[@title='{$this->lang->task->status}']/..//span"; $form->dom->xpath['taskConsumed'] = "//*[@title='{$this->lang->task->consumed}']/../div[2]"; $form->dom->xpath['taskLeft'] = "//*[@title='{$this->lang->task->left}']/../div[2]"; $form->dom->xpath['restartBtn'] = "//a[@title='{$this->lang->task->restart}']"; diff --git a/module/task/test/lib/starttask.ui.class.php b/module/task/test/lib/starttask.ui.class.php index 2858e886ef..ceb90f7e94 100644 --- a/module/task/test/lib/starttask.ui.class.php +++ b/module/task/test/lib/starttask.ui.class.php @@ -35,7 +35,6 @@ class startTaskTester extends tester $form = $this->initForm('task', 'view', array('taskID' => $id), 'appIframe-execution'); $form->dom->xpath['taskAssignedTo'] = "//*[@title='{$this->lang->task->assignedTo}']/../div[2]"; - $form->dom->xpath['taskStatus'] = "//*[@title='{$this->lang->task->status}']/..//span"; $form->dom->xpath['taskConsumed'] = "//*[@title='{$this->lang->task->consumed}']/../div[2]"; $form->dom->xpath['taskLeft'] = "//*[@title='{$this->lang->task->left}']/../div[2]"; $form->dom->xpath['startBtn'] = "//a[@title='{$this->lang->task->start}']"; diff --git a/module/task/test/model/getusertasks.php b/module/task/test/model/getusertasks.php index 62ea52a3cd..9ab5f1995e 100755 --- a/module/task/test/model/getusertasks.php +++ b/module/task/test/model/getusertasks.php @@ -2,7 +2,8 @@ gen(0); $task = zenData('task'); $task->id->range('1-20'); @@ -67,7 +68,7 @@ timeout=0 cid=1 - 查看指派给用户1的任务第20条的name属性 @任务20 -- 检查指派给用户1的任务数量 @8 +- 检查指派给用户1的任务数量 @10 - 查看由用户1关闭的任务第16条的name属性 @任务16 - 检查由用户1关闭的任务数量 @2 - 查看由用户1完成的任务第20条的name属性 @任务20 @@ -79,10 +80,11 @@ cid=1 - 查看不存在的项目下由用户1完成的任务数量 @0 */ +su('admin'); $task = new taskTest(); r($task->getUserTasksTest('user1', 'assignedTo')) && p('20:name') && e('任务20'); // 查看指派给用户1的任务 -r(count($task->getUserTasksTest('user1', 'assignedTo'))) && p() && e('8'); // 检查指派给用户1的任务数量 +r(count($task->getUserTasksTest('user1', 'assignedTo'))) && p() && e('10'); // 检查指派给用户1的任务数量 r($task->getUserTasksTest('user1', 'closedBy')) && p('16:name') && e('任务16'); // 查看由用户1关闭的任务 r(count($task->getUserTasksTest('user1', 'closedBy'))) && p() && e('2'); // 检查由用户1关闭的任务数量 r($task->getUserTasksTest('user1', 'finishedBy')) && p('20:name') && e('任务20'); // 查看由用户1完成的任务 diff --git a/module/task/test/ui/activatetask.php b/module/task/test/ui/activatetask.php new file mode 100644 index 0000000000..9a13b5ee96 --- /dev/null +++ b/module/task/test/ui/activatetask.php @@ -0,0 +1,109 @@ +#!/usr/bin/env php +id->range('1-3'); +$user->account->range('admin, user1, user2'); +$user->password->range($config->uitest->defaultPassword)->format('md5'); +$user->realname->range('admin, USER1, USER2'); +$user->gen(3); + +$product = zenData('product'); +$product->id->range('1'); +$product->name->range('产品1'); +$product->gen(1); + +$project = zenData('project'); +$project->id->range('1, 2'); +$project->project->range('0, 1'); +$project->model->range('scrum, []'); +$project->type->range('project, sprint'); +$project->auth->range('extend, []'); +$project->parent->range('0, 1'); +$project->path->range('`,1,`, `,1,2,`'); +$project->name->range('项目1, 项目1执行1'); +$project->gen(2); + +$projectProduct = zenData('projectproduct'); +$projectProduct->project->range('1, 2'); +$projectProduct->product->range('1'); +$projectProduct->branch->range('0'); +$projectProduct->plan->range('0'); +$projectProduct->gen(2); + +$task = zenData('task'); +$task->id->range('1-100'); +$task->project->range('1'); +$task->parent->range('0'); +$task->path->range('`,1,`, `,2,`, `,3,`, `,4,`, `,5,`, `,6,`, `,7,`, `,8,`, `,9,`, `,10,`'); +$task->execution->range('2'); +$task->story->range('0'); +$task->name->range('1-100'); +$task->type->range('devel'); +$task->consumed->range('0, 2{9}'); +$task->left->range('0, 1, 0, 1{7}'); +$task->deadline->range(' (-5D)-(-4D):1D, []{11}')->type('timestamp')->format('YY/MM/DD'); +$task->status->range('wait, doing, done, pause, cancel, closed'); +$task->gen(6); + +$taskSpec = zenData('taskspec'); +$taskSpec->task->range('1-100'); +$taskSpec->version->range('0'); +$taskSpec->name->range('1-100'); +$taskSpec->gen(6); + +$team = zenData('team'); +$team->id->range('1-100'); +$team->root->range('1{2}, 2{2}'); +$team->type->range('project{2}, execution{2}'); +$team->account->range('admin, user1'); +$team->gen('4'); + +$tester = new activateTaskTester(); +$tester->login(); + +r($tester->activate('1', '', '', 'wait')) &&p('status,message') &&e('SUCCESS,没有显示激活按钮'); +r($tester->activate('2', '', '', 'doing')) &&p('status,message') &&e('SUCCESS,没有显示激活按钮'); +r($tester->activate('3', '', '', 'done')) &&p('status,message') &&e('SUCCESS,预计剩余为空或0时提示正确'); +r($tester->activate('3', '', '0', 'done')) &&p('status,message') &&e('SUCCESS,预计剩余为空或0时提示正确'); +r($tester->activate('3', 'USER1', '1', 'done')) &&p('status,message') &&e('SUCCESS,激活任务成功'); +r($tester->activate('4', '', '', 'pause')) &&p('status,message') &&e('SUCCESS,没有显示激活按钮'); +r($tester->activate('5', 'admin', '2', 'cancel')) &&p('status,message') &&e('SUCCESS,激活任务成功'); +r($tester->activate('6', '', '3', 'closed')) &&p('status,message') &&e('SUCCESS,激活任务成功'); +$tester->closeBrowser(); diff --git a/module/task/test/ui/assignto.php b/module/task/test/ui/assignto.php new file mode 100644 index 0000000000..deea88e76b --- /dev/null +++ b/module/task/test/ui/assignto.php @@ -0,0 +1,115 @@ +#!/usr/bin/env php +id->range('1-3'); +$user->account->range('admin, user1, user2'); +$user->password->range($config->uitest->defaultPassword)->format('md5'); +$user->realname->range('admin, USER1, USER2'); +$user->gen(3); + +$product = zenData('product'); +$product->id->range('1'); +$product->name->range('产品1'); +$product->gen(1); + +$project = zenData('project'); +$project->id->range('1, 2'); +$project->project->range('0, 1'); +$project->model->range('scrum, []'); +$project->type->range('project, sprint'); +$project->auth->range('extend, []'); +$project->parent->range('0, 1'); +$project->path->range('`,1,`, `,1,2,`'); +$project->name->range('项目1, 项目1执行1'); +$project->gen(2); + +$projectProduct = zenData('projectproduct'); +$projectProduct->project->range('1, 2'); +$projectProduct->product->range('1'); +$projectProduct->branch->range('0'); +$projectProduct->plan->range('0'); +$projectProduct->gen(2); + +$task = zenData('task'); +$task->id->range('1-100'); +$task->project->range('1'); +$task->parent->range('0'); +$task->path->range('`,1,`, `,2,`, `,3,`, `,4,`, `,5,`, `,6,`'); +$task->execution->range('2'); +$task->story->range('0'); +$task->name->range('1-100'); +$task->type->range('devel'); +$task->consumed->range('0'); +$task->left->range('0'); +$task->deadline->range(' (-5D)-(-4D):1D, []{11}')->type('timestamp')->format('YY/MM/DD'); +$task->status->range('wait, doing, done, pause, cancel, closed'); +$task->openedBy->range('admin'); +$task->assignedTo->range('[], admin{4}, closed'); +$task->gen(6); + +$taskSpec = zenData('taskspec'); +$taskSpec->task->range('1-100'); +$taskSpec->version->range('0'); +$taskSpec->name->range('1-100'); +$taskSpec->gen(6); + +$team = zenData('team'); +$team->id->range('1-100'); +$team->root->range('1{2}, 2{2}'); +$team->type->range('project{2}, execution{2}'); +$team->account->range('admin, user1'); +$team->gen('4'); + +$tester = new assignToTester(); +$tester->login(); + +r($tester->assignTo('1', 'USER1', '')) &&p('status,message') &&e('SUCCESS,预计剩余内容错误提示正确'); +r($tester->assignTo('1', 'USER1', '0')) &&p('status,message') &&e('SUCCESS,预计剩余内容错误提示正确'); +r($tester->assignTo('1', 'USER1', 'aaa')) &&p('status,message') &&e('SUCCESS,预计剩余内容错误提示正确'); +r($tester->assignTo('1', 'USER1', '1')) &&p('status,message') &&e('SUCCESS,指派任务成功'); +r($tester->assignTo('2', 'USER1', '1')) &&p('status,message') &&e('SUCCESS,指派任务成功'); +r($tester->assignTo('3', 'USER1', '1')) &&p('status,message') &&e('SUCCESS,指派任务成功'); +r($tester->assignTo('4', '', '1')) &&p('status,message') &&e('SUCCESS,指派任务成功'); +r($tester->assignTo('5', '', '1')) &&p('status,message') &&e('SUCCESS,已取消的任务详情页没有显示指派按钮'); +r($tester->assignTo('6', 'USER1', '1')) &&p('status,message') &&e('SUCCESS,已关闭的任务没有显示指派按钮'); +$tester->closeBrowser(); diff --git a/module/task/test/ui/page/view.php b/module/task/test/ui/page/view.php index cc94ad98b8..6abf58072d 100644 --- a/module/task/test/ui/page/view.php +++ b/module/task/test/ui/page/view.php @@ -10,7 +10,8 @@ class viewPage extends page 'assignedToDelBtn' => "//*[@name='assignedTo']/../button", //指派给组件中的删除按钮 'modalText' => "//*[@class='modal-body']", //总计消耗和预计剩余都为空或0时弹窗提示 'confirmBtn' => "//*[@class='modal-footer']//button[1]", - + /* 基本信息 */ + 'taskStatus' => "//div[contains(@class, 'task-status')]//span", ); $this->dom->xpath = array_merge($this->dom->xpath, $xpath); } diff --git a/module/task/view/activate.html.php b/module/task/view/activate.html.php deleted file mode 100644 index b9da4c4968..0000000000 --- a/module/task/view/activate.html.php +++ /dev/null @@ -1,131 +0,0 @@ - - * @package task - * @version $Id: start.html.php 935 2010-07-06 07:49:24Z jajacn@126.com $ - * @link https://www.zentao.net - */ -?> - - - -consumed);?> -user->account);?> - -task->error->teamMember);?> -task->error->teamLeftEmpty);?> -lang->task->error->leftEmptyAB, $this->lang->task->statusList[$task->status]));?> -task->error->notempty, $lang->task->estimate))?> -task->error->notempty, $lang->task->left))?> -error->notempty, $lang->task->assignedTo))?> -team);?> - -mode);?> - -
        -
        -
        -

        - id;?> - name'>" . $task->name . '') : html::a($this->createLink('task', 'view', 'task=' . $task->id), $task->name);?> - - arrow . $lang->task->activate;?> - -

        -
        - -
        - - - - - - - - - - - - - - isParent == '0'):?> - - - - - - - - - - printExtendFields($task, 'table', 'columns=2');?> - - - - - - - -
        task->mode;?>task->modeList, $task->mode) . html::hidden('mode', $task->mode);?>
        task->assignedTo;?> -
        - finishedBy, "class='form-control chosen'");?> - - - -
        -
        - -
        - -
        - -
        task->left;?> -
        - - task->hour;?> -
        -
        task->status;?>
        comment;?>
        - task->activate); - echo html::linkButton($lang->goback, $this->session->taskList); - ?> -
        - - -
        -
        -
        -
        -
        -team) and count($task->team) < 6) ? 6 - count($task->team) : 1);?> - diff --git a/module/task/view/assignto.html.php b/module/task/view/assignto.html.php deleted file mode 100644 index 9113bcf960..0000000000 --- a/module/task/view/assignto.html.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @package task - * @version $Id: complete.html.php 935 2010-07-06 07:49:24Z jajacn@126.com $ - * @link https://www.zentao.net - */ -?> - - -
        -
        - members) and strpos('wait,doing,pause', $task->status) !== false and (!isset($task->members[$app->user->account]) or $task->mode == 'linear')):?> -
        - -
        - mode == 'linear'):?> -

        task->transferNotice;?>

        - -

        task->deniedNotice, '' . $lang->task->teamMember . '', $lang->task->transfer);?>

        - -
        -
        - -
        -

        - id;?> - name'>" . $task->name . '') : html::a($this->createLink('task', 'view', 'task=' . $task->id), $task->name);?> - - arrow . (empty($task->team) ? $lang->task->assign : $lang->task->transfer);?> - -

        -
        -
        - - - - - - status != 'done' and $task->status != 'closed' and $task->parent >= 0):?> - - - - - - - - - - printExtendFields($task, 'table', 'columns=2');?> - - - - - - - -
        team) or strpos('done,cancel,closed', $task->status) !== false) ? $lang->task->assign : $lang->task->transferTo;?>team) or strpos('done,cancel,closed', $task->status) !== false) ? $task->assignedTo : $task->nextUser, "class='form-control chosen'");?>
        task->left;?>
        left, "class='form-control'");?> task->hour;?>
        task->status;?>status);?>
        comment;?>
        - - goback, $this->session->taskList);?> -
        -
        -
        - - -
        -
        - diff --git a/module/task/view/batchcreate.html.php b/module/task/view/batchcreate.html.php deleted file mode 100755 index f72a4d4208..0000000000 --- a/module/task/view/batchcreate.html.php +++ /dev/null @@ -1,347 +0,0 @@ - - * @package task - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - - -task->addChildTask);?> - -task->create->requiredFields);?> -task->create->requiredFields) as $field) -{ - if($field) - { - $requiredFields[$field] = ''; - if(strpos(",{$config->task->customBatchCreateFields},", ",{$field},") !== false) $visibleFields[$field] = ''; - } -} -$colspan = count($visibleFields) + 3; -?> - -
        -
        -

        - - lang->hyphen;?> - task->batchCreateChildren;?> - - task->batchCreate;?> - -

        - lifetime != 'ops' and $execution->attribute != 'request' and $execution->attribute != 'review'):?> - - - - -
        - - createLink('custom', 'ajaxSaveCustomFields', 'module=task§ion=custom&key=batchCreateFields')?> - - -
        - - -
        -
        -
        -
        - - - - - - lifetime != 'ops' and $execution->attribute != 'request' and $execution->attribute != 'review'):?> - - - - type == 'kanban'):?> - - - - - - - - - - - task->getFlowExtendFields(); - foreach($extendFields as $extendField) - { - $required = strpos(",$extendField->rules,", ',1,') !== false ? 'required' : ''; - echo ""; - } - ?> - - - - - task->ditto; - $lang->task->typeList['ditto'] = $lang->task->ditto; - $members['ditto'] = $lang->task->ditto; - $modules['ditto'] = $lang->task->ditto; - if($execution->lifetime != 'ops' and $execution->attribute != 'request' and $execution->attribute != 'review') $colspan = $colspan - 1; - ?> - task->batchCreate; $i++):?> - - - - - - lifetime != 'ops' and $execution->attribute != 'request' and $execution->attribute != 'review'):?> - - - - type == 'kanban'):?> - - - - - - - - - - - loadModel('flow'); - foreach($extendFields as $extendField) echo "control == 'select' or $extendField->control == 'multi-select') ? " style='overflow:visible'" : '') . ">" . $this->flow->getFieldControl($extendField, '', $extendField->field . "[$i]") . ""; - ?> - - - - - - - - - -
        idAB;?> moduleBox'>task->module?> storyBox'>task->story;?>task->name;?>kanbancard->region;?>kanbancard->lane;?>task->type;?> assignedToBox'>task->assignedTo;?> estimateBox'>task->estimateAB;?> estStartedBox'>task->estStarted;?> deadlineBox'>task->deadline;?> descBox'>task->desc;?> priBox'>task->pri;?>{$extendField->name}actions;?>
        - id, $i)'")?> - - -
        - - - - - - -
        -
        -
        - -
        - - - -
        -
        -
        task->typeList, $type, 'class=form-control');?> -
        - 1 ? "checked" : '') . " /> {$lang->task->ditto}"; - ?> -
        -
        -
        - 1 ? "checked" : '') . " /> {$lang->task->ditto}"; - ?> -
        -
        task->priList, $pri, 'class=form-control');?> - - - - -
        - - -
        -
        -
        -
        - - - - - - - - - - - - - - - loadModel('flow'); - foreach($extendFields as $extendField) echo "control == 'select' or $extendField->control == 'multi-select') ? " style='overflow:visible'" : '') . ">" . $this->flow->getFieldControl($extendField, '', $extendField->field . "[%s]") . ""; - ?> - - - -
        %s - id, \"%s\")'")?> - - -
        - - - - - -
        -
        -
        - -
        - - - -
        -
        - -
        task->typeList, $type, 'class="form-control"');?> -
        - {$lang->task->ditto}"; - ?> -
        -
        -
        - {$lang->task->ditto}"; - ?> -
        -
        task->priList, $pri, 'class=form-control');?> - - -
        -
        - - - - - - lifetime != 'ops' and $execution->attribute != 'request' and $execution->attribute != 'review'):?> - - - - type == 'kanban'):?> - - - - - - - - - - - loadModel('flow'); - foreach($extendFields as $extendField) echo "control == 'select' or $extendField->control == 'multi-select') ? " style='overflow:visible'" : '') . ">" . $this->flow->getFieldControl($extendField, '', $extendField->field . "[$i]") . ""; - ?> - - - -
        -type);?> - - -task->ditto);?> - - - - - - - diff --git a/module/task/view/batchedit.html.php b/module/task/view/batchedit.html.php deleted file mode 100755 index 10f231ef6f..0000000000 --- a/module/task/view/batchedit.html.php +++ /dev/null @@ -1,183 +0,0 @@ - - * @package task - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -lang->task->dittoNotice, $lang->executionCommon); -js::set('dittoNotice', $dittoNotice); -js::set('showFields', $showFields); -js::set('requiredFields', $config->task->edit->requiredFields); -?> -
        -
        -

        - task->common . $lang->hyphen . $lang->task->batchEdit;?> - multiple):?> - task->execution . $lang->hyphen . ' ' . $executionName;?> - -

        -
        - createLink('custom', 'ajaxSaveCustomFields', 'module=task§ion=custom&key=batchEditFields')?> - -
        -
        - -
        - - task->edit->requiredFields) as $field) - { - if($field) - { - $requiredFields[$field] = ''; - if(strpos(",{$config->task->customBatchEditFields},", ",{$field},") !== false) $visibleFields[$field] = ''; - } - } - ?> -
        "> -
        - - - - - - - - - - - - - - - - - - - - task->getFlowExtendFields(); - foreach($extendFields as $extendField) echo ""; - ?> - - - - $task):?> - execution->getById($task->execution); - $modules = $this->tree->getTaskOptionMenu($task->execution, 0, 'allModule'); - foreach($modules as $moduleID => $moduleName) $modules[$moduleID] = $prjInfo->name. $moduleName; - $modules = array('ditto' => $this->lang->task->ditto) + $modules; - } - ?> - - assignedTo != $this->app->user->account and $task->mode == 'linear') or !isset($teams[$taskID][$app->user->account]))) ? "disabled='disabled'" : '';?> - parent < 0) ? "disabled='disabled'" : '';?> - '', 'ditto' => $this->lang->task->ditto); - $teamAccounts = !empty($executionTeams[$task->execution]) ? array_column($executionTeams[$task->execution], 'account') : array(); - foreach($teamAccounts as $teamAccount) $members[$teamAccount] = zget($users, $teamAccount); - - $taskMembers = array(); - if(isset($teams[$taskID])) - { - $teamAccounts = $teams[$taskID]; - foreach($teamAccounts as $teamAccount) $taskMembers[$teamAccount->account] = $users[$teamAccount->account]; - } - else - { - if($task->status == 'closed') $members['closed'] = 'Closed'; - $taskMembers = $members; - } - - if($task->assignedTo and !isset($taskMembers[$task->assignedTo])) - { - $taskMembers[$task->assignedTo] = $users[$task->assignedTo]; - } - ?> - - - - - - - - - - - - - - - - - control == 'select' or $extendField->control == 'multi-select') ? " style='overflow:visible'" : '') . ">" . $this->loadModel('flow')->getFieldControl($extendField, $task, $extendField->field . "[{$taskID}]") . "";?> - - - - - - - - -
        idAB;?>'>task->name?>'>task->module?>'>task->assignedTo;?>task->type; ?>'>task->status;?>'>task->estStarted?>'>task->deadline?>'>task->pri;?>'>task->estimateAB;?>'>task->consumedThisTime;?>'>task->leftAB?>'>task->finishedBy;?>'>task->canceledBy;?>'>task->closedBy;?>'>task->closedReason;?>{$extendField->name}
        -
        - name, "class='form-control'");?> -
        - - - color, "data-provide='colorpicker' data-wrapper='input-control-icon-right' data-icon='color' data-btn-tip='{$lang->task->colorTag}' data-update-text='#name\\[{$taskID}\\]'");?> -
        -
        -
        ' style='overflow:visible'>module, "class='form-control picker-select' data-drop-width='auto'")?>' style='overflow:visible'>assignedTo, "class='form-control picker-select' data-drop-width='auto' {$disableAssignedTo}");?>task->typeList, $task->type, "class='form-control'");?>>task->statusList, $task->status, "class='form-control' {$disableHour}");?>>estStarted) ? '' : $task->estStarted, "class='form-control text-center form-date'");?>>deadline) ? '' : $task->deadline, "class='form-control text-center form-date'");?>>task->priList, $task->pri, "class='form-control'");?>>estimate, "class='form-control text-center' {$disableHour}");?>>>left, "class='form-control text-center' {$disableHour}");?>' style='overflow:visible'>finishedBy, "class='form-control picker-select' data-drop-width='auto'");?>' style='overflow:visible'>canceledBy, "class='form-control picker-select' data-drop-width='auto'");?>' style='overflow:visible'>closedBy, "class='form-control picker-select' data-drop-width='auto'");?>> - closedReason; - if(!empty($closedReason)) - { - $reasonList[$closedReason] = $lang->task->reasonList[$closedReason]; - } - else - { - $status = $task->status; - if($status == 'done' or $status == 'cancel') - { - $reasonList[$status] = $lang->task->reasonList[$status]; - } - else - { - $reasonList = $lang->task->reasonList; - } - } - - echo html::select("closedReason[$taskID]", $reasonList, $closedReason, 'class=form-control'); - ?> -
        - - -
        -
        -
        - -
        - diff --git a/module/task/view/cancel.html.php b/module/task/view/cancel.html.php deleted file mode 100644 index 3aaa454e60..0000000000 --- a/module/task/view/cancel.html.php +++ /dev/null @@ -1,50 +0,0 @@ - - * @package task - * @version $Id: cancel.html.php 935 2010-07-06 07:49:24Z jajacn@126.com $ - * @link https://www.zentao.net - */ -?> - - -
        -
        -
        -

        - id;?> - name'>" . $task->name . '') : html::a($this->createLink('task', 'view', 'task=' . $task->id), $task->name);?> - - arrow . $lang->task->cancel;?> - -

        -
        - -
        - - - - - - printExtendFields($task, 'table');?> - - - - - - - -
        task->status;?>
        comment;?>
        - save);?> - goback, $this->session->taskList);?> -
        -
        -
        -
        -
        -
        - diff --git a/module/task/view/close.html.php b/module/task/view/close.html.php deleted file mode 100644 index 2d8debaa84..0000000000 --- a/module/task/view/close.html.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @package task - * @version $Id: cancel.html.php 935 2010-07-06 07:49:24Z jajacn@126.com $ - * @link https://www.zentao.net - */ -?> - - -
        -
        -
        -

        - id;?> - name'>" . $task->name . '') : html::a($this->createLink('task', 'view', 'task=' . $task->id), $task->name);?> - - arrow . $lang->task->close;?> - -

        -
        -
        - - - - - - printExtendFields($task, 'table');?> - - - - - - - -
        task->status;?>
        comment;?>
        - task->close);?> - goback, $this->session->taskList);?> -
        -
        -
        -
        -
        -
        - diff --git a/module/task/view/create.html.php b/module/task/view/create.html.php deleted file mode 100644 index d0939de118..0000000000 --- a/module/task/view/create.html.php +++ /dev/null @@ -1,357 +0,0 @@ - - * @package task - * @version $Id: create.html.php 5090 2013-07-10 05:49:24Z zhujinyonging@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - -id));?> - -id);?> -task->ditto);?> -task->error->teamMember);?> -vision);?> -task->create->requiredFields);?> -error->gt, $lang->task->estimate, '0'))?> -lifetime);?> -attribute);?> - - -hasProduct);?> -task->create->requiredFields) as $field) -{ - if($field) $requiredFields[$field] = ''; - if($field and strpos($showFields, $field) === false) $showFields .= ',' . $field; -} -?> - -
        -
        -
        -

        task->create;?>

        -
        - createLink('custom', 'ajaxSaveCustomFields', 'module=task§ion=custom&key=createFields')?> - -
        -
        -
        - - type != 'kanban' or $this->config->vision == 'lite'):?> - - - - - - - - - - - - - - - - - - - - - - type == 'kanban'):?> - - - - - - - - - - - - - - printExtendFields('', 'table', 'columns=3');?> - - - - - - lifetime != 'ops' and !in_array($execution->attribute, array('request', 'review'))):?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        task->execution;?>id, "class='form-control chosen' onchange='loadAll(this.value)' required");?>
        task->type;?>task->typeList, $task->type, "class='form-control chosen' onchange='setOwners(this.value)' required");?> - -
        task->module;?>module, "class='form-control chosen' onchange='setStories(this.value, $execution->id)'");?> -
        - > -
        -
        task->assignedTo;?> -
        - assignedTo, "class='form-control chosen'");?> - team)) - { - foreach($task->team as $team) $teamMember .= ' ' . zget($members, $team->account); - } - ?> - - -
        -
        -
        - -
        - - -
        kanbancard->region;?>
        kanbancard->lane;?>
        task->status;?>
        task->story;?> - - task->noticeLinkStory, html::a($this->createLink('execution', 'linkStory', "executionID=$execution->id"), $lang->execution->linkStory, '', 'class="text-primary"'), html::a("javascript:loadStories($execution->id)", $lang->refresh, '', 'class="text-primary"')); - if(empty($execution->hasProduct)) $noticeLinkStory = $lang->task->noticeLinkStoryNoProduct; - echo $noticeLinkStory; - ?> - -
        - story, "class='form-control chosen' onchange='setStoryRelated();'");?> - - preview;?> - -
        -
        task->name;?> -
        -
        -
        -
        - - - -
        - name, "class='form-control' required");?> - task->copyStoryTitle;?> - -
        - - task->pri;?> - task->priList as $priKey => $priValue) - { - if(!empty($priKey) and (string)$priKey != (string)$priValue) - { - $hasCustomPri = true; - break; - } - } - $priList = $lang->task->priList; - if(end($priList)) unset($priList[0]); - if(!isset($priList[$task->pri])) - { - reset($priList); - $task->pri = key($priList); - } - ?> - - pri, "class='form-control $hiddenPri'");?> - -
        - - -
        - - -
        -
        - task->estimateAB;?> - -
        -
        -
        -
        -
        task->desc;?> - fetch('user', 'ajaxPrintTemplates', 'type=task&link=desc');?> - desc), "rows='10' class='form-control kindeditor'");?> -
        files;?>fetch('file', 'buildform');?>
        task->datePlan;?> -
        - estStarted, "class='form-control form-date $hiddenEstStarted estStartedBox' placeholder='{$lang->task->estStarted}'");?> - - ~ - deadline, "class='form-control form-date $hiddenDeadline deadlineBox' placeholder='{$lang->task->deadline}'");?> -
        -
        story->mailto;?> -
        - mailto), "class='form-control picker-select' data-placeholder='{$lang->chooseUsersToMail}' multiple");?> - acl != 'private') echo $this->fetch('my', 'buildContactLists');?> -
        -
        task->afterSubmit;?>task->afterChoices, !empty($task->id) ? 'toTaskList' : 'continueAdding');?>
        - - goback, '', 'class="btn btn-wide"') : html::backButton();?> -
        - - -
        -
        -
        - - - - - - - - - - - -isINT) and class_exists('common')) ? common::convert2Pinyin($testStories) : array());?> - -id);?> -type);?> - - - diff --git a/module/task/view/edit.html.php b/module/task/view/edit.html.php deleted file mode 100644 index 6c7990437d..0000000000 --- a/module/task/view/edit.html.php +++ /dev/null @@ -1,310 +0,0 @@ - - * @package task - * @version $Id: edit.html.php 4897 2013-06-26 01:13:16Z wyd621@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - - -story);?> -assignedTo);?> -execution);?> -consumed);?> -status);?> -user->account);?> -members);?> - - -task->confirmChangeExecution);?> -task->error->teamMember);?> -lang->task->error->leftEmptyAB, $this->lang->task->statusList[$task->status]));?> -error->gt, $lang->task->estimate, '0'))?> -error->gt, $lang->task->left, '0'))?> -task->edit->requiredFields);?> -task->edit->requiredFields) as $field) -{ - if($field) $requiredFields[$field] = ''; -} -?> -
        -
        -
        -

        - id;?> - createLink('task', 'view', "taskID=$task->id"), $task->name, '', "class='task-name'");?> - arrow . $lang->task->edit;?> -

        -
        -
        -
        -
        -
        -
        task->name;?>
        -
        -
        -
        -
        - - - -
        - name, 'class="form-control task-name" placeholder="' . $lang->task->name . '"');?> -
        -
        -
        -
        -
        -
        task->desc;?>
        -
        - desc), "rows='8' class='form-control'");?> -
        -
        -
        -
        comment;?>
        -
        -
        - printExtendFields($task, 'div', 'position=left');?> -
        -
        files;?>
        -
        - fetch('file', 'printFiles', array('files' => $task->files, 'fieldset' => 'false', 'object' => $task, 'method' => 'edit'));?> - fetch('file', 'buildform');?> -
        -
        -
        - lastEditedDate);?> - consumed);?> - - -
        - -
        -
        -
        -
        -
        -
        task->legendBasic;?>
        - - parent <= 0 and $execution->multiple):?> - - - - - - execution);?> - - - - - - lifetime != 'ops' and !in_array($execution->attribute, array('request', 'review'))):?> - - - - - - parent >= 0 and empty($task->team)):?> - - - - - - - - - - - - team) and $task->mode == 'linear') ? "disabled='disabled'" : '';?> - team)) - { - $teamAccounts = $task->members; - foreach($teamAccounts as $teamAccount) - { - if(!isset($members[$teamAccount])) continue; - $taskMembers[$teamAccount] = $members[$teamAccount]; - } - } - else - { - $taskMembers = $members; - } - ?> - - - - - - - children)):?> - - - - - - - - - - - - - -
        task->execution;?>execution, 'class="form-control chosen" onchange="loadAll(this.value)"');?>
        task->module;?> -
        - module, 'class="form-control chosen"');?> - -
        - > -
        -
        -
        -
        task->story;?>story, "class='form-control chosen' data-drop_direction='down' data-max_drop_width='0'");?>
        task->parent;?>parent, "class='form-control chosen'");?>
        task->mode;?> - status == 'wait' and $task->parent == 0) - { - echo html::select('mode', $lang->task->editModeList, $task->mode, "class='form-control chosen'"); - } - else - { - if($task->mode == '') - { - echo $lang->task->editModeList['single']; - } - else - { - echo zget($lang->task->editModeList, $task->mode); - } - } - ?> -
        task->assignedTo;?> -
        - mode != '' ? '' : 'hidden';?> - assignedTo, "class='form-control chosen' {$disableAssignedTo}");?> - task->team;?> -
        -
        task->type;?>task->typeList, $task->type, "class='form-control chosen'");?>
        task->status;?>task->statusList, $task->status, "class='form-control chosen'");?>
        task->pri;?>task->priList, $task->pri, "class='form-control chosen'");?>
        task->mailto;?> -
        - mailto, 'class="form-control picker-select" multiple data-drop-direction="bottom"');?> - fetch('my', 'buildContactLists');?> -
        -
        -
        -
        -
        task->legendEffort;?>
        - - - - - - - - - - - - - - - - - - - - - -
        task->estStarted;?>estStarted, "class='form-control form-date'");?>
        task->deadline;?>deadline, "class='form-control form-date'");?>
        task->estimate;?> - team) or $task->parent < 0) ? "readonly" : '';?> - estimate, "class='form-control' {$readonly}");?> -
        task->consumed;?>' . $task->consumed . ' '; common::printIcon('task', 'recordWorkhour', "taskID=$task->id", $task, 'list', '', '', 'record-estimate-toggle btn-link', true);?>
        task->left;?>left, "class='form-control' {$readonly}");?>
        -
        -
        -
        task->legendLife;?>
        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        task->openedBy;?>openedBy);?>
        task->realStarted;?>realStarted) ? '' : $task->realStarted, "class='form-control form-datetime'");?>
        task->finishedBy;?>finishedBy, "class='form-control chosen'");?>
        task->finishedDate;?>finishedDate, 'class="form-control form-datetime"');?>
        task->canceledBy;?>canceledBy, 'class="form-control chosen"');?>
        task->canceledDate;?>canceledDate, 'class="form-control form-datetime"');?>
        task->closedBy;?>closedBy, 'class="form-control chosen"');?>
        task->closedReason;?>task->reasonList, $task->closedReason, 'class="form-control chosen"');?>
        task->closedDate;?>closedDate, 'class="form-control form-datetime"');?>
        -
        - printExtendFields($task, 'div', 'position=right');?> -
        -
        -
        - -
        -
        -id);?> - diff --git a/module/task/view/editeffort.html.php b/module/task/view/editeffort.html.php deleted file mode 100644 index f866eb75a3..0000000000 --- a/module/task/view/editeffort.html.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @package task - * @version $Id: editestimate.html.php 4263 2013-02-24 08:50:46Z zhujinyonging@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -task->confirmRecord);?> - -
        -
        -
        -

        task->editEffort;?>

        -
        -
        - - - - - - - - - - - - - isLast ? '' : 'readonly';?> - team) and $estimate->left == 0) $readonly = 'readonly';?> - - - - - - - - - -
        task->date;?>date, 'class="form-control form-date"');?>
        task->record;?>consumed, 'class="form-control"');?>
        task->left;?>left, "class='form-control' {$readonly}");?>
        comment;?>work, "class=form-control");?>
        -
        -
        -
        -isLast):?> - - - diff --git a/module/task/view/export.html.php b/module/task/view/export.html.php deleted file mode 100755 index 968c095610..0000000000 --- a/module/task/view/export.html.php +++ /dev/null @@ -1,13 +0,0 @@ - - * @package task - * @version $Id$ - * @link https://www.zentao.net - */ -?> - diff --git a/module/task/view/finish.html.php b/module/task/view/finish.html.php deleted file mode 100644 index 4e03659adc..0000000000 --- a/module/task/view/finish.html.php +++ /dev/null @@ -1,137 +0,0 @@ - - * @package task - * @version $Id: complete.html.php 935 2010-07-06 07:49:24Z jajacn@126.com $ - * @link https://www.zentao.net - */ -?> - - - - -task->error->consumedEmptyAB);?> -
        -
        - members) and (!isset($task->members[$app->user->account]) or ($task->assignedTo != $app->user->account and $task->mode == 'linear'))):?> -
        - -
        - assignedTo != $app->user->account and $task->mode == 'linear'):?> -

        task->deniedNotice, '' . $task->assignedToRealName . '', $lang->task->finish);?>

        - -

        task->deniedNotice, '' . $lang->task->teamMember . '', $lang->task->finish);?>

        - -
        -
        - -
        -

        - id;?> - name'>" . $task->name . '') : html::a($this->createLink('task', 'view', 'task=' . $task->id), $task->name);?> - - arrow . $lang->task->finish;?> - -

        -
        -
        - - - - - - - team)):?> - - - - - - - - - - - - - '> - - - - - - - - - - - - - - - - - printExtendFields($task, 'table', 'columns=2');?> - - - - - - - - - - - -
        team) ? $lang->task->common . $lang->task->consumed : $lang->task->hasConsumed;?>consumed;?> workingHour;?>
        task->my . $lang->task->hasConsumed;?>myConsumed;?> workingHour;?>
        task->currentConsumed;?> -
        task->hour;?>
        -
        -
        -
        team) ? $lang->task->consumed : $lang->task->myConsumed;?>
        -
        - team) ? $task->consumed : (float)$task->myConsumed;?> - " . (float)$consumed . " " . $lang->workingHour . html::hidden('consumed', $consumed); - js::set('consumed', $consumed); - ?> -
        -
        -
        task->assign;?> - team) and $task->mode == 'linear') - { - echo zget($members, $task->nextBy) . html::hidden('assignedTo', $task->nextBy); - } - else - { - echo html::select('assignedTo', $members, $task->nextBy, "class='form-control chosen'"); - } - ?> -
        task->realStarted;?> -
        - realStarted, 0, 19); - $readonly = 'readonly'; - if(helper::isZeroDate($realStarted)) - { - $realStarted = ''; - $readonly = ''; - } - ?> - -
        -
        task->finishedDate;?>
        task->status;?>
        files;?>fetch('file', 'buildform');?>
        comment;?>
        - task->finish);?> - goback, $this->session->taskList, 'self', '', 'btn btn-wide');?> -
        -
        -
        -
        - -
        -
        - diff --git a/module/task/view/pause.html.php b/module/task/view/pause.html.php deleted file mode 100644 index a067c50703..0000000000 --- a/module/task/view/pause.html.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @package task - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -
        -
        - members) and (!isset($task->members[$app->user->account]) or ($task->assignedTo != $app->user->account and $task->mode == 'linear'))):?> -
        - -
        - assignedTo != $app->user->account and $task->mode == 'linear'):?> -

        task->deniedNotice, '' . $task->assignedToRealName . '', $lang->task->pause);?>

        - -

        task->deniedNotice, '' . $lang->task->teamMember . '', $lang->task->pause);?>

        - -
        -
        - -
        -

        - id;?> - name'>" . $task->name . '') : html::a($this->createLink('task', 'view', 'task=' . $task->id), $task->name);?> - - arrow . $lang->task->pause;?> - -

        -
        - -
        - - - - - - printExtendFields($task, 'table');?> - - - - - - - -
        task->status;?>
        comment;?>
        - - goback, $this->session->taskList, 'self', '', 'btn btn-wide');?> -
        -
        -
        -
        - -
        -
        - diff --git a/module/task/view/recordworkhour.html.php b/module/task/view/recordworkhour.html.php deleted file mode 100644 index 8ad159fc6c..0000000000 --- a/module/task/view/recordworkhour.html.php +++ /dev/null @@ -1,183 +0,0 @@ - - * @package task - * @version $Id: record.html.php 935 2013-01-08 07:49:24Z wwccss@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -task->foldEffort);?> -task->unfoldEffort);?> -id);?> -task->canOperateEffort($task) and empty($myOrders)):?> - - -members;?> -task->confirmRecord; -if(!empty($members) && $task->mode == 'linear') -{ - $nextAccount = ''; - $isCurrent = false; - foreach($task->team as $taskTeam) - { - if($isCurrent) - { - $nextAccount = $taskTeam->account; - break; - } - if($task->assignedTo == $taskTeam->account and $taskTeam->account == $app->user->account and $taskTeam->status != 'done') $isCurrent = true; - } - if($nextAccount) $confirmRecord = sprintf($lang->task->confirmTransfer, zget($users, $nextAccount)); -} -?> - -task->noticeSaveRecord);?> - -
        -
        -
        -

        - id;?> - name'>" . $task->name . '') : html::a($this->createLink('task', 'view', 'task=' . $task->id), $task->name);?> -

        - - - arrow . $lang->task->logEfforts;?> - -
        - - team) and $task->mode == 'linear'):?> - - - - - - id&from=$from&orderBy=%s";?> - - - - - - - - - - - - 3) ? 'hidden' : ''?> - - - - - - - - - - - -
        task->date);?>task->recordedBy;?>task->work;?>task->consumed;?>task->left;?>actions;?>
        date;?>account);?>work;?>consumed . ' ' . $lang->execution->workHourUnit;?>left . ' ' . $lang->execution->workHourUnit;?> - task->canOperateEffort($task, $effort); - common::printIcon('task', 'editEffort', "effortID=$effort->id", '', 'list', 'edit', '', 'showinonlybody', true, $canOperateEffort ? '' : 'disabled'); - common::printIcon('task', 'deleteWorkhour', "effortID=$effort->id", '', 'list', 'trash', 'hiddenwin', 'showinonlybody', false, $canOperateEffort ? '' : 'disabled'); - ?> -
        - 3):?> -
        - - task->unfoldEffort : $lang->task->foldEffort;?> - - -
        - - - - task->canOperateEffort($task) and empty($myOrders)):?> -
        - -
        - members[$app->user->account])):?> -

        task->deniedNotice, '' . $lang->task->teamMember . '', $lang->task->logEfforts);?>

        - assignedTo != $app->user->account and $task->mode == 'linear'):?> -

        task->deniedNotice, '' . $task->assignedToRealName . '', $lang->task->logEfforts);?>

        - -
        -
        - - - -
        -
        - 3):?> - - - diff --git a/module/task/view/report.html.php b/module/task/view/report.html.php deleted file mode 100644 index de2cf883d7..0000000000 --- a/module/task/view/report.html.php +++ /dev/null @@ -1,90 +0,0 @@ - - * @package execution - * @version $Id: report.html.php 1594 2011-04-10 11:00:00Z wj $ - * @link https://www.zentao.net - */ -?> - - -
        -
        -
        -
        -
        task->report->select;?>
        -
        -
        -
        -
        - task->report->charts, $checkedCharts, '', 'block')?> -
        -
        - - task->report->create, "", 'btn btn-primary');?> -
        -
        -
        -
        -
        -
        -
        -
        - report->typeList as $type => $typeName):?> - " : " ") . $typeName, '', "class='btn btn-link " . ($type == $chartType ? 'btn-active-line' : '') . "'")?> - -
        -
        execution->unclosed . $lang->task->common, $lang->report->notice->help);?>
        - $chartOption):?> -
        -
        -
        -

        task->report->charts[$chartType];?>

        -
        -
        -
        -
        -
        - - - - - - - - - - $data):?> - - - - - percent * 100;?> - - - - - -
        task->report->$chartType->item;?>task->report->value;?>report->percent;?>
        name;?>value;?>
        -
        -
        -
        - -
        -
        -
        - - - diff --git a/module/task/view/restart.html.php b/module/task/view/restart.html.php deleted file mode 100644 index 11a2a84683..0000000000 --- a/module/task/view/restart.html.php +++ /dev/null @@ -1,14 +0,0 @@ - - * @package task - * @version $Id: start.html.php 935 2010-07-06 07:49:24Z jajacn@126.com $ - * @link https://www.zentao.net - */ -?> -task->start = $lang->task->restart;?> - diff --git a/module/task/view/start.html.php b/module/task/view/start.html.php deleted file mode 100644 index de283269b5..0000000000 --- a/module/task/view/start.html.php +++ /dev/null @@ -1,121 +0,0 @@ - - * @package task - * @version $Id: start.html.php 935 2010-07-06 07:49:24Z jajacn@126.com $ - * @link https://www.zentao.net - */ -?> - - - -task->confirmFinish);?> -task->noticeTaskStart);?> -
        - members) and (!isset($task->members[$app->user->account]) or ($task->assignedTo != $app->user->account and $task->mode == 'linear'))): - ?> -
        - -
        - assignedTo != $app->user->account and $task->mode == 'linear'):?> -

        task->deniedNotice, '' . $task->assignedToRealName . '', $lang->task->start);?>

        - -

        task->deniedNotice, '' . $lang->task->teamMember . '', $lang->task->start);?>

        - -
        -
        - -
        -
        -

        - id;?> - name'>" . $task->name . '') : html::a($this->createLink('task', 'view', 'task=' . $task->id), $task->name);?> - - arrow . $lang->task->start;?> - -

        -
        -
        rawMethod == 'start') echo "onsubmit='return checkLeft();'"?>> - - '> - - - - - - - - - - - team) ? $this->task->getTeamByAccount($task->team) : ''; - $consumed = !empty($currentTeam) ? (float)$currentTeam->consumed : $task->consumed; - $lblConsumed = $lang->task->consumed; - $readonly = ''; - if($app->rawMethod == 'restart' and !empty($currentTeam)) - { - $lblConsumed = $lang->task->myConsumed; - $readonly = 'readonly'; - } - elseif($app->rawMethod == 'start' and $task->mode == 'linear') - { - $lblConsumed = $lang->task->myConsumed; - } - ?> - - - - - - - - - - - - printExtendFields($task, 'table', 'columns=2');?> - - - - - - - -
        task->assignedTo;?> - mode == 'linear') - { - echo zget($members, $assignedTo) . html::hidden('assignedTo', $assignedTo); - } - else - { - echo html::select('assignedTo', $members, $assignedTo, "class='form-control chosen'"); - } - ?> -
        task->realStarted;?>
        realStarted) ? helper::now() : $task->realStarted, "class='form-control form-datetime' data-picker-position='bottom-right'");?>
        -
        - task->hour;?> -
        -
        task->left;?> -
        - left : $task->left;?> - task->hour;?> -
        -
        task->status;?>
        comment;?>
        - task->start);?> - goback, $this->session->taskList, 'self', '', 'btn btn-wide');?> -
        -
        -
        -
        -
        - -
        - diff --git a/module/task/view/taskteam.html.php b/module/task/view/taskteam.html.php deleted file mode 100644 index 6e23197416..0000000000 --- a/module/task/view/taskteam.html.php +++ /dev/null @@ -1,364 +0,0 @@ -config->maxCount;?> -config->maxCount = 500;?> - -rawMethod != 'create'):?> - - -rawMethod == 'assignto'):?> - - -mode) or $task->mode == 'linear') ? '' : 'hidden';?> - -team)):?> -team as $member):?> -status; -if($memberStatus == 'done') $memberDisabled = true; -if($memberStatus != 'wait' and $task->mode == 'linear') $sortDisabled = true; -if($memberStatus == 'done' and $task->mode == 'multi') $sortDisabled = true; -if(strpos('|closed|cancel|pause|', $task->status) !== false and $app->rawMethod != 'activate') -{ - $memberStatus = $task->status; - $memberDisabled = true; - $sortDisabled = true; -} - -$hourDisabled = $memberDisabled; -if($task->mode == 'multi' and $app->rawMethod == 'activate') $hourDisabled = false; -?> - - - - - - - account, "class='form-control chosen' data-placeholder='{$lang->task->assignedTo}'" . ($memberDisabled ? ' disabled' : ''))?> - account);?> - account);?> - - - rawMethod == 'create'):?> -
        - estimate, "class='form-control text-center' placeholder='{$lang->task->estimateAB}'") ?> - -
        - -
        -
        - estimate, "class='form-control text-center' placeholder='{$lang->task->estimate}'" . ($hourDisabled ? ' readonly' : ''))?> - -
        -
        - consumed, "class='form-control text-center' readonly placeholder='{$lang->task->consumed}'")?> - -
        -
        - left, "class='form-control text-center' placeholder='{$lang->task->left}'" . ($hourDisabled ? ' readonly' : ''))?> - -
        -
        - - - - - - mode) and $task->mode == 'linear'):?> - - - - - - - - - - - - - - task->assignedTo}'")?> - - - - team) or $app->rawMethod == 'create'):?> -
        - task->estimateAB}'") ?> - -
        - -
        -
        - task->estimate}'")?> - -
        -
        - task->consumed}'")?> - -
        -
        - task->left}'")?> - -
        -
        - - - - - - mode) or $task->mode == 'linear'):?> - - - - -team) and count($task->team) < 6) ? 6 - count($task->team) : 1;?> -status) and $task->status != 'wait' and $task->status != 'doing') $newRowCount = 0;?> - -mode) and $task->mode == 'linear') js::set('sortSelector', 'tr.member-wait');?> -task->error->teamMember);?> -status)):?> -status);?> -lang->task->error->leftEmptyAB, $this->lang->task->statusList[$task->status]));?> -rawMethod == 'edit' and $task->mode == 'linear'):?> - - -
        task->noticeManageTeam, zget($lang->task->statusList, $task->status));?>
        - - - - - -config->maxCount = $oldMaxCount;?> diff --git a/module/task/view/view.html.php b/module/task/view/view.html.php deleted file mode 100644 index 53db8ee0ee..0000000000 --- a/module/task/view/view.html.php +++ /dev/null @@ -1,448 +0,0 @@ - - * @package task - * @version $Id: view.html.php 4808 2013-06-17 05:48:13Z zhujinyonging@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -session->taskList != false ? $app->session->taskList : $this->createLink('execution', 'browse', "executionID=$task->execution");?> - - - -app->getViewType() == 'xhtml'):?> -
        - - -
        -
        -
        -
        -
        task->legendDesc;?>
        -
        - desc) ? $task->desc : "
        " . $lang->noData . '
        ';?> -
        -
        - lifetime != 'ops'):?> - fromBug != 0):?> -
        -
        bug->steps;?>
        -
        - bugSteps) ? $task->bugSteps : "
        " . $lang->noData . '
        ';?> -
        -
        - story):?> -
        -
        task->storySpec;?>
        -
        - storySpec) || !empty($task->storyFiles)) ? $task->storySpec : "
        " . $lang->noData . '
        ';?> -
        - fetch('file', 'printFiles', array('files' => $task->storyFiles, 'fieldset' => 'false', 'object' => $task, 'method' => 'view', 'showDelete' => false));?> -
        -
        -
        task->storyVerify;?>
        -
        - storyVerify) ? $task->storyVerify : "
        " . $lang->noData . '
        ';?> -
        -
        - - cases) and $task->cases):?> -
        -
        task->case;?>
        -
        -
          - cases as $caseID => $case) echo '
        • ' . html::a($this->createLink('testcase', 'view', "caseID=$caseID", '', true), "#$caseID " . $case, '', isonlybody() ? '' : "data-toggle='modal' data-type='iframe' data-width='90%'") . '
        • ';?> -
        -
        -
        - - - children)):?> -
        -
        lang->task->children;?>
        -
        - - - - - - - - - - - - - - - - children as $child):?> - - - - - - - - - - - - - -
        task->id;?> task->lblPri;?> task->name;?>task->deadline;?> task->assignedTo;?> task->status;?>task->consumedAB . $lang->task->lblHour;?>task->leftAB . $lang->task->lblHour;?>actions;?>
        id;?>pri) echo "" . zget($this->lang->task->priList, $child->pri, $child->pri) . "";?>id", '', true); ?>">name;?>deadline;?>task->printAssignedHtml($child, $users);?>processStatus('task', $child);?>consumed;?>left;?> - id", $child, 'list', '', '', 'iframe showinonlybody', true); - common::printIcon('task', 'finish', "taskID=$child->id", $child, 'list', '', '', 'iframe showinonlybody', true); - common::printIcon('task', 'close', "taskID=$child->id", $child, 'list', '', '', 'iframe showinonlybody', true); - common::printIcon('task', 'recordWorkhour', "taskID=$child->id", $child, 'list', 'time', '', 'iframe showinonlybody', true); - common::printIcon('task', 'edit', "taskID=$child->id", $child, 'list'); - common::printIcon('task', 'activate', "taskID=$child->id", $child, 'list', '', '', 'iframe showinonlybody', true); - ?> -
        -
        -
        - - fetch('file', 'printFiles', array('files' => $task->files, 'fieldset' => 'true', 'object' => $task, 'method' => 'view', 'showDelete' => false)); - - $canBeChanged = common::canBeChanged('task', $task); - if($canBeChanged) $actionFormLink = $this->createLink('action', 'comment', "objectType=task&objectID=$task->id"); - ?> -
        - printExtendFields($task, 'div', "position=left&inForm=0&inCell=1");?> - app->getViewType() != 'xhtml'):?> -
        - -
        -
        - app->getViewType() != 'xhtml'):?> - ' . $lang->goback, '', "class='btn'");?> -
        ";?> - - executionList = $execution;?> - task->buildOperateMenu($task, 'view');?> -
        -
        -
        -
        -
        -
        - -
        -
        - - - multiple):?> - - - - - - - - name . '/'; - echo $product->name . $lang->arrow; - } - foreach($modulePath as $key => $module) - { - $moduleTitle .= $module->name; - if(!common::printLink('execution', 'task', "executionID=$task->execution&browseType=byModule¶m=$module->id", $module->name)) echo $module->name; - if(isset($modulePath[$key + 1])) - { - $moduleTitle .= '/'; - echo $lang->arrow; - } - } - } - $printModule = ob_get_contents(); - ob_end_clean(); - ?> - - - lifetime != 'ops'):?> - - - - - - fromBug):?> - - - - - - - - - - mode):?> - - - - - - - - - - - - - - - - - - - - - - - - - - -
        task->execution;?> - config->vision == 'lite' ? 'kanban' : 'view'; - if($execution->type != 'kanban') - { - common::printLink('execution', $method, "executionID={$task->execution}", $execution->name); - } - else - { - echo $execution->name; - } - ?> -
        task->module;?>
        task->story;?> - storyTitle) echo $lang->noData; - $class = isonlybody() ? 'showinonlybody' : 'iframe'; - if($task->storyTitle and !common::printLink('execution', 'storyView', "storyID=$task->story", $task->storyTitle, '', "class=$class data-width='80%'", true, true)) echo $task->storyTitle; - if($task->needConfirm) - { - echo "({$lang->story->changed} "; - echo html::a($this->createLink('task', 'confirmStoryChange', "taskID=$task->id"), $lang->confirm, 'hiddenwin', "class='btn btn-mini btn-info'"); - echo ")"; - } - ?> -
        task->fromBug;?>createLink('bug', 'view', "bugID=$task->fromBug", '', true), "#$task->fromBug " . $fromBug->title, '', "class='iframe' data-width='80%'");?>
        task->assignedTo;?> - team) and $task->mode == 'multi' and strpos('done,cancel,closed', $task->status) === false) - { - foreach($task->team as $member) echo ' ' . zget($users, $member->account); - } - else - { - echo $task->assignedTo ? $task->assignedToRealName . $lang->at . substr($task->assignedDate, 0, 19) : $lang->noData; - } - ?> -
        task->mode;?>task->modeList, $task->mode);?>
        task->type;?>lang->task->typeList, $task->type, $task->type);?>
        task->status;?> processStatus('task', $task);?>
        task->progress;?>progress . '%';?>
        task->pri;?>pri;?>' title='task->priList, $task->pri);?>'>pri == '0' ? $lang->noData : zget($lang->task->priList, $task->pri)?>
        task->mailto;?> - mailto)) - { - echo $lang->noData; - } - else - { - foreach(explode(',', str_replace(' ', '', $task->mailto)) as $account) echo ' ' . zget($users, $account, $account); - } - ?> -
        -
        -
        - - - - - - - - - - - - - - - - - - - - - - - - - -
        task->openedBy;?>openedBy ? zget($users, $task->openedBy, $task->openedBy) . $lang->at . $task->openedDate : $lang->noData;?>
        task->finishedBy;?>finishedBy) ? zget($users, $task->finishedBy, $task->finishedBy) . $lang->at . $task->finishedDate : $lang->noData;?>
        task->canceledBy;?>canceledBy ? zget($users, $task->canceledBy, $task->canceledBy) . $lang->at . $task->canceledDate : $lang->noData;?>
        task->closedBy;?>closedBy ? zget($users, $task->closedBy, $task->closedBy) . $lang->at . $task->closedDate : $lang->noData;?>
        task->closedReason;?>closedReason ? $lang->task->reasonList[$task->closedReason] : $lang->noData;?>
        task->lastEdited;?>lastEditedBy ? zget($users, $task->lastEditedBy, $task->lastEditedBy) . $lang->at . $task->lastEditedDate : $lang->noData;?>
        -
        -
        - - - - - - - - - - - team as $member):?> - - - - - - - - -
        task->team?>task->estimateAB?>task->consumedAB?>task->leftAB?>statusAB;?>
        account);?>estimate?>consumed?>left?>task->statusList, $member->status);?>
        -
        -
        -
        -
        -
        -
        - -
        -
        - - - - - - - - - - - - - - - - - - - - - - - - - -
        task->estimate;?>estimate . $lang->workingHour;?>
        task->consumed;?>consumed, 2) . $lang->workingHour;?>
        task->left;?>left . $lang->workingHour;?>
        task->estStarted;?>estStarted;?>
        task->realStarted;?>realStarted) ? '' : substr($task->realStarted, 0, 19); ?>
        task->deadline;?> - deadline; - if(isset($task->delay)) printf($lang->task->delayWarning, $task->delay); - ?> -
        -
        -
        - - - - - - - - - -
        task->linkMR;?> - $linkMRTitle) - { - echo ($canViewMR ? html::a($this->createLink('mr', 'view', "MRID=$MRID"), "#$MRID $linkMRTitle") : "#$MRID $linkMRTitle") . '
        '; - } - ?> -
        task->linkCommit;?> - revision, 0, 10); - $commitTitle = $revision . ' ' . $commit->comment; - echo "
        -
        -
        -
        -
        - printExtendFields($task, 'div', "position=right&inForm=0&inCell=1");?> -
        -
        -app->getViewType() == 'xhtml'):?> -
        - - -
        - -
        - - - diff --git a/module/testcase/control.php b/module/testcase/control.php index 18a8dece4f..37a7b48113 100644 --- a/module/testcase/control.php +++ b/module/testcase/control.php @@ -956,13 +956,14 @@ class testcase extends control * @param int $caseID * @param string $browseType * @param int $param + * @param string $orderBy * @param int $recTotal * @param int $recPerPage * @param int $pageID * @access public * @return void */ - public function linkBugs(int $caseID, string $browseType = '', int $param = 0, int $recTotal = 0, int $recPerPage = 20, int $pageID = 1) + public function linkBugs(int $caseID, string $browseType = '', int $param = 0, string $orderBy = 'id_asc', int $recTotal = 0, int $recPerPage = 20, int $pageID = 1) { $this->loadModel('bug'); @@ -975,21 +976,24 @@ class testcase extends control /* 获取关联的bug。*/ /* Get bugs to link. */ - $bugs2Link = $this->testcase->getBugs2Link($caseID, $browseType, $queryID); + $bugs2Link = $this->testcase->getBugs2Link($caseID, $browseType, $queryID, $orderBy); /* bug 分页。*/ /* Pager. */ $this->app->loadClass('pager', true); - $recTotal = count($bugs2Link); + if(empty($recTotal)) $recTotal = count($bugs2Link); $pager = new pager($recTotal, $recPerPage, $pageID); $bugs2Link = array_chunk($bugs2Link, $pager->recPerPage); /* Assign. */ - $this->view->title = $this->lang->testcase->linkBugs; - $this->view->case = $case; - $this->view->bugs2Link = empty($bugs2Link) ? $bugs2Link : $bugs2Link[$pageID - 1]; - $this->view->users = $this->loadModel('user')->getPairs('noletter'); - $this->view->pager = $pager; + $this->view->title = $this->lang->testcase->linkBugs; + $this->view->case = $case; + $this->view->bugs2Link = empty($bugs2Link) ? $bugs2Link : $bugs2Link[$pageID - 1]; + $this->view->users = $this->loadModel('user')->getPairs('noletter'); + $this->view->pager = $pager; + $this->view->browseType = $browseType; + $this->view->param = $param; + $this->view->orderBy = $orderBy; $this->display(); } @@ -1232,14 +1236,16 @@ class testcase extends control { $this->testcaseZen->checkProducts(); // 如果不存在产品,则跳转到产品创建页面。 - if($_FILES) + if($_POST) { /* 获取上传的文件。 */ /* Get file. */ $file = $this->loadModel('file')->getUpload('file'); + if(empty($_FILES)) return $this->send(array('result' => 'fail', 'message' => $this->lang->file->errorFileFormat)); if(empty($file[0])) return $this->send(array('result' => 'fail', 'message' => $this->lang->testcase->errorFileNotEmpty)); $file = $file[0]; + if(!$file || (isset($file['extension']) && $file['extension'] != 'csv')) return $this->send(array('result' => 'fail', 'message' => $this->lang->file->errorFileFormat)); /* 移动上传的文件。 */ /* Move file. */ @@ -1953,9 +1959,14 @@ class testcase extends control */ public function importXmind(int $productID, string $branch) { - if($_FILES) + if($_POST) { - if($_FILES['file']['size'][0] == 0) return $this->send(array('result' => 'fail', 'message' => $this->lang->testcase->errorFileNotEmpty)); + $file = $this->loadModel('file')->getUpload('file'); + if(empty($_FILES)) return $this->send(array('result' => 'fail', 'message' => $this->lang->file->errorFileFormat)); + if(empty($file[0])) return $this->send(array('result' => 'fail', 'message' => $this->lang->testcase->errorFileNotEmpty)); + + $file = $file[0]; + if(!$file || (isset($file['extension']) && $file['extension'] != 'xmind')) return $this->send(array('result' => 'fail', 'message' => $this->lang->file->errorFileFormat)); /* 保存xmind配置。*/ /* Sav xmind config. */ diff --git a/module/testcase/js/showxmindimport.ui.js b/module/testcase/js/showxmindimport.ui.js index aa5325b8fb..36513336d0 100644 --- a/module/testcase/js/showxmindimport.ui.js +++ b/module/testcase/js/showxmindimport.ui.js @@ -61,7 +61,7 @@ $(document).ready(function() if(hasExist) { var confirmActions = [{btnType: 'primary', class: 'btn-wide', key: 'confirm', text: importAndCoverLang}, {class: 'btn-wide', key: 'cancel', text: importAndInsertLang}]; - zui.Modal.confirm({message: noticeImport, actions: confirmActions}).then((confirmed) => {submitXmindImport(data, confirmed ? 0 : 1);}) + zui.Modal.confirm({message: noticeImport, actions: confirmActions, onResult: (confirmed) => {submitXmindImport(data, confirmed ? 0 : 1);}}); return; } diff --git a/module/testcase/model.php b/module/testcase/model.php index a88d1193c9..548d886fa7 100755 --- a/module/testcase/model.php +++ b/module/testcase/model.php @@ -674,7 +674,7 @@ class testcaseModel extends model if(dao::isError()) return false; $changes = common::createChanges($oldCase, $case); - $actionID = $this->loadModel('action')->create('case', $oldCase->id, 'Reviewed', $case->comment, ucfirst($case->result)); + $actionID = $this->loadModel('action')->create('case', $oldCase->id, 'Reviewed', $this->post->comment, ucfirst($case->result)); $this->action->logHistory($actionID, $changes); return true; } @@ -752,15 +752,16 @@ class testcaseModel extends model * @param int $caseID * @param string $browseType * @param int $queryID + * @param string $orderBy * @access public * @return array */ - public function getBugs2Link(int $caseID, string $browseType = 'bySearch', int $queryID = 0): array + public function getBugs2Link(int $caseID, string $browseType = 'bySearch', int $queryID = 0, string $orderBy = 'id_asc'): array { if($browseType != 'bySearch') return array(); $case = $this->getByID($caseID); - $bugs2Link = $this->loadModel('bug')->getBySearch('bug', $case->product, (string)$case->branch, 0, 0, (int)$queryID, '', 'id'); + $bugs2Link = $this->loadModel('bug')->getBySearch('bug', $case->product, (string)$case->branch, 0, 0, (int)$queryID, '', $orderBy); foreach($bugs2Link as $key => $bug2Link) { if($bug2Link->case != 0) unset($bugs2Link[$key]); @@ -1487,18 +1488,21 @@ class testcaseModel extends model if(empty($projects)) return false; $this->loadModel('action'); - $projects = array_unique($projects); + $projects = array_filter(array_unique($projects)); $objectInfo = $this->dao->select('*')->from(TABLE_PROJECT)->where('id')->in($projects)->fetchAll('id', false); foreach($projects as $projectID) { + if(!isset($objectInfo[$projectID])) continue; + $lastOrder = (int)$this->dao->select('*')->from(TABLE_PROJECTCASE)->where('project')->eq($projectID)->orderBy('order_desc')->limit(1)->fetch('order'); + $lastOrder++; $data = new stdclass(); $data->project = $projectID; $data->product = $case->product; $data->case = $caseID; $data->version = 1; - $data->order = ++ $lastOrder; + $data->order = $lastOrder; $this->dao->insert(TABLE_PROJECTCASE)->data($data)->exec(); $object = $objectInfo[$projectID]; @@ -2977,7 +2981,7 @@ class testcaseModel extends model $_SESSION['searchParams']['module'] = 'testcase'; $searchConfig = $this->loadModel('search')->processBuildinFields('testcase', $this->config->testcase->search); - $searchConfig['params'] = $this->search->setDefaultParams($searchConfig['fields'], $searchConfig['params']); + $searchConfig['params'] = $this->search->setDefaultParams('testcase', $searchConfig['fields'], $searchConfig['params']); return $searchConfig; } diff --git a/module/testcase/test/lib/testcasezen.unittest.class.php b/module/testcase/test/lib/testcasezen.unittest.class.php new file mode 100644 index 0000000000..3c9c3b7834 --- /dev/null +++ b/module/testcase/test/lib/testcasezen.unittest.class.php @@ -0,0 +1,32 @@ +tester = $tester; + $tester->app->setModuleName('testcase'); + + $this->objectModel = $tester->loadModel('testcase'); + $this->testcaseZenTest = initReference('testcase'); + } + + /** + * 构建从用例库导入的数据。 + * Build data for importing from lib. + * + * @param int $productID + * @param string $branch + * @param int $libID + * @param array $postData + * @access public + * @return array + */ + public function buildDataForImportFromLibTest(int $productID, string $branch, int $libID, array $postData): array + { + foreach($postData as $key => $value) $_POST[$key] = $value; + return callZenMethod('testcase', 'buildDataForImportFromLib', [$productID, $branch, $libID]); + } +} diff --git a/module/testcase/test/model/getbugs2link.php b/module/testcase/test/model/getbugs2link.php index 6bcf713df7..5879332b2a 100755 --- a/module/testcase/test/model/getbugs2link.php +++ b/module/testcase/test/model/getbugs2link.php @@ -3,8 +3,17 @@ include dirname(__FILE__, 5) . '/test/lib/init.php'; include dirname(__FILE__, 2) . '/lib/testcase.unittest.class.php'; -zenData('bug')->gen(10); +$bug = zenData('bug'); +$bug->id->range('1-10'); +$bug->product->range('1{5},2{5}'); +$bug->project->range('0'); +$bug->execution->range('0'); +$bug->title->range('bug名称')->prefix('1-10'); +$bug->gen(10); + zenData('user')->gen(1); +zenData('case')->gen(5); +zenData('story')->gen(5); su('admin'); @@ -26,14 +35,15 @@ cid=1 */ +global $tester; $caseIDList = array(1, 2, 3); $browseTypeList = array('bySearch', ''); $testcase = new testcaseTest(); -r($testcase->getBugs2LinkTest($caseIDList[0], $browseTypeList[0])) && p() && e('1,2,3'); // 获取相关的 case 1 browse bySearch bug -r($testcase->getBugs2LinkTest($caseIDList[1], $browseTypeList[0])) && p() && e('1,2,3'); // 获取相关的 case 2 browse bySearch bug -r($testcase->getBugs2LinkTest($caseIDList[2], $browseTypeList[0])) && p() && e('1,2,3'); // 获取相关的 case 3 browse bySearch bug +r($testcase->getBugs2LinkTest($caseIDList[0], $browseTypeList[0])) && p() && e('1,2,3,4,5'); // 获取相关的 case 1 browse bySearch bug +r($testcase->getBugs2LinkTest($caseIDList[1], $browseTypeList[0])) && p() && e('1,2,3,4,5'); // 获取相关的 case 2 browse bySearch bug +r($testcase->getBugs2LinkTest($caseIDList[2], $browseTypeList[0])) && p() && e('1,2,3,4,5'); // 获取相关的 case 3 browse bySearch bug r($testcase->getBugs2LinkTest($caseIDList[0], $browseTypeList[1])) && p() && e('0'); // 获取相关的 case 1 browse 空 bug r($testcase->getBugs2LinkTest($caseIDList[1], $browseTypeList[1])) && p() && e('0'); // 获取相关的 case 2 browse 空 bug diff --git a/module/testcase/test/model/review.php b/module/testcase/test/model/review.php index f23ee9f69f..71ed661c3d 100755 --- a/module/testcase/test/model/review.php +++ b/module/testcase/test/model/review.php @@ -5,6 +5,7 @@ include dirname(__FILE__, 2) . '/lib/testcase.unittest.class.php'; su('admin'); zenData('case')->gen(10); +zenData('story')->gen(10); /** diff --git a/module/testcase/test/zen/builddataforimportfromlib.php b/module/testcase/test/zen/builddataforimportfromlib.php new file mode 100644 index 0000000000..982989692b --- /dev/null +++ b/module/testcase/test/zen/builddataforimportfromlib.php @@ -0,0 +1,31 @@ +#!/usr/bin/env php +loadYaml('case')->gen(20); +zenData('product')->gen(5); +zenData('user')->gen(5); +su('admin'); + +$postData = array('branch' => array(), 'caseIdList' => range(1, 20)); + +$testcaseTester = new testcaseZenTest(); +$result = $testcaseTester->buildDataForImportFromLibTest(1, 'all', 0, $postData); +r(isset($result[0])) && p() && e('1'); // 测试用例属性是否存在 +r(isset($result[1])) && p() && e('1'); // 测试用例步骤是否存在 +r(isset($result[2])) && p() && e('1'); // 测试用例文件是否存在 +r(isset($result[3])) && p() && e('1'); // 测试已导入的用例是否存在 +r($result[3]) && p('', ';') && e('1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,'); // 获取用例ID diff --git a/module/testcase/ui/linkbugs.html.php b/module/testcase/ui/linkbugs.html.php index 3e6ddb941b..aec7f04b55 100644 --- a/module/testcase/ui/linkbugs.html.php +++ b/module/testcase/ui/linkbugs.html.php @@ -31,6 +31,8 @@ dtable set::cols($config->testcase->linkbugs->dtable->fieldList), set::data($bugs2Link), set::userMap($users), + set::orderBy($orderBy), + set::sortLink(createLink('testcase', 'linkBugs', "caseID={$case->id}&browseType={$browseType}¶m={$param}&orderBy={name}_{sortType}")), set::checkable(true), set::footToolbar($footToolbar), set::footPager(usePager()) diff --git a/module/testcase/view/automation.html.php b/module/testcase/view/automation.html.php deleted file mode 100644 index dbec667246..0000000000 --- a/module/testcase/view/automation.html.php +++ /dev/null @@ -1,104 +0,0 @@ - - * @package task - * @version $Id: cancel.html.php 935 2010-07-06 07:49:24Z jajacn@126.com $ - * @link https://www.zentao.net - */ -?> - - -
        -
        -
        -

        - zanode->automation;?>  -

        -
        -
        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        testcase->product;?>
        zanode->common;?>node) ? $automation->node : '', "class='form-control picker-select'");?> - createLink('zanode', 'create'), $lang->zanode->create, '', "class='text-primary' target='_blank'");?> - ", '', "class='btn btn-icon refresh' data-toggle='tooltip' title='{$lang->refresh}' onclick='loadNodes()'");?> -
        - zanode->scriptPath;?> - scriptPath) ? $automation->scriptPath : '', "class='form-control' placeholder='{$lang->zanode->scriptTips}'");?> -
        - zanode->shell;?> - shell) ? $automation->shell : '', "rows='6' class='form-control' placeholder='{$lang->zanode->shellTips}'");?> -
        - - id);?> - -
        -
        -
        -
        - - diff --git a/module/testcase/view/batchcreate.html.php b/module/testcase/view/batchcreate.html.php deleted file mode 100644 index a4f7e1f22e..0000000000 --- a/module/testcase/view/batchcreate.html.php +++ /dev/null @@ -1,219 +0,0 @@ - - * @package testcase - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -testcase->batchCreate);?> - - -testcase->create->requiredFields)?> - -
        -
        -

        - testcase->batchCreate;?> - - arrow . $story->title ?> - -

        -
        - - createLink('custom', 'ajaxSaveCustomFields', 'module=testcase§ion=custom&key=batchCreateFields')?> - -
        -
        - testcase->create->requiredFields) as $field) - { - if($field) - { - $requiredFields[$field] = ''; - if(strpos(",{$config->testcase->list->customBatchCreateFields},", ",{$field},") !== false) $visibleFields[$field] = ''; - } - } - $colspan = count($visibleFields) + 3; - $hiddenStory = (isonlybody() and $story) ? ' hidden' : ''; - if($hiddenStory and isset($visibleFields['story'])) $colspan -= 1; - ?> -
        -
        - - - - - - - - - - - - - - - - testcase->getFlowExtendFields(); - foreach($extendFields as $extendField) - { - $required = strpos(",$extendField->rules,", ',1,') !== false ? 'required' : ''; - echo ""; - } - ?> - - - - - testcase->typeList['']);?> - testcase->batchCreate; $i++):?> - testcase->typeList['ditto'] = $lang->testcase->ditto; - if($i != 1) $lang->testcase->priList['ditto'] = $lang->testcase->ditto; - $type = $i == 1 ? 'feature' : 'ditto'; - $pri = $i == 1 ? 3 : 'ditto'; - ?> - - - - - - - - - - - - - - loadModel('flow'); - foreach($extendFields as $extendField) echo "control == 'select' or $extendField->control == 'multi-select') ? " style='overflow:visible'" : '') . ">" . $this->flow->getFieldControl($extendField, '', $extendField->field . "[$i]") . ""; - ?> - - - - - - - - - -
        idAB;?> branchBox'>product->branch;?> moduleBox'>testcase->module;?> sceneBox'>testcase->scene;?> storyBox'> testcase->story;?>testcase->title;?>testcase->type;?> priBox'>testcase->pri;?> preconditionBox'>testcase->precondition;?> keywordsBox'>testcase->keywords;?> stageBox'>testcase->stage;?> reviewBox'>testcase->review;?>{$extendField->name}actions;?>
        branchBox'> moduleBox' style='overflow:visible'>' style='overflow:visible;'> storyBox' style='overflow:visible'> id : '', 'class="form-control picker-select"');?> -
        - -
        - - - -
        -
        -
        testcase->typeList, $type, "class='form-control chosen'");?> priBox'>testcase->priList, $pri, "class='form-control chosen'");?> preconditionBox'> keywordsBox'> stageBox' style='overflow:visible'>testcase->stageList, '', "class='form-control chosen' multiple");?> reviewBox'>testcase->reviewList, $needReview, "class='form-control chosen'");?> - - - - -
        - - -
        -
        -
        -
        - - - - - - - - - - - - - - - - - loadModel('flow'); - foreach($extendFields as $extendField) echo "control == 'select' or $extendField->control == 'multi-select') ? " style='overflow:visible'" : '') . ">" . $this->flow->getFieldControl($extendField, '', $extendField->field . "[%s]") . ""; - ?> - - - -
        %s branchBox'> moduleBox' style='overflow:visible'>' style='overflow:visible'> storyBox' style='overflow:visible'> -
        - -
        - - - -
        -
        -
        testcase->typeList, $type, "class='form-control chosen'");?> priBox'>testcase->priList, $pri, "class='form-control chosen'");?> preconditionBox'> keywordsBox'> stageBox' style='overflow:visible'>testcase->stageList, '', "class='form-control chosen' multiple");?> reviewBox'>testcase->reviewList, $needReview, "class='form-control chosen'");?> - - - - -
        -
        - - - - - - - - - - - - - - - - loadModel('flow'); - foreach($extendFields as $extendField) echo "control == 'select' or $extendField->control == 'multi-select') ? " style='overflow:visible'" : '') . ">" . $this->flow->getFieldControl($extendField, '', $extendField->field . "[$i]") . ""; - ?> - - - -
        - - diff --git a/module/testcase/view/batchedit.html.php b/module/testcase/view/batchedit.html.php deleted file mode 100644 index ee2ce80de4..0000000000 --- a/module/testcase/view/batchedit.html.php +++ /dev/null @@ -1,143 +0,0 @@ - - * @package testcase - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -lang->testcase->dittoNotice);?> - - -testcase->confirmUnlinkTesttask);?> - -testcase->edit->requiredFields)?> - -
        -
        -

        testcase->common . $lang->hyphen . $lang->testcase->batchEdit;?>

        -
        - createLink('custom', 'ajaxSaveCustomFields', 'module=testcase§ion=custom&key=batchEditFields')?> - -
        -
        - -
        - - testcase->edit->requiredFields) as $field) - { - if($field) - { - $requiredFields[$field] = ''; - if(strpos(",{$config->testcase->list->customBatchEditFields},", ",{$field},") !== false) $visibleFields[$field] = ''; - } - } - ?> -
        -
        - - - - - - - - - - - - - - - - - - - - testcase->getFlowExtendFields(); - foreach($extendFields as $extendField) echo ""; - ?> - - - - - - - - - - - - - - - - - - - - - - - control == 'select' or $extendField->control == 'multi-select') ? " style='overflow:visible'" : '') . ">" . $this->loadModel('flow')->getFieldControl($extendField, $cases[$caseID], $extendField->field . "[{$caseID}]") . "";?> - - - - - - - - -
        idAB;?>'>priAB;?>'>statusAB;?>testcase->branch;?>'>testcase->module;?>'>testcase->scene;?>'>testcase->story;?>testcase->title;?>testcase->type;?>'>testcase->precondition;?>'>testcase->keywords;?>'>testcase->stage;?>{$extendField->name}
        '> pri, 'class=form-control');?>'> - status == 'wait') - { - echo $lang->testcase->statusList['wait']; - echo html::hidden("statuses[$caseID]", 'wait'); - } - else - { - echo html::select("statuses[$caseID]", (array)$lang->testcase->statusList, $cases[$caseID]->status, 'class=form-control'); - } - ?> - - product;?> - type : $products[$branchProductID]->type;?> - - branch : '', "class='form-control chosen' onchange='loadBranches($branchProductID, this.value, $caseID, {$cases[$caseID]->branch})', $disabled");?> - ' style='overflow:visible'> '/')), $cases[$caseID]->module, "class='form-control chosen' onchange='loadStories2($productID, this.value, $caseID)'");?>' style='overflow:visible'> '/')), $cases[$caseID]->scene, "class='form-control chosen' data-drop_direction='down'");?>' style='overflow:visible'>story, "class='form-control picker-select'");?> -
        -
        - title, "class='form-control'");?> -
        - - - color, "data-provide='colorpicker' data-icon='color' data-wrapper='input-control-icon-right' data-update-color='#title\\[$caseID\\]'");?> -
        -
        -
        -
        type, 'class=form-control');?>'>precondition, "rows='1' class='form-control autosize'")?>'> keywords, "class='form-control'");?>' style='overflow:visible'>testcase->stageList, $cases[$caseID]->stage, "class='form-control chosen' multiple data-placeholder='{$lang->testcase->stage}'");?>
        - - -
        -
        -
        - -
        - - diff --git a/module/testcase/view/browse.html.php b/module/testcase/view/browse.html.php deleted file mode 100644 index d80ea172dc..0000000000 --- a/module/testcase/view/browse.html.php +++ /dev/null @@ -1,586 +0,0 @@ - - * @package testcase - * @version $Id: browse.html.php 5108 2013-07-12 01:59:04Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> -session->caseBrowseType == 'bysearch') ? 'all' : $this->session->caseBrowseType); -js::set('moduleID' , $moduleID); -js::set('confirmDelete', $lang->testcase->confirmDelete); -js::set('batchDelete', $lang->testcase->confirmBatchDeleteSceneCase); -js::set('productID', $productID); -js::set('branch', $branch); -js::set('suiteID', $suiteID); -js::set('automation', !empty($automation) ? $automation->id : 0); -js::set('runCaseConfirm', $lang->zanode->runCaseConfirm); -js::set('confirmURL', $this->createLink('testtask', 'batchRun', "productID=$productID&orderBy=$orderBy&from=testcase&taskID=0&confirm=yes")); -js::set('cancelURL', $this->createLink('testtask', 'batchRun', "productID=$productID&orderBy=$orderBy&from=testcase&taskID=0&confirm=no")); -js::set('orderBy', $orderBy); -js::set('differentProduct', $lang->testcase->differentProduct); -js::set('langRowIndex', $lang->testcase->rowIndex); -js::set('langNestTotal', $lang->testcase->nestTotal); -js::set('langNormal', $lang->testcase->normal); -?> -app->tab == 'project'):?> - - - -
        - -
        -
        '>
        - - -
        -

        - cookie->onlyScene): ?> - testcase->noScene;?> - - - createLink('testcase', 'createScene', "productID=$productID&branch=$branch&moduleID=$initModule"), " " . $lang->testcase->newScene, '', "class='btn btn-info' data-app='{$this->app->tab}'");?> - - - testcase->noCase;?> - - - createLink('testcase', 'create', "productID=$productID&branch=$branch&moduleID=$initModule"), " " . $lang->testcase->create, '', "class='btn btn-info' data-app='{$this->app->tab}'");?> - - - - createLink('testsuite', 'linkCase', "suiteID=$param"), " " . $lang->testsuite->linkCase, '', "class='btn btn-info' data-app='{$this->app->tab}'");?> - - -

        -
        - - moduleName . ucfirst($this->methodName); - $useDatatable = (isset($config->datatable->$datatableId->mode) and $config->datatable->$datatableId->mode == 'datatable'); - ?> -
        > -
        - -
        - recTotal}&recPerPage={$pager->recPerPage}"; - - if($useDatatable) include '../../common/view/datatable.html.php'; - else include '../../common/view/tablesorter.html.php'; - - if($config->testcase->needReview or !empty($config->testcase->forceReview)) $config->testcase->datatable->fieldList['actions']['width'] = '190'; - $setting = $this->datatable->getSetting('testcase'); - $widths = $this->datatable->setFixedFieldWidth($setting); - $columns = 0; - - $canBatchRun = common::hasPriv('testtask', 'batchRun'); - $canBatchEdit = common::hasPriv('testcase', 'batchEdit'); - $canBatchDelete = common::hasPriv('testcase', 'batchDelete'); - $canBatchChangeType = common::hasPriv('testcase', 'batchChangeType'); - $canBatchConfirmStoryChange = common::hasPriv('testcase', 'batchConfirmStoryChange'); - $canBatchChangeModule = common::hasPriv('testcase', 'batchChangeModule'); - $canImportToLib = common::hasPriv('testcase', 'importToLib'); - $canBatchAction = ($canBatchRun or $canBatchEdit or $canBatchDelete or $canBatchChangeType or $canBatchConfirmStoryChange or $canBatchChangeModule or $canImportToLib); - ?> - ';?> - ' id='caseList' data-fixed-left-width='' data-fixed-right-width='' data-checkbox-name='caseIDList[]'> - - - $value) - { - if($value->show) - { - $this->datatable->printHead($value, $orderBy, $vars, $canBatchAction); - $columns ++; - } - } - ?> - - - - - $scene):?> - id' data-auto='$scene->auto' data-order='$scene->sort' data-parent='$scene->parent' data-product='$scene->product'"; - if($scene->isCase == 2) - { - $trAttrs .= " data-nested='true'"; - $trClass .= $scene->parent == '0' ? ' is-top-level table-nest-child-hide' : ' table-nest-hide'; - } - - if($scene->parent and isset($scenes[$scene->parent])) - { - if($scene->isCase != 2) $trClass .= ' is-nest-child'; - if(empty($scene->path)) $scene->path = $scenes[$scene->parent]->path . "$scene->id,"; - $trClass .= ' table-nest-hide'; - $trAttrs .= " data-nest-parent='$scene->parent' data-nest-path='$scene->path'"; - } - elseif($scene->isCase != 2) - { - $trClass .= ' no-nest'; - } - $trAttrs .= " class='row-case $trClass'"; - $originOrders[] = $scene->id; - ?> - > - $value) $this->testcase->printCell($value, $scene, $users, $branchOption, $modulePairs, $browseType, $useDatatable ? 'datatable' : 'table',$scene->isCase);?> - - - -
        - ';?> -
        - -getModuleRoot() . 'common/view/footer.lite.html.php';?> diff --git a/module/testcase/view/linkbugs.html.php b/module/testcase/view/linkbugs.html.php deleted file mode 100644 index 740dd5aa0b..0000000000 --- a/module/testcase/view/linkbugs.html.php +++ /dev/null @@ -1,96 +0,0 @@ - - * @package testcase - * @version $Id: linkbugs.html.php 4411 2016-03-09 11:02:04Z Chen Fei $ - * @link https://www.zentao.net - */ -?> - - -
        -
        -

        - id;?> - createLink('case', 'view', "caseID={$case->id}"), $case->title, '_blank');?> - arrow . $lang->testcase->linkBugs;?> -

        -
        -
        - -
        - - - - - - - - - - - - - - - - - - - - - - - - - -
        -
        - -
        - idAB;?> -
        pri;?>>priAB;?>bug->title;?>bug->type;?>openedByAB;?>statusAB;?>
        -
        - - -
        - id);?> -
        bug->priList, $bug2Link->pri, $bug2Link->pri)?>'>bug->priList, $bug2Link->pri, $bug2Link->pri)?>createLink('bug', 'view', "bugID=$bug2Link->id"), $bug2Link->title, '_blank');?>bug->typeList, $bug2Link->type);?>openedBy);?>
        - -
        - -
        - - diff --git a/module/testcase/view/linkcases.html.php b/module/testcase/view/linkcases.html.php deleted file mode 100644 index 3f5324b738..0000000000 --- a/module/testcase/view/linkcases.html.php +++ /dev/null @@ -1,96 +0,0 @@ - - * @package testcase - * @version $Id: linkcases.html.php 4411 2016-03-09 11:02:04Z Chen Fei $ - * @link https://www.zentao.net - */ -?> - - -
        -
        -

        - id;?> - createLink('case', 'view', "caseID={$case->id}"), $case->title, '_blank');?> - arrow . $lang->testcase->linkCases;?> -

        -
        -
        - -
        - - - - - - - - - - - - - - - - - - - - - - - - - -
        -
        - -
        - idAB;?> -
        pri;?>>priAB;?>testcase->title;?>testcase->type;?>openedByAB;?>statusAB;?>
        -
        - - -
        - id);?> -
        testcase->priList, $case2Link->pri, $case2Link->pri)?>'>testcase->priList, $case2Link->pri, $case2Link->pri)?>createLink('testcase', 'view', "caseID=$case2Link->id"), $case2Link->title, '_blank');?>testcase->typeList[$case2Link->type];?>openedBy);?>
        - -
        - -
        - - diff --git a/module/testcase/view/review.html.php b/module/testcase/view/review.html.php deleted file mode 100644 index 00eabc6b49..0000000000 --- a/module/testcase/view/review.html.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @package testcase - * @version $Id: review.html.php 4129 2013-01-18 01:58:14Z wwccss $ - * @link https://www.zentao.net - */ -?> - - - - -id);?> -
        -
        -

        - id;?> - createLink('testcase', 'view', "caseID=$case->id"), $case->title);?> -

        -
        -
        - - - - - - - - - - - - - - printExtendFields($case, 'table');?> - - - - - - - - - - - -
        testcase->reviewedDateAB;?>
        testcase->result;?>testcase->reviewResultList, '', 'class=form-control required');?>
        testcase->status;?>status);?>
        testcase->reviewedByAB;?>user->account, "class='form-control chosen' multiple");?>
        comment;?>
        -
        -
        -
        -
        - diff --git a/module/testcase/view/showimport.html.php b/module/testcase/view/showimport.html.php deleted file mode 100644 index 839315cd10..0000000000 --- a/module/testcase/view/showimport.html.php +++ /dev/null @@ -1,195 +0,0 @@ - - - - -
        - $this->config->file->maxImport):?> -
        -
        -

        testcase->import;?>

        -
        -

        file->importSummary, $allCount, html::input('maxImport', $config->file->maxImport, "style='width:50px'"), ceil($allCount / $config->file->maxImport));?>

        -

        import, "id='import'", 'btn btn-primary');?>

        -
        - - -
        -
        -

        testcase->import;?>

        -
        -
        -
        - - - - testcase->create->requiredFields;?> - - - type != 'normal'):?> - - - - - - - - - - - show) continue; - - $width = ($field->width && $field->width != 'auto' ? $field->width . 'px' : 'auto'); - $required = strpos(",$field->rules,", ",$notEmptyRule->id,") !== false ? 'required' : ''; - echo ""; - } - } - ?> - - - - - - $case):?> - title)) continue;?> - - - - - type != 'normal'):?> - branch)) $branchID = $case->branch; - if(!isset($branches[$branchID])) $branchID = $branch; - ?> - - - - - - - - - - - loadModel('flow'); - foreach($appendFields as $field) - { - if(!$field->show) continue; - $value = $field->defaultValue ? $field->defaultValue : zget($case, $field->field, ''); - echo ''; - } - } - ?> - - - - - - - - - - -
        lineNumber?>idAB?>testcase->branch?>'>testcase->title?>'>testcase->module?>'>testcase->story?>'>testcase->pri?>'>testcase->type?>'>testcase->stage?>'>testcase->precondition?>'>testcase->keywords?>$field->name - - - - - -
        testcase->stepDesc?>testcase->stepExpect?>
        -
        - id)) - { - echo $case->id . html::hidden("id[$key]", $case->id); - $insert = false; - } - else - { - echo "{$lang->testcase->new}"; - } - echo html::hidden("product[$key]", $productID); - ?> - title, ENT_QUOTES), "class='form-control'")?> - - module) ? $case->module : ((!empty($case->id) and isset($cases[$case->id])) ? $cases[$case->id]->module : ''), "class='form-control chosen moduleChange' onchange='loadStories($productID, this.value, $key)'")?> - - story) ? $case->story : ((!empty($case->id) and isset($cases[$case->id])) ? $cases[$case->id]->story : '');?> - zget($stories, $storyID, '')), $storyID, "class='form-control chosen storyChange'")?>testcase->priList, isset($case->pri) ? $case->pri : ((!empty($case->id) and isset($cases[$case->id])) ? $cases[$case->id]->pri : ''), "class='form-control chosen'")?>testcase->typeList, isset($case->type) ? $case->type : '', "class='form-control chosen'")?>testcase->stageList, !empty($case->stage) ? $case->stage : ((!empty($case->id) and isset($cases[$case->id])) ? $cases[$case->id]->stage : ''), "multiple='multiple' class='form-control chosen'")?>precondition) ? htmlSpecialString($case->precondition) : "", "class='form-control'")?>keywords) ? $case->keywords : '', "class='form-control'")?>' . $this->flow->buildControl($field, $value, "$field->field[$key]", true) . ' - - - - $desc):?> - - - - - - - - - - - - - - - -
        - - - - - - - -
        - -
        - lang->save : $this->lang->file->saveAndNext; - if(!$insert and $dataInsert === '') - { - echo ""; - } - else - { - echo html::submitButton($submitText); - if($dataInsert !== '') echo html::hidden('insert', $dataInsert); - } - echo html::hidden('isEndPage', $isEndPage ? 1 : 0); - echo html::hidden('pagerID', $pagerID); - echo html::linkButton($lang->goback, $this->inlink('browse', "productID=$productID"), 'self', '', 'btn btn-wide'); - echo sprintf($lang->file->importPager, $allCount, $pagerID, $allPager); - ?> -
        -
        - -
        -
        - - - diff --git a/module/testcase/view/showscript.html.php b/module/testcase/view/showscript.html.php deleted file mode 100644 index c44fe95d5c..0000000000 --- a/module/testcase/view/showscript.html.php +++ /dev/null @@ -1,31 +0,0 @@ - - * @package testcase - * @version $Id: showscript.html.php 4723 2022-07-28 08:47:29Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - -
        -
        -

        - id;?> - title;?> -

        -
        -
        -
        -
        script;?>
        -
        -
        -
        - diff --git a/module/testcase/view/showxmindimport.html.php b/module/testcase/view/showxmindimport.html.php deleted file mode 100644 index cd6eab91a8..0000000000 --- a/module/testcase/view/showxmindimport.html.php +++ /dev/null @@ -1,96 +0,0 @@ - - * @package case - * @version $Id: create.html.php 4904 2013-06-26 05:37:45Z wyd621@gmail.com $ - * @link https://www.zentao.net - */ -?> -getModuleRoot() . 'common/view/header.html.php';?> - - - - - - - - - - - -
        -
        -
        -

        testcase->xmindImportEdit;?>(name;?>)

        -
        - -
        -
        -
        - - - - - - - - - -
        -
        -
        - - goback, '', 'class="btn btn-wide"') : html::backButton();?> -
        -
        -
        -
        - - -getModuleRoot() . 'common/view/footer.html.php';?> diff --git a/module/testcase/view/view.html.php b/module/testcase/view/view.html.php deleted file mode 100644 index 2e4c0409fd..0000000000 --- a/module/testcase/view/view.html.php +++ /dev/null @@ -1,373 +0,0 @@ - - * @package case - * @version $Id: view.html.php 5000 2013-07-03 08:20:57Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -session->caseList ? $app->session->caseList : $this->createLink('testcase', 'browse', "productID=$case->product");?> - -tab);?> - - -
        -
        -
        - auto != 'unit' and !empty($case->precondition)):?> -
        -
        testcase->precondition;?>
        -
        precondition);?>
        -
        - -
        -
        testcase->steps;?>
        -
        - - - - - - - - - steps as $stepID => $step) - { - $stepClass = "step-{$step->type}"; - if($step->type == 'group' or $step->type == 'step') - { - $stepId++; - $childId = 0; - } - if($step->type == 'step') $stepClass = 'step-group'; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - $childId ++; - } - ?> -
        testcase->stepID;?>testcase->stepDesc;?>testcase->stepExpect;?>
        $stepId
        "; - if($step->type == 'item') echo "{$stepId}.{$childId}"; - echo nl2br(str_replace(' ', ' ', $step->desc)) . "
        " . nl2br(str_replace(' ', ' ', $step->expect)) . "
        -
        -
        - xml)):?> -
        -
        testcase->xml;?>
        -
        xml));?>
        -
        - - fetch('file', 'printFiles', array('files' => $case->files, 'fieldset' => 'true', 'object' => $case, 'method' => 'view', 'showDelete' => false));?> -
        - printExtendFields($case, 'div', "position=left&inForm=0&inCell=1");?> -
        -
        - -
        ";?> - isLibCase = $isLibCase;?> - caseFails = $caseFails;?> - runID = $from == 'testcase' ? 0 : $run->id;?> - testcase->buildOperateMenu($case, 'view');?> -
        -
        -
        -
        -
        -
        - testcase->legendBasicInfo;?> -
        - - - - - - - - - - - - '> - - - - type != 'normal'):?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        testcase->fromCase;?> - linkCaseTitles)) - { - foreach($case->linkCaseTitles as $linkCaseID => $linkCaseTitle) - { - echo html::a($this->createLink('testcase', 'view', "caseID=$linkCaseID", '', true), "#$linkCaseID $linkCaseTitle", '', "class='iframe' data-width='80%'") . '
        '; - } - } - ?> -
        testcase->lib;?>createLink('caselib', 'browse', "libID=$case->lib"), $libName) : $libName;?>
        testcase->product;?>name) ? html::a($this->createLink('product', 'browse', "productID=$case->product"), $product->name) : $product->name;?>
        product->branch, $lang->product->branchName[$product->type]);?>createLink('testcase', 'browse', "productID=$case->product&branch=$case->branch"), $branchName) : $branchName;?>
        testcase->module;?> - app->tab; - - if(empty($modulePath)) - { - echo "/"; - } - else - { - if($caseModule->branch and isset($branches[$caseModule->branch])) - { - echo $branches[$caseModule->branch] . $lang->arrow; - } - - foreach($modulePath as $key => $module) - { - if($tab == 'qa' || $tab == 'ops') - { - if($isLibCase) - { - if(!common::printLink('caselib', 'browse', "libID=$case->lib&browseType=byModule¶m=$module->id", $module->name)) echo $module->name; - } - else - { - if(!common::printLink('testcase', 'browse', "productID=$case->product&branch=$module->branch&browseType=byModule¶m=$module->id", $module->name)) echo $module->name; - } - } - if($tab == 'project' and !common::printLink('project', 'testcase', "projectID={$this->session->project}&productID=$case->product&branch=$module->branch&browseType=byModule¶m=$module->id", $module->name)) echo $module->name; - if($tab == 'execution' or $tab == 'product') echo $module->name; - if(isset($modulePath[$key + 1])) echo $lang->arrow; - } - } - ?> -
        testcase->story;?> - session->project}" : ''; - if(isset($case->storyTitle)) - { - if(common::hasPriv('story', 'view')) - { - echo html::a($this->createLink('story', 'view', "storyID=$case->story" . $param, '', true), "#$case->story:$case->storyTitle", '', "class=$class data-width='80%'"); - } - else - { - echo "#$case->story:$case->storyTitle"; - } - } - if($case->story and $case->storyStatus == 'active' and $case->latestStoryVersion > $case->storyVersion) - { - echo "({$lang->story->changed} "; - if(common::hasPriv('testcase', 'confirmStoryChange', $case)) echo html::a($this->createLink('testcase', 'confirmStoryChange', "caseID=$case->id"), $lang->confirm, 'hiddenwin'); - echo ")"; - } - ?> -
        testcase->type;?>testcase->typeList[$case->type];?>
        testcase->stage;?> - stage) - { - $stags = explode(',', $case->stage); - foreach($stags as $stage) - { - if(empty($stage)) continue; - isset($lang->testcase->stageList[$stage]) ? print($lang->testcase->stageList[$stage]) : print($stage); - echo "
        "; - } - } - ?> -
        testcase->pri;?>testcase->priList, $case->pri)?>
        testcase->status;?> - processStatus('testcase', $case); - if($case->version > $case->currentVersion and $from == 'testtask') - { - echo "(testcase->fromTesttask}>{$lang->testcase->changed} "; - if(common::hasPriv('testcase', 'confirmchange')) echo html::a($this->createLink('testcase', 'confirmchange', "caseID=$case->id&taskID=$taskID"), $lang->testcase->sync, 'hiddenwin', "class='btn btn-mini btn-info'"); - echo ")"; - } - if(isset($case->fromCaseVersion) and $case->fromCaseVersion > $case->version and $from != 'testtask' and !empty($case->product)) - { - echo "(testcase->fromCaselib}>{$lang->testcase->changed} "; - if(common::hasPriv('testcase', 'confirmLibcaseChange')) echo html::a($this->createLink('testcase', 'confirmLibcaseChange', "caseID=$case->id&libcaseID=$case->fromCaseID"), $lang->testcase->sync, 'hiddenwin', "class='btn btn-mini btn-info'"); - if(common::hasPriv('testcase', 'ignoreLibcaseChange')) echo html::a($this->createLink('testcase', 'ignoreLibcaseChange', "caseID=$case->id"), $lang->testcase->ignore, 'hiddenwin', "class='btn btn-mini btn-info'"); - echo ")"; - } - ?> -
        app->loadLang('testtask')->testtask->lastRunTime;?>lastRunDate)) echo $case->lastRunDate;?>
        app->loadLang('testtask')->testtask->lastRunResult;?>lastRunResult ? $lang->testcase->resultList[$case->lastRunResult] : $lang->testcase->unexecuted;?>
        testcase->keywords;?>keywords;?>
        testcase->linkCase;?> - linkCaseTitles)) - { - foreach($case->linkCaseTitles as $linkCaseID => $linkCaseTitle) - { - echo html::a($this->createLink('testcase', 'view', "caseID=$linkCaseID", '', true), "#$linkCaseID $linkCaseTitle", '', "class='iframe' data-width='80%' title='$linkCaseTitle'") . '
        '; - } - } - ?> -
        -
        -
        -
        - -
        -
        - testcase->legendLinkBugs;?> -
        - - fromBug):?> - - - - - toBugs):?> - - - - -
        createLink('bug', 'view', "bugID=$case->fromBug", '', true), $case->fromBugData->title, '', "class='iframe' data-width='80%'");?>
        - toBugs as $bugID => $bug) - { - echo html::a($this->createLink('bug', 'view', "bugID=$bugID", '', true), "#$bugID " . $bug->title, '', "class='iframe' data-width='80%' title='$bug->title'") . '
        '; - } - ?> -
        -
        -
        -
        - -
        -
        - testcase->legendOpenAndEdit;?> -
        - - - - - - testcase->needReview or !empty($config->testcase->forceReview)):?> - - - - - - - - - - - - - -
        testcase->openedBy;?>openedBy) . $lang->at . $case->openedDate;?>
        testcase->reviewedBy;?>reviewedBy); foreach($reviewedBy as $account) echo ' ' . zget($users, trim($account)); ?>
        testcase->reviewedDate;?>reviewedBy) echo $case->reviewedDate;?>
        testcase->lblLastEdited;?>lastEditedBy) echo zget($users, $case->lastEditedBy) . $lang->at . $case->lastEditedDate;?>
        -
        -
        -
        - printExtendFields($case, 'div', "position=right&inForm=0&inCell=1");?> -
        -
        -
        -
        - createLink('testcase', 'view', "caseID=%s&version=&from=$from&taskID=$taskID"));?> -
        -fullscreen); -js::set('retrack', $lang->retrack); -js::set('isLibCase', $isLibCase); -?> - diff --git a/module/testcase/view/zerocase.html.php b/module/testcase/view/zerocase.html.php deleted file mode 100644 index 0c80a49467..0000000000 --- a/module/testcase/view/zerocase.html.php +++ /dev/null @@ -1,162 +0,0 @@ - - * @package product - * @version $Id: browse.html.php 4909 2013-06-26 07:23:50Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - -tab);?> -
        - -
        -

        story->noStory;?>

        -
        - -
        - - - - app->rawModule = 'testcase'; - $vars = "productID=$productID&branchID=$branch&orderBy=%s&project=$projectID&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}"; - ?> - - - - - - - - - - - - - - - $story):?> - app->tab == 'project') $param = $this->session->project; - if($this->app->tab == 'execution') $param = $this->session->execution; - $viewLink = $this->createLink('story', 'view', "storyID=$story->id&version=0¶m=$param"); - $canView = common::hasPriv('story', 'view'); - ?> - - - - - - - - - - - - - - - -
        -
        - -
        - idAB);?> -
        story->pri;?>>priAB);?> story->title);?> story->planAB);?> story->source);?> openedByAB);?> assignedToAB);?>story->estimateAB);?> statusAB);?> story->stageAB);?>actions;?>
        -
        - - -
        - id);?> -
        pri;?>' title='story->priList, $story->pri);?>'>story->priList, $story->pri)?> - - title, '', "data-app='product'") : $story->title;?> - - planTitle;?>story->sourceList[$story->source];?>openedBy);?>assignedTo);?>estimate;?>processStatus('story', $story);?>story->stageList, $story->stage);?> - id}"; - $this->app->tab = 'product'; - common::printIcon('story', 'change', $vars, $story, 'list', 'fork'); - common::printIcon('story', 'review', $vars, $story, 'list', 'glasses'); - common::printIcon('story', 'close', $vars, $story, 'list', 'off', '', 'iframe', 'yes'); - common::printIcon('story', 'edit', $vars, $story, 'list'); - $this->app->tab = 'qa'; - common::printIcon('story', 'createCase', "productID=$story->product&branch=0&module=0&from=¶m=0&$vars", $story, 'list', 'sitemap'); - ?> -
        - - show('right', 'pagerjs');?> -
        - - -
        - diff --git a/module/testcase/zen.php b/module/testcase/zen.php index f6334a6628..d453b870ec 100755 --- a/module/testcase/zen.php +++ b/module/testcase/zen.php @@ -1610,6 +1610,7 @@ class testcaseZen extends testcase if(!isset($fromCases[$caseID])) continue; $case = clone $fromCases[$caseID]; + $case->lib = 0; $case->steps = array(); $case->expects = array(); $case->stepType = array(); diff --git a/module/testreport/ui/browse.html.php b/module/testreport/ui/browse.html.php index aa77860d39..4246d7abbc 100644 --- a/module/testreport/ui/browse.html.php +++ b/module/testreport/ui/browse.html.php @@ -36,7 +36,7 @@ featureBar toolbar ( - $objectType != 'project' && $objectType != 'execution' ? btngroup + $objectType != 'project' && $objectType != 'execution' && hasPriv('testreport', 'create') ? btngroup ( btn ( diff --git a/module/testreport/view/browse.html.php b/module/testreport/view/browse.html.php deleted file mode 100644 index d573616519..0000000000 --- a/module/testreport/view/browse.html.php +++ /dev/null @@ -1,83 +0,0 @@ - - * @package testreport - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -global->flow == 'full'):?> - - - -
        - -
        -

        testreport->noReport;?>

        -
        - - - recTotal}&recPerPage={$pager->recPerPage}";?> - - - - - - - multiple)):?> - - - - - - - - - - id");?> - - - - - multiple)):?> - execution, '');?> - execution and zget($execution, 'multiple', '')) ? '#' . $report->execution . zget($execution, 'name', '') : '';?> - - - tasks) as $taskID) $taskName .= '#' . $taskID . $tasks[$taskID] . ' '; - ?> - - - - - -
        idAB);?>testreport->title);?>openedByAB);?>testreport->createdDate);?>testreport->execution);?>testreport->testtask;?>actions;?>
        id), '', "data-app='{$app->tab}'");?>title, '', "data-app='{$app->tab}' title='{$report->title}'")?>createdBy);?>createdDate, 2);?> - id", '', 'list'); - common::printIcon('testreport', 'delete', "id=$report->id", '', 'list', 'trash', 'hiddenwin'); - } - ?> -
        - - -
        - diff --git a/module/testreport/view/create.html.php b/module/testreport/view/create.html.php deleted file mode 100644 index c5d2907aea..0000000000 --- a/module/testreport/view/create.html.php +++ /dev/null @@ -1,150 +0,0 @@ - - * @package testreport - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - - - - -
        -
        -
        -

        -
        testreport->create;?>
        - -
        - testtask->common;?> - -
        - -

        -
        -
        -
        -
        testreport->legendBasic?>
        -
        - - - - - - - - - - - - - - - - - - desc)):?> - - - - - - - - - - - - - - - - - - - - - - - - -
        testreport->startEnd?> -
        - - ~ - - - id) ? $execution->id : 0)) . html::hidden('tasks', $tasks); - echo html::hidden('objectID', $objectID) . html::hidden('objectType', $objectType); - ?> -
        -
        -
        - testreport->owner?> - -
        -
        testreport->members?>
        testreport->title?>
        testreport->goal?> - desc;?> - -
        testreport->profile?> - ' . $storySummary . ''; - echo '
        ' . sprintf($lang->testreport->buildSummary, empty($builds) ? 1 : count($builds)) . $caseSummary . '
        '; - echo '
        ' . sprintf($lang->testreport->bugSummary, $bugSummary['foundBugs'], count($legacyBugs), $bugSummary['activatedBugs'], $bugSummary['countBugByTask'], $bugSummary['bugConfirmedRate'] . '%', $bugSummary['bugCreateByCaseRate'] . '%') . '
        '; - ?> -
        testreport->report?>
        files?>fetch('file', 'buildform');?>
        - - -
        -
        -
        -
        -
        testreport->legendStoryAndBug?>
        -
        - - -
        -
        -
        -
        testreport->legendBuild?>
        -
        - -
        -
        -
        -
        testreport->legendCase?>
        -
        - -
        -
        -
        -
        testreport->legendLegacyBugs?>
        -
        - -
        -
        -
        -
        testreport->legendReport?>
        -
        - -
        -
        -
        -
        -
        - - diff --git a/module/testreport/view/edit.html.php b/module/testreport/view/edit.html.php deleted file mode 100644 index 53d22e2c62..0000000000 --- a/module/testreport/view/edit.html.php +++ /dev/null @@ -1,123 +0,0 @@ - - * @package testreport - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - - - -
        -
        -
        -

        testreport->edit;?>

        -
        ' . $lang->goback, '', 'btn btn-link');?>
        -
        -
        -
        -
        testreport->legendBasic?>
        - - - - - - - - - - - - - - - - - - desc)):?> - - - - - - - - - - - - - - - - - - - - - - - - -
        testreport->startEnd?> -
        - - ~ - - - id) . html::hidden('tasks', $tasks);?> -
        -
        -
        - testreport->owner?> - owner, "class='form-control chosen'")?> -
        -
        testreport->members?>members, "class='form-control picker-select' multiple")?>
        testreport->title?>title, "class='form-control'")?>
        testreport->goal?> - desc?> - -
        testreport->profile?> - ' . $storySummary . '

        '; - echo '

        ' . sprintf($lang->testreport->buildSummary, empty($builds) ? 1 : count($builds)) . $caseSummary . '

        '; - echo '

        ' . sprintf($lang->testreport->bugSummary, $bugSummary['foundBugs'], count($legacyBugs), $bugSummary['activatedBugs'], $bugSummary['countBugByTask'], $bugSummary['bugConfirmedRate'] . '%', $bugSummary['bugCreateByCaseRate'] . '%') . '

        '; - ?> -
        testreport->report?>report, "class='form-control'")?>
        files?>fetch('file', 'buildform');?>
        - - -
        -
        -
        -
        testreport->legendStoryAndBug?>
        - - -
        -
        -
        testreport->legendBuild?>
        - -
        -
        -
        testreport->legendCase?>
        - -
        -
        -
        testreport->legendLegacyBugs?>
        - -
        -
        -
        testreport->legendReport?>
        - -
        -
        -
        -
        -id);?> - - diff --git a/module/testreport/view/view.html.php b/module/testreport/view/view.html.php deleted file mode 100644 index c45bd81416..0000000000 --- a/module/testreport/view/view.html.php +++ /dev/null @@ -1,131 +0,0 @@ - - * @package testreport - * @version $Id$ - * @link https://www.zentao.net - */ -?> -session->notHead):?> - - - - -
        - - app->rawParams['tab'] = 'cases';?> -
        -
        - - - - - - - - - - - - - - - desc)):?> - - - - - - - - - - session->notHead):?> - - - - - -
        testreport->startEnd?> begin . ' ~ ' . $report->end;?>
        testreport->owner?>owner);?>
        testreport->members?>members) as $member)echo zget($users, $member) . '   ';?>
        testreport->goal?> - desc?> - -
        testreport->profile?> - ' . $storySummary . '

        '; - echo '

        ' . sprintf($lang->testreport->buildSummary, empty($builds) ? 1 : count($builds)) . $caseSummary . '

        '; - echo '

        ' . sprintf($lang->testreport->bugSummary, $bugSummary['foundBugs'], count($legacyBugs), $bugSummary['activatedBugs'], $bugSummary['countBugByTask'], $bugSummary['bugConfirmedRate'] . '%', $bugSummary['bugCreateByCaseRate'] . '%') . '

        '; - ?> -
        files?>fetch('file', 'printFiles', array('files' => $report->files, 'fieldset' => 'false'));?>
        -
        -
        - - -
        -
        -
        -
        -
        -
        report) ? $lang->testreport->none : $report->report;?>
        - session->notHead):?> -
        - app->user->admin):?> -
        testreport->moreNotice;?>
        - - -
        -
        - -session->notHead):?> -
        - -
        - - deleted):?> -
        - objectType == 'execution' ? "&extra=$report->tasks" : ''; - if(common::hasPriv('testreport', 'create')) echo html::a(inLink('create', "objectID=$report->objectID&objectType=$report->objectType" . $extra), "", '', "class='btn' title='{$lang->testreport->recreate}' data-app='{$this->app->tab}'"); - common::printIcon('testreport', 'edit', "reportID=$report->id", '', 'button'); - common::printIcon('testreport', 'delete', "reportID=$report->id", '', 'button', 'trash', 'hiddenwin'); - } - ?> - -
        -
        - - diff --git a/module/testsuite/test/model/isclickable.php b/module/testsuite/test/model/isclickable.php index 8068a7126b..036593f764 100644 --- a/module/testsuite/test/model/isclickable.php +++ b/module/testsuite/test/model/isclickable.php @@ -1,31 +1,29 @@ #!/usr/bin/env php isClickable(); cid=1 -pid=1 -测试 linkcase 方法是否可以点击 >> 1 -测试 edit 方法是否可以点击 >> 1 -测试 delete 方法是否可以点击 >> 1 +- 测试 browse 方法是否可以点击 @1 +- 测试 create 方法是否可以点击 @1 +- 测试 view 方法是否可以点击 @1 +- 测试 linkCase 方法是否可以点击 @1 +- 测试 edit 方法是否可以点击 @1 +- 测试 delete 方法是否可以点击 @1 */ +include dirname(__FILE__, 5) . '/test/lib/init.php'; +include dirname(__FILE__, 2) . '/lib/testsuite.unittest.class.php'; $object = new stdclass(); -$actionList = array('linkCase', 'edit', 'delete'); +$actionList = array('browse', 'create', 'view', 'linkCase', 'edit', 'delete'); su('admin'); $testsuite = new testsuiteTest(); -r($testsuite->isClickableTest($object, $actionList[0])) && p() && e('1'); // 测试 linkCase 方法是否可以点击 -r($testsuite->isClickableTest($object, $actionList[1])) && p() && e('1'); // 测试 edit 方法是否可以点击 -r($testsuite->isClickableTest($object, $actionList[2])) && p() && e('1'); // 测试 delete 方法是否可以点击 - -su('user1'); -$testsuite = new testsuiteTest(); -r($testsuite->isClickableTest($object, $actionList[0])) && p() && e('1'); // 测试 linkCase 方法是否可以点击 -r($testsuite->isClickableTest($object, $actionList[1])) && p() && e('1'); // 测试 edit 方法是否可以点击 -r($testsuite->isClickableTest($object, $actionList[2])) && p() && e('1'); // 测试 delete 方法是否可以点击 \ No newline at end of file +r($testsuite->isClickableTest($object, $actionList[0])) && p() && e('1'); // 测试 browse 方法是否可以点击 +r($testsuite->isClickableTest($object, $actionList[1])) && p() && e('1'); // 测试 create 方法是否可以点击 +r($testsuite->isClickableTest($object, $actionList[2])) && p() && e('1'); // 测试 view 方法是否可以点击 +r($testsuite->isClickableTest($object, $actionList[3])) && p() && e('1'); // 测试 linkCase 方法是否可以点击 +r($testsuite->isClickableTest($object, $actionList[4])) && p() && e('1'); // 测试 edit 方法是否可以点击 +r($testsuite->isClickableTest($object, $actionList[5])) && p() && e('1'); // 测试 delete 方法是否可以点击 diff --git a/module/testsuite/ui/browse.html.php b/module/testsuite/ui/browse.html.php index 6e96bb95fa..6a4d3fbdff 100644 --- a/module/testsuite/ui/browse.html.php +++ b/module/testsuite/ui/browse.html.php @@ -32,13 +32,13 @@ toolbar ( btngroup ( - btn + hasPriv('testsuite', 'create') ? btn ( setClass('btn primary'), set::icon('plus'), set::url(helper::createLink('testsuite', 'create', "productID={$product->id}")), $lang->testsuite->create - ) + ) : null ) ); @@ -54,7 +54,7 @@ dtable set::footPager(usePager()), set::emptyTip($lang->testsuite->noTestsuite), set::createTip($lang->testsuite->create), - set::createLink(createLink('testsuite', 'create', "productID={$product->id}")) + hasPriv('testsuite', 'create') ? set::createLink(createLink('testsuite', 'create', "productID={$product->id}")) : null ); render(); diff --git a/module/testsuite/ui/view.html.php b/module/testsuite/ui/view.html.php index bebed8bbed..b9f440b6d5 100644 --- a/module/testsuite/ui/view.html.php +++ b/module/testsuite/ui/view.html.php @@ -48,7 +48,7 @@ detailHeader $canBatchEdit = common::hasPriv('testcase', 'batchEdit'); $canBatchUnlink = common::hasPriv('testsuite', 'batchUnlinkCases'); $canBatchRun = common::hasPriv('testtask', 'batchRun'); -$hasCheckbox = ($canBeChanged && $canBatchEdit && $canBatchUnlink && $canBatchRun); +$hasCheckbox = ($canBeChanged && ($canBatchEdit || $canBatchUnlink || $canBatchRun)); $batchItems = array( $canBatchUnlink ? array('text' => $lang->testsuite->unlinkCase, 'innerClass' => 'batch-btn ajax-btn not-open-url', 'data-url' => helper::createLink('testsuite', 'batchUnlinkCases', "suiteID={$suite->id}")) : null, diff --git a/module/testsuite/view/browse.html.php b/module/testsuite/view/browse.html.php deleted file mode 100644 index 558538c135..0000000000 --- a/module/testsuite/view/browse.html.php +++ /dev/null @@ -1,91 +0,0 @@ - - * @package testsuite - * @version $Id: browse.html.php 4129 2013-01-18 01:58:14Z wwccss $ - * @link https://www.zentao.net - */ -?> - -testsuite->confirmDelete)?> -global->flow);?> - -
        - -
        -

        - testsuite->noTestsuite;?> - - createLink('testsuite', 'create', "product=$productID"), " " . $lang->testsuite->create, '', "class='btn btn-info'");?> - -

        -
        - - - - recTotal}&recPerPage={$pager->recPerPage}"; ?> - - - - - - - testsuite->getFlowExtendFields(); - foreach($extendFields as $extendField) echo ""; - ?> - - - - - - - - - - - - " . $this->loadModel('flow')->getFieldValue($extendField, $suite) . "";?> - - - - -
        idAB);?>testsuite->name);?>testsuite->desc;?>testsuite->addedBy);?>testsuite->addedDate);?>{$extendField->name}actions;?>
        id"), sprintf('%03d', $suite->id));?> - type == 'public') echo "{$lang->testsuite->authorList['public']} ";?> - type == 'private') echo "{$lang->testsuite->authorList['private']} ";?> - id"), $suite->name);?> - - ', '
        ', '
        ', '
        '), "\n", str_replace(array("\n", "\r"), '', $suite->desc)), ''));?> -
        -
        addedBy);?>addedDate ? substr($suite->addedDate, 0, 10) : '';?> - testsuite->buildOperateMenu($suite, 'browse');?> -
        - - -
        - diff --git a/module/testsuite/view/create.html.php b/module/testsuite/view/create.html.php deleted file mode 100644 index 7b26c8420e..0000000000 --- a/module/testsuite/view/create.html.php +++ /dev/null @@ -1,46 +0,0 @@ - - * @package testsuite - * @version $Id: create.html.php 4728 2013-05-03 06:14:34Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -
        -
        -
        -

        testsuite->create;?>

        -
        -
        - - - - - - - - - - printExtendFields('', 'table', 'columns=2');?> - - - - - - - - -
        testsuite->name;?>
        testsuite->desc;?>
        testsuite->author;?>testsuite->authorList, 'private');?>
        - - -
        -
        -
        -
        - diff --git a/module/testsuite/view/edit.html.php b/module/testsuite/view/edit.html.php deleted file mode 100644 index 9b9d9ded78..0000000000 --- a/module/testsuite/view/edit.html.php +++ /dev/null @@ -1,47 +0,0 @@ - - * @package testsuite - * @version $Id: edit.html.php 4728 2013-05-03 06:14:34Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -
        -
        -
        -

        testsuite->edit;?>

        -
        -
        - - - - - - - - - - printExtendFields($suite, 'table');?> - type != 'library' and $suite->type != 'unit'):?> - - - - - - - - -
        testsuite->name;?>name, "class='form-control'");?>
        testsuite->desc;?>desc), "rows=10 class='form-control'");?>
        testsuite->author;?>testsuite->authorList, $suite->type);?>
        - - -
        -
        -
        -
        - diff --git a/module/testsuite/view/linkcase.html.php b/module/testsuite/view/linkcase.html.php deleted file mode 100644 index 1313e89fd6..0000000000 --- a/module/testsuite/view/linkcase.html.php +++ /dev/null @@ -1,99 +0,0 @@ - - * @package testsuite - * @version $Id: linkcase.html.php 4411 2013-02-22 00:56:04Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -global->flow);?> - -
        -
        - -
        -

        - testcase->noCase;?> -

        -
        - -
        -
        -  testsuite->unlinkedCases;?> (recTotal;?>) -
        - - - - - - - - - - - - - - - - - - - - - - - - - -
        -
        - -
        - idAB;?> -
        testsuite->linkVersion;?>pri;?>>priAB;?>testcase->title;?>testcase->type;?>openedByAB;?>statusAB;?>
        -
        - - -
        - id);?> -
        id]", array_combine(range($case->version, 1), range($case->version, 1)), '', 'class="form-control"');?> testcase->priList, $case->pri, $case->pri)?> - title . ' ( '; - for($i = $case->version; $i >= 1; $i --) - { - echo html::a($this->createLink('testcase', 'view', "caseID=$case->id&version=$i", '', true), "#$i", '', "class='iframe' data-width='95%'"); - } - echo ')'; - ?> - testcase->typeList[$case->type];?>openedBy);?>processStatus('testcase', $case);?>
        - - - -
        - -
        - diff --git a/module/testsuite/view/view.html.php b/module/testsuite/view/view.html.php deleted file mode 100644 index 02acfac78a..0000000000 --- a/module/testsuite/view/view.html.php +++ /dev/null @@ -1,218 +0,0 @@ - - * @package testsuite - * @version $Id: view.html.php 4141 2013-01-18 06:15:13Z zhujinyonging@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -app->loadLang('zanode');?> -testsuite->confirmUnlinkCase)?> -global->flow);?> -id : 0);?> -zanode->runCaseConfirm);?> -createLink('testtask', 'batchRun', "productID=$suite->product&orderBy=id_desc&from=testcase&taskID=0&confirm=yes"));?> -createLink('testtask', 'batchRun', "productID=$suite->product&orderBy=id_desc&from=testcase&taskID=0&confirm=no"));?> - -
        -
        -
        -
        -
        - - - - id&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}";?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        - -
        - -
        - - idAB);?> -
        testsuite->pri;?>>priAB);?>testcase->module);?>testcase->title);?>testcase->type);?>statusAB);?>testcase->lastRunResult);?>testcase->bugsAB;?>testcase->resultsAB;?>testcase->stepNumberAB;?>actions;?>
        - - id => sprintf('%03d', $case->id)));?> - - id);?> - - testcase->priList, $case->pri, $case->pri)?>module];?> - {$branches[$case->branch]}"?> - createLink('testcase', 'view', "caseID=$case->id&version=$case->caseVersion"), $case->title);?> - testcase->typeList[$case->type];?>version < $case->caseVersion) ? "{$lang->testcase->changed}" : $this->processStatus('testcase', $case);?>lastRunResult) echo $lang->testcase->resultList[$case->lastRunResult];?>bugs) ? html::a($this->createLink('testcase', 'bugs', "runID=0&caseID={$case->id}"), $case->bugs, '', "class='iframe'") : $case->bugs;?>results) ? html::a($this->createLink('testtask', 'results', "runID=0&caseID={$case->id}"), $case->results, '', "class='iframe'") : $case->results;?>stepNumber;?> - createLink('testsuite', 'unlinkCase', "suiteID=$suite->id&caseID=$case->id&confirm=yes"); - echo html::a("javascript:ajaxDelete(\"$unlinkURL\", \"caseList\", confirmUnlink)", '', '', "title='{$lang->testsuite->unlinkCase}' class='btn'"); - } - if(common::hasPriv('testtask', 'runCase')) echo html::a($this->createLink('testtask', 'runCase', "runID=0&caseID=$case->id&version=$case->version"), '', '', "class='btn runCase iframe' data-width='95%' title={$lang->testtask->runCase}"); - common::printIcon('testtask', 'results', "runID=0&caseID=$case->id", $suite, 'list', 'list-alt', '', 'results iframe', false, "data-width='95%'"); - } - ?> -
        - -
        -
        -
        -
        - -
        -
        -
        -
        testsuite->legendDesc;?>
        -
        - desc;?> -
        -
        -
        - printExtendFields($suite, 'div', "position=right&inForm=0&inCell=1");?> -
        - -
        -
        - -
        - - diff --git a/module/testtask/css/runcase.ui.css b/module/testtask/css/runcase.ui.css index 535ac3bf60..02423ead57 100644 --- a/module/testtask/css/runcase.ui.css +++ b/module/testtask/css/runcase.ui.css @@ -11,3 +11,7 @@ #caseStepForm .step-item-id {color: var(--color-gray-500);} .modal[id^='fileModal'] .modal-dialog {max-height: 100%;} + +.files-list>li>a {display: inline; word-wrap: break-word; color: #313c52; line-height: 24px} +.files-list .icon.icon-file-text {padding-left: 7px} +.files-list .right-icon .btn {padding: 0 6px; height: 20px} diff --git a/module/testtask/js/runcase.ui.js b/module/testtask/js/runcase.ui.js index a215b7a7f7..c7326f8336 100644 --- a/module/testtask/js/runcase.ui.js +++ b/module/testtask/js/runcase.ui.js @@ -23,6 +23,17 @@ function loadResult() { loadCurrentPage({url: resultsLink, selector: '#casesResults', partial: true}); window.waitDom('#casesResults .result-item', function(){ $('#casesResults .result-item').first().trigger('click');}) + $(document).off('mouseover', 'li.file').on('mouseover', 'li.file', function() + { + $(this).children('span.right-icon').removeClass("hidden"); + $(this).addClass('backgroundColor'); + }); + + $(document).off('mouseout', 'li.file').on('mouseout', 'li.file', function() + { + $(this).children('span.right-icon').addClass("hidden"); + $(this).removeClass('backgroundColor'); + }); } /** diff --git a/module/testtask/model.php b/module/testtask/model.php index df9fe05762..2abe12e392 100755 --- a/module/testtask/model.php +++ b/module/testtask/model.php @@ -1644,7 +1644,7 @@ class testtaskModel extends model { $resultFiles[$file->objectID][$file->id] = $file; } - elseif($file->objectType == 'stepResult' && $file->extra !== '') + elseif($file->objectType == 'stepResult') { $stepFiles[$file->objectID][(int)$file->extra][$file->id] = $file; } diff --git a/module/testtask/test/model/getresultsfiles.php b/module/testtask/test/model/getresultsfiles.php index f4c2b92ddc..fd7d0f9f64 100644 --- a/module/testtask/test/model/getresultsfiles.php +++ b/module/testtask/test/model/getresultsfiles.php @@ -22,7 +22,7 @@ cid=1 - 属性step @4: 4 6: 6 - 测试获取结果 7 8 9 的文件 - 属性result @9: 9 - - 属性step @~~ + - 属性step @8: 8 - 测试获取结果 10 11 12 的文件 - 属性result @11: 11 - 属性step @10: 10 12: 12 @@ -55,7 +55,7 @@ $testtask = new testtaskTest(); r($testtask->getResultsFilesTest($resultIdList[0])) && p('result,step') && e('1: 1 3: 3,2: 2'); // 测试获取结果 1 2 3 的文件 r($testtask->getResultsFilesTest($resultIdList[1])) && p('result,step') && e('5: 5,4: 4 6: 6'); // 测试获取结果 4 5 6 的文件 -r($testtask->getResultsFilesTest($resultIdList[2])) && p('result,step') && e('9: 9,~~'); // 测试获取结果 7 8 9 的文件 +r($testtask->getResultsFilesTest($resultIdList[2])) && p('result,step') && e('9: 9,8: 8'); // 测试获取结果 7 8 9 的文件 r($testtask->getResultsFilesTest($resultIdList[3])) && p('result,step') && e('11: 11,10: 10 12: 12'); // 测试获取结果 10 11 12 的文件 r($testtask->getResultsFilesTest($resultIdList[4])) && p('result,step') && e('13: 13 15: 15,~~'); // 测试获取结果 13 14 15 的文件 r($testtask->getResultsFilesTest($resultIdList[5])) && p('result,step') && e('17: 17,16: 16 18: 18'); // 测试获取结果 16 17 18 的文件 diff --git a/module/testtask/view/activate.html.php b/module/testtask/view/activate.html.php deleted file mode 100644 index d09d427792..0000000000 --- a/module/testtask/view/activate.html.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @package testtask - * @version $Id: start.html.php 935 2013-01-16 07:49:24Z wwccss@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -
        -
        -
        -

        - id;?> - createLink('testtask', 'view', 'taskID=' . $testtask->id), $testtask->name, '_blank');?> - arrow . $lang->testtask->activate;?> -

        -
        -
        - - - - - - printExtendFields($testtask, 'table');?> - - - - - - - -
        testtask->status;?>
        comment;?>
        goback, $this->session->taskList, 'self', '', 'btn btn-wide');?>
        -
        -
        -
        -
        -
        - diff --git a/module/testtask/view/batchrun.html.php b/module/testtask/view/batchrun.html.php deleted file mode 100644 index 0e0aa805a7..0000000000 --- a/module/testtask/view/batchrun.html.php +++ /dev/null @@ -1,126 +0,0 @@ - - * @package testcase - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -app->loadLang('testcase'); unset($this->lang->testcase->resultList['n/a']); ?> -
        -
        -

        testtask->common . $lang->hyphen) : ''). $lang->testtask->batchRun;?>

        -
        -
        - - - - - - - - - - - - $case):?> - auto == 'auto' and $confirm == 'yes') continue;?> - status == 'wait') continue;?> - id]", $caseID); ?> - - - - - - - - - - -
        idAB;?>testcase->module;?>testcase->title;?>testcase->precondition;?>testcase->result?>testcase->stepDesc . '/' . $lang->testcase->stepExpect?>
        version)?>module] . "'>" . $moduleOptionMenu[$case->module] . ""?>title}'>{$case->title}"?>precondition}'>{$case->precondition}"?> - lang->testcase->resultList, 'pass', "onclick='showAction(this.value,\".action$caseID\")'", 'block')?> - - - - - $step):?> - type == 'group' or $step->type == 'step') - { - $stepId ++; - $childId = 0; - } - $ID = $step->type == 'item' ? "{$stepId}.{$childId}" : $stepId; - $stepClass = $step->type == 'item' ? 'step-item' : 'step-group'; - ?> - - - type != 'group'):?> - - - - - - - -
        type == 'group') echo "colspan='2'"?>>desc' class='$stepClass'>" . $ID . "、" . $step->desc . ''?>expect'>" . $lang->testcase->stepExpect . ":" . $step->expect . ''?>
        - - - -
        -
        -
        - - diff --git a/module/testtask/view/block.html.php b/module/testtask/view/block.html.php deleted file mode 100644 index 176940d08c..0000000000 --- a/module/testtask/view/block.html.php +++ /dev/null @@ -1,46 +0,0 @@ - - * @package testtask - * @version $Id: start.html.php 935 2013-01-16 07:49:24Z wwccss@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - -
        -
        -
        -

        - id;?> - createLink('testtask', 'view', 'taskID=' . $testtask->id), $testtask->name, '_blank');?> - arrow . $lang->testtask->block;?> -

        -
        -
        - - - - - - printExtendFields($testtask, 'table');?> - - - - - - - -
        testtask->status;?>
        comment;?>
        goback, $this->session->taskList, 'self', '', 'btn btn-wide'); ?>
        -
        - -
        -
        -
        -
        - diff --git a/module/testtask/view/browse.html.php b/module/testtask/view/browse.html.php deleted file mode 100644 index 87f2a36832..0000000000 --- a/module/testtask/view/browse.html.php +++ /dev/null @@ -1,134 +0,0 @@ - - * @package testtask - * @version $Id: browse.html.php 4129 2013-01-18 01:58:14Z wwccss $ - * @link https://www.zentao.net - */ -?> - - -testtask->confirmDelete)?> -global->flow);?> -session->testTaskVersionScope; -$status = $this->session->testTaskVersionStatus; -$status = strtolower($status); -?> - - - -
        - -
        -

        - testtask->noTesttask;?> - - createLink('testtask', 'create', "product=$productID"), " " . $lang->testtask->create, '', "class='btn btn-info'");?> - -

        -
        - - - - recTotal}&recPerPage={$pager->recPerPage}"; ?> - - - - - shadow):?> - - - - - - - - testtask->getFlowExtendFields(); - foreach($extendFields as $extendField) echo ""; - ?> - - - - - - - status == 'wait') $waitCount ++;?> - status == 'doing') $testingCount ++;?> - status == 'blocked') $blockedCount ++;?> - status == 'done') $doneCount ++;?> - - - - - shadow):?> - - - - processStatus('testtask', $task);?> - - - - - " . $this->loadModel('flow')->getFieldValue($extendField, $task) . "";?> - - - - -
        idAB);?> testtask->name);?> testtask->build);?> testtask->product);?> testtask->execution);?>statusAB);?> testtask->owner);?> testtask->begin);?> testtask->end);?>{$extendField->name}actions;?>
        id"), sprintf('%03d', $task->id));?>id"), $task->name);?>build == 'trunk' || empty($task->buildName)) ? $lang->trunk : html::a($this->createLink('build', 'view', "buildID=$task->build"), $task->buildName, '', "data-group=execution");?>productName?>executionName?> - - - - owner);?>begin?>end?> - testtask->buildOperateMenu($task, 'browse');?> -
        - - -
        - - diff --git a/module/testtask/view/browseunits.html.php b/module/testtask/view/browseunits.html.php deleted file mode 100644 index 494fdd50bb..0000000000 --- a/module/testtask/view/browseunits.html.php +++ /dev/null @@ -1,85 +0,0 @@ - - * @package testtask - * @version $Id: browse.html.php 4129 2013-01-18 01:58:14Z wwccss $ - * @link https://www.zentao.net - */ -?> - - - -testtask->confirmDelete)?> -global->flow);?> - -
        -
        - -
        -

        - testtask->noTesttask;?> -

        -
        - - - - recTotal}&recPerPage={$pager->recPerPage}"; ?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        idAB);?>testtask->name);?> testtask->execution);?> testtask->build);?> testtask->owner);?> testtask->execTime);?>testtask->caseCount;?>testtask->passCount;?>testtask->failCount;?>actions;?>
        id);?>id"), $task->name, '', "data-app={$this->app->tab}");?>executionName?>build == 'trunk' || empty($task->buildName)) ? $lang->trunk : html::a($this->createLink('build', 'view', "buildID=$task->build"), $task->buildName, '', 'data-app="execution"');?>owner);?>begin?>caseCount?>passCount?>failCount?> - id", '', 'list', 'list-alt'); - common::printIcon('testtask', 'edit', "taskID=$task->id", $task, 'list'); - if(common::hasPriv('testtask', 'delete', $task)) - { - $deleteURL = $this->createLink('testtask', 'delete', "taskID=$task->id&confirm=yes"); - echo html::a("javascript:ajaxDelete(\"$deleteURL\",\"taskList\",confirmDelete)", '', '', "title='{$lang->testcase->delete}' class='btn'"); - } - ?> -
        - - - - -
        -
        - - diff --git a/module/testtask/view/cases.html.php b/module/testtask/view/cases.html.php deleted file mode 100644 index 5a5278ac59..0000000000 --- a/module/testtask/view/cases.html.php +++ /dev/null @@ -1,220 +0,0 @@ - - * @package case - * @version $Id: view.html.php 594 2010-03-27 13:44:07Z wwccss $ - * @link https://www.zentao.net - */ -?> - - - -testtask->confirmUnlinkCase)?> -session->taskCaseBrowseType == 'bysearch') ? 'all' : $this->session->taskCaseBrowseType);?> - - -id : 0);?> -app->loadLang('zanode');?> -zanode->runCaseConfirm);?> -createLink('testtask', 'batchRun', "productID=$productID&orderBy=id_desc&from=testtask&taskID=$taskID&confirm=yes"));?> -createLink('testtask', 'batchRun', "productID=$productID&orderBy=id_desc&from=testtask&taskID=$taskID&confirm=no"));?> -
        - -
        -
        - moduleName . ucfirst($this->methodName); - $useDatatable = (isset($config->datatable->$datatableId->mode) and $config->datatable->$datatableId->mode == 'datatable'); - ?> -
        > -
        - -
        - id&browseType=$browseType¶m=$param&orderBy=%s&recToal={$pager->recTotal}&recPerPage={$pager->recPerPage}"; - - $canBatchEdit = common::hasPriv('testcase', 'batchEdit'); - $canBatchUnlink = common::hasPriv('testtask', 'batchUnlinkCases'); - $canBatchAssign = common::hasPriv('testtask', 'batchAssign'); - $canBatchRun = common::hasPriv('testtask', 'batchRun'); - - $canBatchAction = ($canBeChanged and ($canBatchEdit or $canBatchUnlink or $canBatchAssign or $canBatchRun)); - - if($useDatatable) include '../../common/view/datatable.html.php'; - if(!$useDatatable) include '../../common/view/tablesorter.html.php'; - - $config->testcase->datatable->defaultField = $config->testtask->datatable->defaultField; - $config->testcase->datatable->fieldList['actions']['width'] = '120'; - - $setting = $this->datatable->getSetting('testtask'); - $widths = $this->datatable->setFixedFieldWidth($setting); - $columns = 0; - ?> - ';?> - ' id='caseList' data-fixed-left-width='' data-fixed-right-width='' data-checkbox-name='caseIDList[]'> - - - $value) - { - if($value->show) - { - $this->datatable->printHead($value, $orderBy, $vars, $canBatchAction); - $columns ++; - } - } - ?> - - - - - - $value) $this->testtask->printCell($value, $run, $users, $task, $branches, $useDatatable ? 'datatable' : 'table');?> - - - -
        - ';?> - - - -
        -

        testcase->noCase;?> " . $lang->testtask->linkCase, '', "class='btn btn-info'");?>

        -
        - -
        -
        -
        - - diff --git a/module/testtask/view/close.html.php b/module/testtask/view/close.html.php deleted file mode 100644 index 9b40a45c61..0000000000 --- a/module/testtask/view/close.html.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @package testtask - * @version $Id: close.html.php 935 2013-01-16 07:49:24Z wwccss@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -
        -
        -
        -

        - id;?> - createLink('testtask', 'view', 'taskID=' . $testtask->id), $testtask->name, '_blank');?> - arrow . $lang->testtask->close;?> -

        -
        -
        - - - - - - printExtendFields($testtask, 'table');?> - - - - - - - - - - - - - - - -
        testtask->status;?>
        testtask->realFinishedDate;?>realFinishedDate) ? helper::now() : $testtask->realFinishedDate, "class='form-control form-datetime w-180px'");?>
        comment;?>
        testtask->mailto;?> -
        - mailto), "multiple class='form-control chosen'");?> - -
        -
        goback, $this->session->taskList, 'self', '', 'btn btn-wide');?>
        -
        -
        -
        -
        -
        - diff --git a/module/testtask/view/create.html.php b/module/testtask/view/create.html.php deleted file mode 100644 index 3fd61530be..0000000000 --- a/module/testtask/view/create.html.php +++ /dev/null @@ -1,129 +0,0 @@ - - * @package testtask - * @version $Id: create.html.php 4728 2013-05-03 06:14:34Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - - - - -
        -
        -
        -

        testtask->create;?>

        -
        -
        - - - shadow)) echo "class='hide'";?>> - - - - - - - - - - - - - - '> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - printExtendFields('', 'table');?> - - - -
        testtask->product;?>id, "class='form-control chosen' onchange='loadProductRelated()'");?>
        testtask->product;?>id, "class='form-control' onchange='loadTestReports(this.value)'");?>
        testtask->execution;?>
        testtask->build;?> -
        - - - - id}&projectID={$projectID}", '', true), $lang->build->create, '', "data-toggle='modal' data-type='iframe' data-width='95%'")?> - - -
        -
        testtask->type;?>testtask->typeList, '', "class='form-control picker-select' multiple");?>
        testtask->owner;?> -
        - - testtask->pri;?> - testtask->priList, 3, "class='form-control chosen'");?> -
        -
        testtask->begin;?> -
        - - testtask->end;?> - -
        -
        testtask->status;?>testtask->statusList, '', "class='form-control chosen'");?>
        testtask->testreport;?>
        testtask->name;?>
        testtask->desc;?> - fetch('user', 'ajaxPrintTemplates', 'type=testtask&link=desc');?> - -
        files;?>fetch('file', 'buildform');?>
        testtask->mailto;?> -
        - fetch('my', 'buildContactLists'); - ?> -
        -
        - - -
        -
        -
        -
        - diff --git a/module/testtask/view/edit.html.php b/module/testtask/view/edit.html.php deleted file mode 100644 index 5a159917e5..0000000000 --- a/module/testtask/view/edit.html.php +++ /dev/null @@ -1,119 +0,0 @@ - - * @package testtask - * @version $Id: edit.html.php 4728 2013-05-03 06:14:34Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - -project);?> -
        -
        -
        -

        - id;?> - createLink('testtask', 'view', 'taskID=' . $task->id), $task->name, '_blank');?> - arrow . $lang->testtask->edit;?> -

        -
        -
        - - product);?> - multiple):?> - execution);?> - - execution) ? 'hide' : '';?>'> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - printExtendFields($task, 'table');?> - - - -
        testtask->execution;?> - execution, "class='form-control chosen' onchange='loadExecutionRelated(this.value)'");?> -
        testtask->build;?>build, "class='form-control chosen'");?>
        testtask->type;?>testtask->typeList, $task->type, "class='form-control picker-select' multiple");?>
        testtask->owner;?> -
        - owner, "class='form-control chosen'");?> - testtask->pri;?> - testtask->priList, $task->pri, "class='form-control chosen'");?> -
        -
        testtask->begin;?> -
        - begin, "class='form-control form-date'");?> - testtask->end;?> - end, "class='form-control form-date'");?> -
        -
        testtask->status;?>testtask->statusList, $task->status, "class='form-control chosen'");?>
        testtask->testreport;?>testreport, "class='form-control chosen'");?>
        testtask->name;?>name, "class='form-control'");?>
        testtask->desc;?> - fetch('user', 'ajaxPrintTemplates', 'type=testtask&link=desc');?> - desc), "rows=10 class='form-control'");?> -
        comment;?>
        files;?> - fetch('file', 'printFiles', array('files' => $task->files, 'fieldset' => 'false', 'object' => $task, 'method' => 'edit'));?> - fetch('file', 'buildform');?> -
        testtask->mailto;?> -
        - mailto), "multiple class='form-control picker-select'");?> - fetch('my', 'buildContactLists');?> -
        -
        - - -
        -
        -
        -
        - diff --git a/module/testtask/view/groupcase.html.php b/module/testtask/view/groupcase.html.php deleted file mode 100644 index ff9985aafc..0000000000 --- a/module/testtask/view/groupcase.html.php +++ /dev/null @@ -1,103 +0,0 @@ - - * @package testcase - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - - - -testtask->confirmUnlinkCase)?> -
        - - - - - - - - - - - - - - - - - - - - - - $groupCases):?> - task->noStory; - if(empty($groupName) and $groupBy == 'assignedTo') $groupName = $groupKey ? zget($users, $groupKey, $lang->task->noAssigned) : $lang->task->noAssigned; - ?> - - > - - - - case)) - { - echo ""; - break; - } - ?> - - - - - - - - - - - - - - - - - - - - - - - -
        -
        - - -
        -
        idAB;?>priAB;?>testcase->title;?> typeAB;?> testtask->assignedTo;?> testtask->lastRunAccount;?>testtask->lastRunTime;?> testtask->lastRunResult;?> testtask->status;?>testcase->bugsAB;?>testcase->resultsAB;?>testcase->stepNumberAB;?> actions;?>
        -
        $groupName", '', "class='text-primary'");?>
        -
        case);?>pri;?>' title='testcase->priList, $run->pri, $run->pri);?>'>testcase->priList, $run->pri, $run->pri);?>case&version=$run->version&from=testtask&taskID=$run->task", $run->title)) echo $run->title;?>testcase->typeList, $run->type, '');?>assignedTo);?>lastRunner);?>lastRunDate)) echo date(DT_MONTHTIME1, strtotime($run->lastRunDate));?>lastRunResult) echo $lang->testcase->resultList[$run->lastRunResult];?>version < $run->caseVersion) ? "{$lang->testcase->changed}" : $this->processStatus('testcase', $run);?>bugs) ? html::a($this->createLink('testcase', 'bugs', "runID={$run->id}&caseID={$run->case}"), $run->bugs, '', "class='iframe'") : $run->bugs;?>results) ? html::a($this->createLink('testtask', 'results', "runID={$run->id}&caseID={$run->case}"), $run->results, '', "class='iframe'") : $run->results;?>stepNumber;?> - - id&caseID=$run->case&version=$run->caseVersion", '', 'list', 'play', '', 'runCase iframe', false, "data-width='95%'");?> - case", '', 'list');?> - id&confirm=yes"); - echo html::a("javascript:ajaxDelete(\"$unlinkURL\", \"casesForm\", confirmUnlink)", '', '', "title='{$this->lang->testtask->unlinkCase}' class='btn'"); - } - ?> - -
        -
        - diff --git a/module/testtask/view/importunitresult.html.php b/module/testtask/view/importunitresult.html.php deleted file mode 100644 index 9f940d3242..0000000000 --- a/module/testtask/view/importunitresult.html.php +++ /dev/null @@ -1,111 +0,0 @@ - - * @package testtask - * @version $Id: create.html.php 4728 2013-05-03 06:14:34Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - - - -
        -
        -
        -

        testtask->importUnitResult;?>

        -
        -
        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - printExtendFields('', 'table');?> - - - -
        testtask->execution;?>
        testtask->build;?> -
        - - - build->create, '', "data-toggle='modal' data-type='iframe' data-width='95%'")?> -
        - - -
        job->frame;?>job->frameList, '', "class='form-control chosen'");?>
        testtask->owner;?> -
        - app->user->account, "class='form-control chosen'");?> - testtask->pri;?> - testtask->priList, 0, "class='form-control chosen'");?> -
        -
        testtask->begin;?> -
        - - testtask->end;?> - -
        -
        testtask->resultFile;?>testtask->unitXMLFormat;?>
        testtask->name;?>testtask->titleOfAuto, date('Y-m-d H:i:s')), "class='form-control'");?>
        testtask->desc;?>
        testtask->mailto;?> -
        - fetch('my', 'buildContactLists'); - ?> -
        -
        - - - -
        -
        -
        -
        - - - diff --git a/module/testtask/view/linkcase.html.php b/module/testtask/view/linkcase.html.php deleted file mode 100644 index 130f2992db..0000000000 --- a/module/testtask/view/linkcase.html.php +++ /dev/null @@ -1,137 +0,0 @@ - - * @package testtask - * @version $Id: linkcase.html.php 4411 2013-02-22 00:56:04Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - -
        -
        -
        - -
        -  testtask->unlinkedCases;?> (recTotal;?>) -
        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        - -
        - -
        - - idAB;?> -
        testtask->linkVersion;?>priAB;?>testcase->title;?>testcase->linkStory;?>testcase->type;?>openedByAB;?>testtask->lastRunAccount;?>testtask->lastRunTime;?>testtask->lastRunResult;?>statusAB;?>
        - id => sprintf('%03d', $case->id)));?> - id]", array_combine(range($case->version, 1), range($case->version, 1)), '', 'class="form-control"');?> testcase->priList, $case->pri, $case->pri)?> - title . ' ( '; - for($i = $case->version; $i >= 1; $i --) - { - echo html::a($this->createLink('testcase', 'view', "caseID=$case->id&version=$i", '', true), "#$i", '', "class='iframe' data-width='95%'"); - } - echo ')'; - ?> - story and $case->storyTitle) echo html::a(helper ::createLink('story', 'view', "storyID=$case->story"), $case->storyTitle);?>testcase->typeList[$case->type];?>openedBy);?>lastRunner);?>lastRunDate)) echo date(DT_MONTHTIME1, strtotime($case->lastRunDate));?>lastRunResult ? $lang->testcase->resultList[$case->lastRunResult] : $lang->testcase->unexecuted;?>processStatus('testcase', $case);?>
        - - - -
        -
        - diff --git a/module/testtask/view/report.html.php b/module/testtask/view/report.html.php deleted file mode 100644 index 5be1d19871..0000000000 --- a/module/testtask/view/report.html.php +++ /dev/null @@ -1,102 +0,0 @@ - - * @package testtask - * @version $Id: report.html.php 4657 2013-04-17 02:01:26Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -
        -
        -
        -
        -
        testtask->report->select;?>
        -
        -
        -
        -
        - testtask->report->charts, $checkedCharts, '', 'block');?> -
        -
        - - testtask->report->create, '', "btn btn-primary");?> -
        -
        -
        -
        -
        -
        -
        -
        - report->typeList as $type => $typeName):?> - " : "") . $typeName, '', "class='btn btn-link " . ($type == $chartType ? 'btn-active-line' : '') . "'")?> - -
        - app->loadLang('testcase');?> -
        testtask->wait . $lang->testcase->common, $lang->report->notice->help);?>
        - $chartOption):?> -
        -
        -
        -

        - testtask->report->charts[$chartType];?> - - $data) $total += $data->value; - $pass = isset($datas['testTaskPerRunResult']['pass']) ? $datas['testTaskPerRunResult']['pass']->value : 0; - $noExec = isset($datas['testTaskPerRunResult']['']) ? $datas['testTaskPerRunResult']['']->value : 0; - $fail = isset($datas['testTaskPerRunResult']['fail']) ? $datas['testTaskPerRunResult']['fail']->value : 0; - ?> - - -

        -
        -
        -
        -
        -
        - - - - - - - - - $data):?> - - - - - - - -
        report->item;?>report->value;?>report->percent;?>
        name;?>value;?>percent * 100) . '%';?>
        -
        -
        -
        - -
        -
        -
        - - - - - - diff --git a/module/testtask/view/results.html.php b/module/testtask/view/results.html.php deleted file mode 100644 index c1456e0f87..0000000000 --- a/module/testtask/view/results.html.php +++ /dev/null @@ -1,199 +0,0 @@ - - * @package testtask - * @version $Id: results.html.php 4129 2013-01-18 01:58:14Z wwccss $ - * @link https://www.zentao.net - */ -?> - -tab);?> -
        -
        -

        - id;?> - title;?> -

        -
        - -
        - auto != 'unit'):?> -
        -
        testcase->precondition;?>
        -
        precondition;?>
        -
        - -
        - - auto != 'unit'):?> - - - - - $result):?> - caseResult == 'pass' ? 'success' : ($result->caseResult == 'fail' ? 'danger' : ($result->caseResult == 'blocked' ? 'warning' : ''))); - if($class != 'success') $failCount++; - $fileCount = '(' . count($result->files) . ')'; - ?> - ' id='result-' style='cursor: pointer'> - - - node > 0):?> - - - - - - - - - - app->tab == 'execution' ? "executionID={$this->session->execution}" : "";?> - execution" : $executionParam;?> - id" : "";?> - build) ? $testtask->build : $result->build);?> - - - - - -
        - testcase->result?>   testtask->showResult, $count)?> -
          #id?>date;?>testtask->runNode, zget($users, $result->lastRunner), $result->nodeName, $lang->testtask->runCase) . "  {$lang->testtask->auto}";?>lastRunner) . ' ' . $lang->testtask->runCase;?>build, '');?> - node == 0 || !empty($result->ZTFResult)):?> - testcase->resultList[$result->caseResult];?> - - node > 0 and empty($result->ZTFResult)):?> - testtask->running;?> - - files)) echo html::a("#caseResult{$result->id}", $lang->files . $fileCount, '', "data-toggle='modal' data-type='iframe'")?>
        - app->tab == 'project' ? "projectID={$this->session->project}," : ''?> -
        - - - - - - - - - - - - - - stepResults as $key => $stepResult): - ?> - id . '-' . $key; - $fileCount = '(' . count($stepResult['files']) . ')'; - ?> - - - - - - - - - - - - - - - - - caseResult == 'fail' and common::hasPriv('testcase', 'createBug')):?> - - - - - - - ZTFResult) && $result->node>0):?> - - - - - -
        testcase->stepID;?>testcase->stepDesc;?>testcase->stepExpect;?>testcase->stepVersion;?>testcase->result;?>testcase->real;?>
        - caseResult == 'fail'):?> - -
        - - -
        - - - -
        > -
        - {$stepId}.{$childId}";?> - -
        -
        version)) echo nl2br($result->version);?> text-center'>testcase->resultList[$stepResult['result']];?>files . $fileCount, '', "data-toggle='modal' data-type='iframe'")?>
        -
        - - -
        -
        testcase->createBug, "onclick='createBug(this)'", "btn btn-primary createBtn");?>
        -

        -

        testtask->runningLog;?>

        -

        ZTFResult;?>

        -
        -
        -
        - - - stepResults)):?> - stepResults as $stepID => $stepResult):?> - - - - -
        0) echo $failCount > 0 ? "" . sprintf($lang->testtask->showFail, $failCount) . "":"{$lang->testtask->passAll}";?>
        - -
        -
        -
        - diff --git a/module/testtask/view/runcase.html.php b/module/testtask/view/runcase.html.php deleted file mode 100644 index d90e72e5fc..0000000000 --- a/module/testtask/view/runcase.html.php +++ /dev/null @@ -1,174 +0,0 @@ - - * @package testtask - * @version $Id: runcase.html.php 4723 2013-05-03 05:19:29Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -save);?> -tab);?> - -
        -
        -

        - case->id;?> - case->title;?> -

        -
        -
        - - - - - - - - - - - - - - - - - case->steps)) - { - $step = new stdclass(); - $step->id = 0; - $step->parent = 0; - $step->case = $run->case->id; - $step->type = 'step'; - $step->desc = ''; - $step->expect = ''; - $run->case->steps[] = $step; - } - $stepId = $childId = 0; - ?> - case->steps as $key => $step):?> - type}"; - if($step->type == 'group' or $step->type == 'step') - { - $stepId++; - $childId = 0; - } - ?> - - - - type != 'group'):?> - - - - - - - - - - - -
        testcase->precondition;?>
        case->precondition);?>
        testcase->stepID;?>testcase->stepDesc;?>testcase->stepExpect;?>testcase->result;?>testcase->real;?>
        type == 'group') echo "colspan='4'"?>> -
        - type == 'item') echo "{$stepId}.{$childId}";?> - desc);?> -
        -
        expect);?>id]", $lang->testcase->resultList, 'pass', "class='form-control' onchange='checkStepValue(this.value)'");?> - - - - - -
        id]", '', "rows=1 class='form-control autosize'");?>
        -
        - testtask->pre, '', "id='pre' class='btn btn-wide'"); - if($run->case->status != 'wait' and $confirm != 'yes') echo html::submitButton(); - if($nextCase) echo ' ' . html::a(inlink('runCase', "runID={$nextCase['runID']}&caseID={$nextCase['caseID']}&version={$nextCase['version']}"), $lang->testtask->next, '', "id='next' class='btn btn-wide'"); - echo html::hidden('case', $run->case->id); - echo html::hidden('version', $run->case->currentVersion); - ?> - -
        - case->steps as $key => $step):?> - - -
        -
        -
        - - diff --git a/module/testtask/view/start.html.php b/module/testtask/view/start.html.php deleted file mode 100644 index a0963e24dc..0000000000 --- a/module/testtask/view/start.html.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @package testtask - * @version $Id: start.html.php 935 2013-01-16 07:49:24Z wwccss@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -
        -
        -
        -

        - id;?> - name'>" . $testtask->name . '') : html::a($this->createLink('testtask', 'view', 'taskID=' . $testtask->id), $testtask->name, '_blank');?> - - arrow . $lang->testtask->start;?> - -

        -
        -
        - - - - - - printExtendFields($testtask, 'table');?> - - - - - - - -
        testtask->status;?>
        comment;?>
        - - goback, $this->session->taskList, 'self', '', 'btn btn-wide');?> -
        -
        -
        -
        -
        - - diff --git a/module/testtask/view/unitcases.html.php b/module/testtask/view/unitcases.html.php deleted file mode 100644 index 87ec87f6c6..0000000000 --- a/module/testtask/view/unitcases.html.php +++ /dev/null @@ -1,58 +0,0 @@ - - * @package testcase - * @version $Id$ - * @link https://www.zentao.net - */ -?> -global->flow); -?> - -global->flow == 'full'):?> - -
        '> -
        - - -
        -
        - - -
        - -
        - - diff --git a/module/testtask/view/view.html.php b/module/testtask/view/view.html.php deleted file mode 100644 index 69c5e263ac..0000000000 --- a/module/testtask/view/view.html.php +++ /dev/null @@ -1,135 +0,0 @@ - - * @package case - * @version $Id: view.html.php 4141 2013-01-18 06:15:13Z zhujinyonging@gmail.com $ - * @link https://www.zentao.net - */ -?> - - -session->testtaskList ? $this->session->testtaskList : $this->createLink('testtask', 'browse', "productID=$task->product");?> - -
        -
        -
        -
        -
        testtask->desc;?>
        -
        desc) ? $task->desc : $lang->noData;?>
        -
        - fetch('file', 'printFiles', array('files' => $task->files, 'fieldset' => 'true', 'object' => $task, 'method' => 'view', 'showDelete' => false));?> - report):?> -
        -
        testtask->report;?>
        -
        report;?>
        -
        - - createLink('action', 'comment', "objectType=testtask&objectID=$task->id"); - ?> -
        - printExtendFields($task, 'div', "position=left&inForm=0&inCell=1");?> -
        -
        -
        - ' . $lang->goback, '', 'btn btn-secondary');?> -
        - testtask->buildOperateMenu($task, 'view');?> -
        -
        -
        -
        -
        -
        -
        testtask->legendBasicInfo;?>
        -
        - - - multiple)):?> - - - - - - - - - - - - - type) as $type) $testType .= zget($lang->testtask->typeList, $type) . ' ';?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        testtask->execution;?>executionName : html::a($this->createLink('execution', 'story', "executionID=$task->execution"), $task->executionName, '', "title='{$task->executionName}'");?>
        testtask->build;?> - build == 'trunk') - { - print($lang->trunk); - } - else - { - $isOnlybody ? print($task->buildName) : print(html::a($this->createLink('build', 'view', "buildID=$task->build"), $task->buildName, '', "title='{$task->buildName}'")); - } - ?> -
        testtask->type;?>
        testtask->owner;?>owner);?>
        testtask->mailto;?>mailto)); foreach($mailto as $account) echo ' ' . zget($users, $account, $account);?>
        testtask->pri;?>testtask->priList, $task->pri);?>
        testtask->begin;?>begin;?>
        testtask->end;?>end;?>
        testtask->realFinishedDate;?>realFinishedDate)) echo $task->realFinishedDate;?>
        testtask->status;?>processStatus('testtask', $task);?>
        testtask->testreport;?>testreport) ? '' : html::a($this->createLink('testreport', 'view', "reportID=$task->testreport"), $testreportTitle);?>
        -
        -
        -
        - printExtendFields($task, 'div', "position=right&inForm=0&inCell=1");?> -
        -
        - -
        - -
        - diff --git a/module/todo/view/assignto.html.php b/module/todo/view/assignto.html.php deleted file mode 100755 index 5aeabfd7a7..0000000000 --- a/module/todo/view/assignto.html.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @package todo - * @version $Id: create.html.php 2741 2012-04-07 07:24:21 $ - * @link https://www.zentao.net - */ -?> - - - -
        -
        -
        -
        -
        -

        todo->assignedTo;?>

        -
        -
        - - - - - - - - - - - - - - - - - - - -
        todo->assignedTo;?>assignedTo, "class='form-control chosen'");?>
        todo->date;?> -
        - date)), "class='form-control form-date'");?> - -
        -
        -
        - - -
        -
        todo->beginAndEnd;?> -
        - date ? key($times) : $time, 'onchange=selectNext(); class="form-control chosen"');?> -
        -
        - -
        -
        -
        - - -
        -
        -
        -
        -
        -
        -
        -
        -
        - diff --git a/module/todo/view/batchcreate.html.php b/module/todo/view/batchcreate.html.php deleted file mode 100755 index 0e4cd79996..0000000000 --- a/module/todo/view/batchcreate.html.php +++ /dev/null @@ -1,131 +0,0 @@ - - * @package todo - * @version $Id: create.html.php 2741 2012-04-07 07:24:21Z areyou123456 $ - * @link https://www.zentao.net - */ -?> - - -todo->moduleList)?> -todo->getUserObjectsMethod)?> -todo->noOptions);?> -todo->typeList);?> -
        -
        -

        todo->batchCreate . $lang->todo->common;?>

        -
        - todo->date;?> - - -
        - - -
        -
        -
        -
        - createLink('custom', 'ajaxSaveCustomFields', 'module=todo§ion=custom&key=batchCreateFields')?> - -
        -
        -
        - -
        ' data-ride='table'> - - - - - - - - - - - - - - - - - todo->batchCreateNumber; $i++):?> - - - - - - - 0 ? 'ditto' : $app->user->account;?> - 0) $users['ditto'] = $lang->todo->ditto;?> - - - - - - - - - - - -
        idAB;?>'>todo->type;?>'>todo->pri;?>todo->name;?>'>todo->desc;?>todo->assignTo;?>'>todo->beginAndEnd;?>
        ' id="select-all">
        todo->typeList, '', "onchange='loadList(this.value, " . ($i + 1) . ")' class='form-control'");?>todo->priList, $pri, "class='form-control'");?> - -
        -
        > -
        - -
        -
        - -
        -
        -
        - - -
        -
        '> - - - -
        -
        -
        -';?> - - - diff --git a/module/todo/view/batchedit.html.php b/module/todo/view/batchedit.html.php deleted file mode 100644 index 73708a5eba..0000000000 --- a/module/todo/view/batchedit.html.php +++ /dev/null @@ -1,149 +0,0 @@ - - * @package todo - * @version $Id: create.html.php 2741 2012-04-07 07:24:21Z areyou123456 $ - * @link https://www.zentao.net - */ -?> - - -todo->moduleList)?> -todo->noOptions);?> -todo->typeList);?> -todo->getUserObjectsMethod)?> -
        -
        -

        todo->common . $lang->hyphen . $lang->todo->batchEdit;?>

        -
        - createLink('custom', 'ajaxSaveCustomFields', 'module=todo§ion=custom&key=batchEditFields')?> -
        -
        - -
        - - -
        '> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        idAB;?>todo->date;?>todo->type;?>'> todo->pri;?>todo->name;?>todo->assignedTo;?>'>todo->beginAndEnd;?>'> todo->status;?>
        id . html::hidden("todoIDList[$todo->id]", $todo->id);?>id]", $todo->date, "class='form-control form-date'");?> - type == 'cycle') - { - echo html::hidden("types[$todo->id]", $todo->type); - echo $lang->todo->cycle; - } - else - { - echo html::select("types[$todo->id]", $lang->todo->typeList, $todo->type, "onchange='loadList(this.value, {$todo->id}, \"{$todo->type}\", {$todo->objectID})' class='form-control'"); - } - ?> - id]", $lang->todo->priList, $todo->pri, "class='form-control chosen'");?> - -
        - type, $this->config->todo->moduleList)) - { - echo html::input("names[$todo->id]", $todo->name, "class='form-control'"); - } - elseif($todo->type == 'task') - { - echo html::select("tasks[$todo->id]", $tasks, $todo->objectID, 'class="form-control chosen"'); - } - elseif($todo->type == 'bug') - { - echo html::select("bugs[$todo->id]", $bugs, $todo->objectID, 'class="form-control chosen"'); - } - elseif($todo->type == 'story') - { - echo html::select("stories[$todo->id]", $storys, $todo->objectID, 'class="form-control chosen"'); - } - elseif($todo->type == 'issue') - { - echo html::select("issues[$todo->id]", $issues, $todo->objectID, 'class="form-control chosen"'); - } - elseif($todo->type == 'risk') - { - echo html::select("risks[$todo->id]", $risks, $todo->objectID, 'class="form-control chosen"'); - } - elseif($todo->type == 'review') - { - echo html::select("reviews[$todo->id]", $reviews, $todo->objectID, 'class="form-control chosen"'); - } - elseif($todo->type == 'testtask') - { - echo html::select("testtasks[$todo->id]", $testtasks, $todo->objectID, 'class="form-control chosen"'); - } - elseif($todo->type == 'opportunity') - { - echo html::select("opportunities[$todo->id]", $opportunities, $todo->objectID, 'class="form-control chosen"'); - } - elseif($todo->type == 'feedback') - { - echo html::select("feedbacks[$todo->id]", $feedbacks, $todo->objectID, 'class="form-control chosen"'); - } - ?> -
        -
        id]", $users, $todo->assignedTo, "class='form-control chosen'");?> -
        - id]", $times, substr($todo->begin, 0, 2) . substr($todo->begin, 3, 2), "onchange=\"setBeginsAndEnds($todo->id, 'begin');\" class='form-control chosen control-time-begin'" . ((isset($visibleFields['beginAndEnd']) && $todo->begin != '') ? '' : " disabled")); - echo ''; - echo html::select("ends[$todo->id]", $times, substr($todo->end, 0, 2) . substr($todo->end, 3, 2), "onchange=\"setBeginsAndEnds($todo->id, 'end');\" class='form-control chosen control-time-end'" . ((isset($visibleFields['beginAndEnd']) && $todo->begin != '') ? '' : " disabled")); - ?> - -
        - begin == '') echo "checked='checked'";?>> - -
        -
        -
        -
        id]", $lang->todo->statusList, $todo->status, "class='form-control chosen'");?>
        - - -
        -
        - -
        - diff --git a/module/todo/view/create.html.php b/module/todo/view/create.html.php deleted file mode 100644 index 21a0b4d171..0000000000 --- a/module/todo/view/create.html.php +++ /dev/null @@ -1,193 +0,0 @@ - - * @package todo - * @version $Id: create.html.php 4728 2013-05-03 06:14:34Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - -todo->noTodo);?> -todo->moduleList)?> -todo->getUserObjectsMethod)?> - $lang->todo->name, 'objectID' => $lang->todo->objectID));?> -vision);?> -todo->noOptions);?> -todo->typeList);?> -
        -
        -
        -

        todo->create;?>

        -
        -
        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        todo->date;?> -
        - - -
        - - -
        -
        - -
        - - -
        -
        -
        -
        todo->type;?>todo->typeList, '', 'onchange="loadList(this.value);" class="form-control"');?>
        todo->assignTo;?>user->account, 'class="form-control chosen"');?>
        todo->name;?> - -
        -
        - todo->pri;?> -
        - - -
        -
        -
        todo->desc;?>
        todo->status;?>todo->statusList, '', "class='form-control chosen'");?>
        todo->beginAndEnd;?> -
        - -
        -
        -
        - - -
        -
        todo->private;?> -
        - - -
        -
        - - session->todoList, $lang->goback, '', "class='btn btn-back btn-wide'");?> -
        -
        -
        -
        - - - diff --git a/module/todo/view/edit.html.php b/module/todo/view/edit.html.php deleted file mode 100644 index eab969d200..0000000000 --- a/module/todo/view/edit.html.php +++ /dev/null @@ -1,205 +0,0 @@ - - * @package todo - * @version $Id: edit.html.php 4728 2013-05-03 06:14:34Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - -todo->moduleList)?> -todo->getUserObjectsMethod)?> -objectID);?> -type);?> - $lang->todo->name, 'objectID' => $lang->todo->objectID));?> -vision);?> -todo->noOptions);?> -todo->typeList);?> - - - -
        -
        -
        -

        - id;?> - createLink('todo', 'view', 'todo=' . $todo->id), $todo->name);?> - arrow . $lang->todo->edit;?> -

        -
        - -
        -
        - - diff --git a/module/todo/view/export.html.php b/module/todo/view/export.html.php deleted file mode 100755 index 266fa8d27d..0000000000 --- a/module/todo/view/export.html.php +++ /dev/null @@ -1,13 +0,0 @@ - - * @package todo - * @version $Id$ - * @link https://www.zentao.net - */ -?> - diff --git a/module/todo/view/view.html.php b/module/todo/view/view.html.php deleted file mode 100644 index cf00105845..0000000000 --- a/module/todo/view/view.html.php +++ /dev/null @@ -1,285 +0,0 @@ - - * @package todo - * @version $Id: view.html.php 4955 2013-07-02 01:47:21Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - - -
        -
        -
        -
        -
        - todo->desc; - if($todo->type == 'bug') common::printLink('bug', 'view', "id={$todo->objectID}", ' BUG#' . $todo->objectID); - if($todo->type == 'task') common::printLink('task', 'view', "id={$todo->objectID}", ' TASK#' . $todo->objectID); - if($todo->type == 'story') common::printLink('story', 'view', "id={$todo->objectID}", ' STORY#' . $todo->objectID); - ?> -
        -
        desc;?>
        -
        - createLink('action', 'comment', "objectType=todo&objectID=$todo->id");?> - -
        - -
        -
        - session->todoList) - { - $browseLink = empty($todo->deleted) ? $this->session->todoList : $this->createLink('action', 'trash'); - } - elseif($todo->account == $app->user->account) - { - $browseLink = $this->createLink('my', 'todo'); - } - else - { - $browseLink = $this->createLink('user', 'todo', "userID=$user->id"); - } - - if(!$todo->deleted) - { - if($this->app->user->admin or ($this->app->user->account == $todo->account) or ($this->app->user->account == $todo->assignedTo)) - { - if($todo->status == 'wait') common::printLink('todo', 'start', "todoID=$todo->id", "", 'hiddenwin', "title='{$lang->todo->start}' class='btn showinonlybody'"); - if($todo->status == 'done' or $todo->status == 'closed') common::printLink('todo', 'activate', "todoID=$todo->id", "", 'hiddenwin', "title='{$lang->todo->activate}' class='btn showinonlybody'"); - if($todo->status == 'done') common::printLink('todo', 'close', "todoID=$todo->id", "", 'hiddenwin', "title='{$lang->todo->close}' class='btn showinonlybody'"); - common::printLink('todo', 'edit', "todoID=$todo->id", "", '', "title='{$lang->todo->edit}' class='btn showinonlybody'"); - common::printLink('todo', 'delete', "todoID=$todo->id", "", 'hiddenwin', "title='{$lang->todo->delete}' class='btn showinonlybody'"); - - if($todo->status != 'done' && $todo->status != 'closed') - { - echo "
        "; - echo html::a($this->createLink('todo', 'finish', "id=$todo->id", 'html', true), "", 'hiddenwin', "title='{$lang->todo->finish}' class='btn showinonlybody btn-success'"); - $createStoryPriv = common::hasPriv('story', 'create'); - $createTaskPriv = common::hasPriv('task', 'create'); - $createBugPriv = common::hasPriv('bug', 'create'); - $printBtn = $config->vision == 'lite' and empty($projects); - if($printBtn and ($createStoryPriv or $createTaskPriv or $createBugPriv)) - { - $isonlybody = isonlybody(); - unset($_GET['onlybody']); - echo ""; - echo ""; - if($isonlybody) $_GET['onlybody'] = 'yes'; - } - echo "
        "; - } - } - } - common::printRPN($browseLink); - ?> -
        -
        -
        -
        -
        -
        -
        todo->legendBasic;?>
        -
        - - - - - - - - - - - - - - - - - - - - - - - - - - assignedTo)):?> - - - - - - - - - - - - - -
        todo->pri;?>pri;?>' title='todo->priList, $todo->pri, $todo->pri);?>'>todo->priList, $todo->pri)?>
        todo->status;?> todo->statusList[$todo->status];?>
        todo->type;?>todo->typeList[$todo->type];?>
        todo->account;?>account);?>
        todo->date;?>date == '20300101' ? $lang->todo->periods['future'] : formatTime($todo->date, DT_DATE1);?>
        todo->beginAndEnd;?>begin])) echo $times[$todo->begin]; if(isset($times[$todo->end])) echo ' ~ ' . $times[$todo->end];?>
        todo->assignedTo;?>assignedTo);?>
        todo->assignedBy;?>assignedBy);?>
        todo->assignedDate;?>assignedDate, DT_DATE1);?>
        -
        -
        - cycle):?> - config = json_decode($todo->config);?> -
        -
        todo->cycle;?>
        -
        - - - - - - - - - -
        todo->beginAndEnd?>config->begin . " ~ " . $todo->config->end;?>
        todo->cycleConfig?> - config->type == 'day') - { - if(isset($todo->config->day)) echo $lang->todo->every . $todo->config->day . $lang->day; - - if(isset($todo->config->specifiedDate)) - { - $specifiedNotes = $lang->todo->specify; - if(isset($todo->config->cycleYear)) $specifiedNotes .= $lang->todo->everyYear; - $specifiedNotes .= zget($lang->datepicker->monthNames, $todo->config->specify->month) . $todo->config->specify->day . $lang->todo->day; - echo $specifiedNotes; - } - } - elseif($todo->config->type == 'week') - { - foreach(explode(',', $todo->config->week) as $week) echo $lang->todo->dayNames[$week] . ' '; - } - elseif($todo->config->type == 'month') - { - foreach(explode(',', $todo->config->month) as $month) echo $month . ' '; - } - echo '
        '; - if($todo->config->beforeDays) printf($lang->todo->lblBeforeDays, $todo->config->beforeDays); - ?> -
        -
        -
        - -
        -
        -
        -
        -
        -
        - - - -id);?> -execution->selectExecution);?> -todo->selectProduct);?> - - diff --git a/module/transfer/control.php b/module/transfer/control.php index ca391754d5..53cac5003f 100755 --- a/module/transfer/control.php +++ b/module/transfer/control.php @@ -97,9 +97,11 @@ class transfer extends control public function import(string $module, string $locate = '') { $locate = $locate ? $locate : $this->session->showImportURL; - if($_FILES) + if($this->server->request_method == 'POST') { $file = $this->loadModel('file')->getUpload('file'); + if(empty($_FILES)) return $this->send(array('result' => 'fail', 'message' => $this->lang->file->errorFileFormat)); + if(empty($file[0])) return $this->send(array('result' => 'fail', 'message' => $this->lang->testcase->errorFileNotEmpty)); if(!empty($file['error'])) return $this->send(array('result' => 'fail', 'message' => $this->lang->file->uploadError[$file['error']])); $file = $file[0]; diff --git a/module/tree/view/browse.html.php b/module/tree/view/browse.html.php deleted file mode 100644 index 016110a1b1..0000000000 --- a/module/tree/view/browse.html.php +++ /dev/null @@ -1,373 +0,0 @@ - - * @package tree - * @version $Id: browse.html.php 4796 2013-06-06 02:21:59Z zhujinyonging@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - - - - - - - - -tree->noSubmodule);?> - -app->loadLang('doc');?> -type) && $root->type != 'normal')) ? true : false;?> -tree->name; -if($viewType == 'line') $name = $lang->tree->line; -if($viewType == 'api') $name = $lang->tree->dir; -if($viewType == 'doc') $name = $lang->doc->catalogName; -if($viewType == 'report') $name = $lang->tree->reportGroup; -if($viewType == 'trainskill' or $viewType == 'trainpost') $name = $lang->tree->cate; - -$childTitle = $lang->tree->child; -if(strpos($viewType, 'doc') !== false or $viewType == 'api') $childTitle = $lang->doc->childType; -if($viewType == 'line' or $viewType == 'trainskill' or $viewType == 'trainpost') $childTitle = ''; -if($viewType == 'host') $childTitle = $lang->tree->childGroup; - -$editTitle = $lang->tree->edit; -$deleteTitle = $lang->tree->delete; -if($viewType == 'doc' or $viewType == 'api') -{ - $editTitle = $lang->doc->editType; - $deleteTitle = $lang->doc->deleteType; -} -?> - -
        -
        -
        -
        -
        - tab == 'product' and $viewType == 'story'):?> -
        - createLink('tree', 'viewHistory', "productID=$rootID", '', true), $lang->history, '', "class='btn btn-sm btn-primary iframe'");?> -
        - -
        -
        -
          -
          -
          -
          -
          -
          -
          -
          - - doc->manageType : $lang->tree->$manageChild;?> -
          - - -
          tree->syncFromProduct, '', "class='btn btn-sm btn-primary'")?>
          - -
          createLink('feedback', 'syncProduct', "productID=$rootID&module=feedback&parent=$parent", '', true), $lang->tree->syncProductModule, '', "class='btn btn-sm btn-primary iframe' data-width='60%'");?>
          - -
          createLink('ticket', 'syncProduct', "productID=$rootID&parent=$parent", '', true), $lang->tree->syncProductModule, '', "class='btn btn-sm btn-primary iframe' data-width='60%'");?>
          - -
          -
          -
          '> - - - - - - - - - - - - - - -
          - " . html::a($this->createLink('tree', 'browse', "root=$rootID&viewType=$viewType¤tModuleID=0&branch=0&from=$from", '', ''), empty($root->name) ? '' : $root->name, '', "data-app='{$this->app->tab}'") . ""; - foreach($parentModules as $module) - { - echo "" . html::a($this->createLink('tree', 'browse', "root=$rootID&viewType=$viewType¤tModuleID=$module->id&branch=0&from=$from"), $module->name, '', "data-app='{$this->app->tab}'") . " "; - } - ?> - -
          - - - - - - - order > $maxOrder) $maxOrder = $sonModule->order;?> - type == $viewType ? '' : 'disabled';?> -
          -
          id]", $sonModule->name, 'class="form-control"' . $disabled);?>
          - -
          id]", $branches, $sonModule->branch, 'class="form-control" disabled');?>
          - -
          id]", $sonModule->short, "class='form-control' placeholder='{$lang->tree->short}' $disabled") . html::hidden("order[id$sonModule->id]", $sonModule->order);?>
          -
          -
          - - -
          -
          - - -
          - - -
          tree->short}'");?>
          -
          - - -
          -
          - -
          - -
          -
          -
          - -
          - -
          tree->short}'");?>
          -
          - - -
          -
          -
          -
          - - - - -
          -
          -
          -
          -
          -
          -app->tab);?> - - - - diff --git a/module/tree/view/browsetask.html.php b/module/tree/view/browsetask.html.php deleted file mode 100644 index 793d06ad4b..0000000000 --- a/module/tree/view/browsetask.html.php +++ /dev/null @@ -1,248 +0,0 @@ - - * @package tree - * @version $Id: browse.html.php 4796 2013-06-06 02:21:59Z zhujinyonging@gmail.com $ - * @link https://www.zentao.net - */ -?> - -tab);?> - - -
          -
          -
          -
          -
          -
          -
          -
            -
            -
            -
            -
            -
            id}&viewType=task");?>'> -
            -
            -
            multiple ? $lang->tree->manageTaskChild : $lang->tree->manageProjectChild;?>
            -
            -
            - - - - - - - - - -
            - " . html::a($this->createLink('tree', 'browsetask', "root={$root->id}&productID=$productID&viewType=task"), $root->name, '', "data-app='{$app->tab}'") . ""; - foreach($parentModules as $module) - { - echo "" . html::a($this->createLink('tree', 'browsetask', "root={$root->id}&productID=$productID&moduleID=$module->id"), $module->name, '', "data-app='{$app->tab}'") . " "; - } - ?> - -
            - - - -
            -
            id]", $product->name, 'class=form-control disabled="true"')?>
            -
            - - - - order > $maxOrder) $maxOrder = $sonModule->order; - $disabled = $sonModule->type == 'task' ? '' : 'disabled'; - ?> -
            -
            id]", $sonModule->name, "class='form-control' placeholder='{$lang->tree->name}' $disabled")?>
            -
            - id]", $sonModule->short, "class='form-control' placeholder='{$lang->tree->short}' $disabled"); - echo html::hidden("order[id$sonModule->id]", $sonModule->order); - ?> -
            -
            -
            - - -
            -
            tree->name}'")?>
            -
            tree->short}'")?>
            -
            - - -
            - branch);?> -
            - -
            -
            -
            -
            tree->name}'");?>
            -
            tree->short}'");?>
            -
            - - -
            - branch);?> -
            -
            -
            - goback, '', "class='btn btn-wide'"); - echo html::hidden('parentModuleID', $currentModuleID); - echo html::hidden('maxOrder', $maxOrder); - ?> - -
            -
            -
            -
            -
            -
            - - diff --git a/module/tree/view/edit.html.php b/module/tree/view/edit.html.php deleted file mode 100644 index e1161d37cc..0000000000 --- a/module/tree/view/edit.html.php +++ /dev/null @@ -1,207 +0,0 @@ - - * @package tree - * @version $Id: edit.html.php 4795 2013-06-04 05:59:58Z zhujinyonging@gmail.com $ - * @link https://www.zentao.net - */ -?> -app->getWebRoot(); -$jsRoot = $webRoot . "js/"; -js::set('type', $type); -if(isset($pageCSS)) css::internal($pageCSS); -?> - - diff --git a/module/tree/view/viewhistory.html.php b/module/tree/view/viewhistory.html.php deleted file mode 100644 index 8c8229ee85..0000000000 --- a/module/tree/view/viewhistory.html.php +++ /dev/null @@ -1,21 +0,0 @@ - - * @package tree - * @version $Id: edit.html.php 4795 2022-07-05 16:10:58Z $ - * @link https://www.zentao.net - */ -?> - - -
            -

            tree->emptyHistory;?>

            -
            - - - - diff --git a/module/tutorial/view/index.html.php b/module/tutorial/view/index.html.php deleted file mode 100644 index 2ba4473d61..0000000000 --- a/module/tutorial/view/index.html.php +++ /dev/null @@ -1,102 +0,0 @@ - - * @package tutorial - * @version $Id: browse.html.php 4728 2013-05-03 06:14:34Z sunhao@cnezsoft.com $ - * @link https://www.zentao.net - */ -?> - - -
            -
            - -
            -
            - -
            -
            -

            tutorial->congratulation;?>

            -   ' class='btn btn-outline'> tutorial->exit;?> -
            -
            -
            -

            tutorial->congratulateTask;?>

            - -
            -
            -
            - -
            - - -tutorial->serverErrorTip);?> - - -tutorial->targetPageTip);?> -tutorial->target);?> -tutorial->targetAppTip);?> -tutorial->requiredTip);?> - - diff --git a/module/tutorial/view/start.html.php b/module/tutorial/view/start.html.php deleted file mode 100644 index e863bb4a84..0000000000 --- a/module/tutorial/view/start.html.php +++ /dev/null @@ -1,20 +0,0 @@ - - * @package tutorial - * @version $Id: browse.html.php 4728 2013-05-03 06:14:34Z sunhao@cnezsoft.com $ - * @link https://www.zentao.net - */ -?> - -
            -
            -

            tutorial->common;?>

            -

            tutorial->desc;?>

            - tutorial->start, '_top', "class='btn btn-primary btn-lg btn-wide btn-info'");;?> -
            - diff --git a/module/upgrade/config.php b/module/upgrade/config.php index 5d9080b439..9b41aca0c0 100644 --- a/module/upgrade/config.php +++ b/module/upgrade/config.php @@ -72,6 +72,7 @@ $config->upgrade->maxVersion['max7_0'] = '21_7_1'; $config->upgrade->maxVersion['max7_1'] = '21_7_2'; $config->upgrade->maxVersion['max7_2'] = '21_7_3'; $config->upgrade->maxVersion['max7_3'] = '21_7_4'; +$config->upgrade->maxVersion['max7_4'] = '21_7_5'; $config->upgrade->maxVersion['max7_4'] = '21_7_5'; // max insert position. $config->upgrade->bizVersion = array(); @@ -183,6 +184,7 @@ $config->upgrade->bizVersion['biz12_0'] = '21_7_1'; $config->upgrade->bizVersion['biz12_1'] = '21_7_2'; $config->upgrade->bizVersion['biz12_2'] = '21_7_3'; $config->upgrade->bizVersion['biz12_3'] = '21_7_4'; +$config->upgrade->bizVersion['biz12_4'] = '21_7_5'; $config->upgrade->bizVersion['biz12_4'] = '21_7_5'; // biz insert position. $config->upgrade->proVersion = array(); @@ -331,6 +333,7 @@ $config->upgrade->ipdVersion['ipd4_0'] = '21_7_1'; $config->upgrade->ipdVersion['ipd4_1'] = '21_7_2'; $config->upgrade->ipdVersion['ipd4_2'] = '21_7_3'; $config->upgrade->ipdVersion['ipd4_3'] = '21_7_4'; +$config->upgrade->ipdVersion['ipd4_4'] = '21_7_5'; $config->upgrade->ipdVersion['ipd4_4'] = '21_7_5'; // ipd insert position. $config->upgrade->lowerTables = array(); @@ -1496,6 +1499,10 @@ $config->delete['21_6_beta'][] = 'extension/biz/project/ext/model/zentaoipd.php' $config->delete['21_7_2'][] = 'module/solution'; +$config->delete['21_7_5'][] = 'extension/biz/doc/ext/js/app/zentaobiz.ui.js'; +$config->delete['21_7_5'][] = 'extension/max/doc/ext/js/app/zentaobiz.ui.js'; +$config->delete['21_7_5'][] = 'extension/ipd/doc/ext/js/app/zentaobiz.ui.js'; + $config->upgrade->openModules = array('action', 'admin', 'ai', 'bi', 'aiapp', 'api', 'automation', 'backup', 'block', 'branch', 'budget', 'bug', 'build', 'cache', 'caselib', 'chart', 'ci', 'client', 'common', 'company', 'compile', 'convert', 'cron', 'custom', 'datatable', 'dataview', 'dept', 'design', 'dev', 'dimension', 'doc', 'durationestimation', 'entry', 'execution', 'extension', 'file', 'git', 'gitlab', 'group', 'holiday', 'im', 'index', 'index.html', 'install', 'issue', 'jenkins', 'job', 'kanban', 'license', 'mail', 'message', 'metric', 'misc', 'mr', 'my', 'personnel', 'pipeline', 'product', 'productplan', 'productset', 'program', 'programplan', 'project', 'projectbuild', 'projectplan', 'projectrelease', 'projectstory', 'pivot', 'qa', 'release', 'repo', 'report', 'risk', 'score', 'screen', 'search', 'setting', 'sonarqube', 'sso', 'stage', 'stakeholder', 'story', 'subject', 'svn', 'task', 'testcase', 'testreport', 'testsuite', 'testtask', 'todo', 'tree', 'tutorial', 'upgrade', 'user', 'webhook', 'weekly', 'workestimation', 'gitea', 'gogs', 'transfer', 'zahost', 'zanode', 'editor', 'charter', 'roadmap', 'account', 'cne', 'host', 'instance', 'ops', 'serverroom', 'space', 'store', 'system', 'solution', 'demand', 'gitfox', 'epic', 'requirement', 'mark'); $config->upgrade->unsetModules = array('design', 'program', 'programplan', 'projectbuild', 'projectrelease', 'stage', 'stakeholder', 'product', 'branch', 'productplan', 'release', 'build', 'qa', 'bug', 'testcase', 'testtask', 'testreport', 'testsuite', 'caselib', 'automation', 'repo', 'ci', 'compile', 'jenkins', 'job', 'svn', 'gitlab', 'sonarqube', 'mr', 'git', 'report', 'sqlbuilder', 'feedback', 'faq', 'attend', 'holiday', 'leave', 'makeup', 'overtime', 'lieu', 'ops', 'host', 'serverroom', 'account', 'domain', 'service', 'deploy', 'conference', 'traincourse', 'pssp', 'baseline', 'classify', 'cm', 'cmcl', 'auditcl', 'reviewcl', 'process', 'activity', 'zoutput', 'auditplan', 'nc', 'subject', 'weekly', 'workestimation', 'issue', 'durationestimation', 'risk', 'opportunity', 'trainplan', 'gapanalysis', 'researchplan', 'researchreport', 'meeting', 'meetingroom', 'budget', 'reviewissue', 'reviewsetting', 'review', 'milestone', 'measurement', 'measrecord', 'assetlib', 'setting', 'im', 'client', 'ldap', 'dev', 'api', 'gitea', 'gogs', 'zanode', 'zahost'); diff --git a/module/upgrade/lang/version.php b/module/upgrade/lang/version.php index ab5a02cce6..46c42f2e17 100644 --- a/module/upgrade/lang/version.php +++ b/module/upgrade/lang/version.php @@ -217,6 +217,7 @@ $lang->upgrade->fromVersions['21_7_1'] = '21.7.1'; $lang->upgrade->fromVersions['21_7_2'] = '21.7.2'; $lang->upgrade->fromVersions['21_7_3'] = '21.7.3'; $lang->upgrade->fromVersions['21_7_4'] = '21.7.4'; +$lang->upgrade->fromVersions['21_7_5'] = '21.7.5'; $lang->upgrade->fromVersions['21_7_5'] = '21.7.5'; // pms insert position. global $config; @@ -435,6 +436,7 @@ $lang->upgrade->fromVersions['biz12_0'] = 'Biz12.0'; $lang->upgrade->fromVersions['biz12_1'] = 'Biz12.1'; $lang->upgrade->fromVersions['biz12_2'] = 'Biz12.2'; $lang->upgrade->fromVersions['biz12_3'] = 'Biz12.3'; +$lang->upgrade->fromVersions['biz12_4'] = 'Biz12.4'; $lang->upgrade->fromVersions['biz12_4'] = 'Biz12.4'; // biz insert position. /* Max. */ @@ -511,6 +513,7 @@ $lang->upgrade->fromVersions['max7_0'] = 'Max7.0'; $lang->upgrade->fromVersions['max7_1'] = 'Max7.1'; $lang->upgrade->fromVersions['max7_2'] = 'Max7.2'; $lang->upgrade->fromVersions['max7_3'] = 'Max7.3'; +$lang->upgrade->fromVersions['max7_4'] = 'Max7.4'; $lang->upgrade->fromVersions['max7_4'] = 'Max7.4'; // max insert position. /* Ipd */ @@ -548,4 +551,5 @@ $lang->upgrade->fromVersions['ipd3_7'] = 'Ipd3.7'; $lang->upgrade->fromVersions['ipd4_0'] = 'Ipd4.0'; $lang->upgrade->fromVersions['ipd4_1'] = 'Ipd4.1'; $lang->upgrade->fromVersions['ipd4_2'] = 'Ipd4.2'; +$lang->upgrade->fromVersions['ipd4_3'] = 'Ipd4.3'; $lang->upgrade->fromVersions['ipd4_3'] = 'Ipd4.3'; // ipd insert position. diff --git a/module/upgrade/view/afterexec.html.php b/module/upgrade/view/afterexec.html.php deleted file mode 100644 index 5eab2b5bf5..0000000000 --- a/module/upgrade/view/afterexec.html.php +++ /dev/null @@ -1,140 +0,0 @@ - - * @package upgrade - * @version $Id: execute.html.php 5119 2013-07-12 08:06:42Z wyd621@gmail.com $ - */ -?> - -
            - -
            - - diff --git a/module/upgrade/view/backup.html.php b/module/upgrade/view/backup.html.php deleted file mode 100644 index 3e95a7709b..0000000000 --- a/module/upgrade/view/backup.html.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @package upgrade - * @version $Id: index.html.php 4129 2013-01-18 01:58:14Z wwccss $ - */ -?> - -
            - -
            - diff --git a/module/upgrade/view/checkextension.html.php b/module/upgrade/view/checkextension.html.php deleted file mode 100644 index 9bbebb6940..0000000000 --- a/module/upgrade/view/checkextension.html.php +++ /dev/null @@ -1,27 +0,0 @@ - - * @package upgrade - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
            -
            - -
            -
            - diff --git a/module/upgrade/view/confirm.html.php b/module/upgrade/view/confirm.html.php deleted file mode 100644 index 7a4a35a415..0000000000 --- a/module/upgrade/view/confirm.html.php +++ /dev/null @@ -1,29 +0,0 @@ - - * @package upgrade - * @version $Id: confirm.html.php 4129 2013-01-18 01:58:14Z wwccss $ - */ -?> - -
            -
            '> - -
            -
            - diff --git a/module/upgrade/view/consistency.html.php b/module/upgrade/view/consistency.html.php deleted file mode 100644 index 4f9cfb61bf..0000000000 --- a/module/upgrade/view/consistency.html.php +++ /dev/null @@ -1,29 +0,0 @@ - - * @package upgrade - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
            -
            - -
            -
            - diff --git a/module/upgrade/view/createprogram.html.php b/module/upgrade/view/createprogram.html.php deleted file mode 100644 index 073e3f6ce7..0000000000 --- a/module/upgrade/view/createprogram.html.php +++ /dev/null @@ -1,103 +0,0 @@ - - - - - -
            upgrade->dataMethod;?>
            lang->upgrade->projectType, $projectType);?>
            '>upgrade->createProjectTip?>
            '>upgrade->createExecutionTip?>
            - - - - - - - - - - - - - - - - - - - '> - - - - - - - - - - - - - project->subAclList['program']);?> - - - - -
            upgrade->setProject : $lang->upgrade->setProgram;?>
            - - upgrade->programName;?> - -
            - - - -
            - - -
            -
            -
            - -
            program->common . $lang->program->status;?>program->statusList, '', "class='form-control chosen'");?>
            - - upgrade->projectName;?> - -
            - - - - -
            - - -
            -
            - -
            -
            project->status;?>project->statusList, '', "class='form-control chosen'");?>
            - - upgrade->line;?> - -
            - - - - -
            - - -
            -
            - -
            -
            project->PM;?> '') + $users, '', "class='form-control chosen'");?>
            project->dateRange;?> -
            - project->begin . "' required");?> - project->to;?> - project->end . "' required");?> - -
            - - -
            -
            -
            -
            project->acl;?>program->aclList, 'open', '', 'block'));?>
            -
            diff --git a/module/upgrade/view/execute.html.php b/module/upgrade/view/execute.html.php deleted file mode 100644 index 1c4fa12777..0000000000 --- a/module/upgrade/view/execute.html.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @package upgrade - * @version $Id: execute.html.php 5119 2013-07-12 08:06:42Z wyd621@gmail.com $ - */ -?> - -
            - -
            - - diff --git a/module/upgrade/view/license.html.php b/module/upgrade/view/license.html.php deleted file mode 100644 index 188208b48c..0000000000 --- a/module/upgrade/view/license.html.php +++ /dev/null @@ -1,29 +0,0 @@ - - * @package upgrade - * @version $Id: selectversion.html.php 1292 2014-06-05 03:03:52Z guanxiying $ - */ -?> - -
            - -
            - diff --git a/module/upgrade/view/mergebyline.html.php b/module/upgrade/view/mergebyline.html.php deleted file mode 100644 index 2d9a7c570a..0000000000 --- a/module/upgrade/view/mergebyline.html.php +++ /dev/null @@ -1,87 +0,0 @@ - - -
            - upgrade->productCount, $noMergedProductCount); - if($content) $content .= ','; - if($noMergedSprintCount) $content .= sprintf($lang->upgrade->projectCount, $noMergedSprintCount); - printf($lang->upgrade->mergeSummary, $content); - echo '
            ' . $lang->upgrade->mergeByProject; - ?> -
            -
            -
            -
            -
            -
            - -
            -
            - -
            -
            -
            -
            -
            -
            -
            -
            -
            - -
            -
            - -
            -
            -
            - - -
            lineBox'> - id] as $productID => $product):?> -
            -
            - id]", array($productID => $product->name), '', "title='{$product->name}' data-productid='{$product->id}' data-line='{$line->id}' data-begin='{$product->createdDate}' data-programid='{$product->program}' class='tile'");?> - id][$productID]", $productID);?> -
            -
            -
            - - -
            - id][$productID]", array($sprint->id => $sprint->name), '', "title='{$sprint->name}' data-product='{$product->id}' data-line='{$line->id}' data-begin='{$sprint->begin}' data-end='{$sprint->end}' data-status='{$sprint->status}' data-pm='{$sprint->PM}' class='tile'");?> - id][$productID][$sprint->id]", $sprint->id);?> -
            - - -
            -
            -
            - - -
            - -
            -
            -
            -
            -
            -
            - name; - $product = isset($lineGroups[$line->id]) ? reset($lineGroups[$line->id]) : ''; - $sprintName = $product ? $product->name : ''; - include "./createprogram.html.php"; - ?> -
            -
            -
            diff --git a/module/upgrade/view/mergebyproduct.html.php b/module/upgrade/view/mergebyproduct.html.php deleted file mode 100644 index c02ecc5259..0000000000 --- a/module/upgrade/view/mergebyproduct.html.php +++ /dev/null @@ -1,55 +0,0 @@ - -
            - upgrade->productCount, $noMergedProductCount); - if($content) $content .= ','; - if($noMergedSprintCount) $content .= sprintf($lang->upgrade->projectCount, $noMergedSprintCount); - printf($lang->upgrade->mergeSummary, $content); - echo '
            ' . $lang->upgrade->mergeByProject; - ?> -
            -
            -
            -
            -
            -
            - -
            -
            - -
            -
            -
            - $product):?> -
            -
            - id => $product->name), '', "data-productid='{$product->id}' data-begin='{$product->createdDate}' data-programid='{$product->program}'");?> -
            -
            -
            - - -
            - id => $sprint->name), '', "data-product='{$productID}' data-begin='{$sprint->begin}' data-end='{$sprint->end}' data-status='{$sprint->status}' data-pm='{$sprint->PM}'");?> - id]", $sprint->id);?> -
            - - -
            -
            -
            - -
            -
            -
            -
            -
            -
            - -
            -
            -
            diff --git a/module/upgrade/view/mergebysprint.html.php b/module/upgrade/view/mergebysprint.html.php deleted file mode 100644 index 0ce539b84e..0000000000 --- a/module/upgrade/view/mergebysprint.html.php +++ /dev/null @@ -1,32 +0,0 @@ -
            - upgrade->productCount, $noMergedProductCount); - if($content) $content .= ','; - if($noMergedSprintCount) $content .= sprintf($lang->upgrade->projectCount, $noMergedSprintCount); - printf($lang->upgrade->mergeSummary, $content); - echo '
            ' . $lang->upgrade->mergeByProject; - ?> -
            -
            -
            -
            -
            -
            - -
            -
            -
            - $sprint):?> -
            - id => $sprint->name), '', "data-begin='{$sprint->begin}' data-end='{$sprint->end}' data-status='{$sprint->status}' data-pm='{$sprint->PM}'");?> -
            - -
            -
            -
            -
            -
            -
            -
            -
            diff --git a/module/upgrade/view/mergeprogram.html.php b/module/upgrade/view/mergeprogram.html.php deleted file mode 100644 index 8bb875f28c..0000000000 --- a/module/upgrade/view/mergeprogram.html.php +++ /dev/null @@ -1,39 +0,0 @@ - - * @package upgrade - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -execution->weekend);?> - - -upgrade->errorNoProduct);?> -upgrade->errorNoExecution);?> -
            -
            - -
            -
            - diff --git a/module/upgrade/view/mergerepo.html.php b/module/upgrade/view/mergerepo.html.php deleted file mode 100644 index 758465d518..0000000000 --- a/module/upgrade/view/mergerepo.html.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @package upgrade - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
            -
            - -
            -
            - diff --git a/module/upgrade/view/moveextfiles.html.php b/module/upgrade/view/moveextfiles.html.php deleted file mode 100644 index 093bb1af58..0000000000 --- a/module/upgrade/view/moveextfiles.html.php +++ /dev/null @@ -1,41 +0,0 @@ - - * @package upgrade - * @version $Id: moveextfiles.html.php 5119 2022-02-21 13:22:42Z $ - */ -?> - -
            -
            "> - - -
            - - - - diff --git a/module/upgrade/view/renameobject.html.php b/module/upgrade/view/renameobject.html.php deleted file mode 100644 index 7a9d6c257d..0000000000 --- a/module/upgrade/view/renameobject.html.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @package upgrade - * @version $Id: renameobject.html.php 4129 2021-11-30 13:07:14Z sunguangming $ - */ -?> - - -
            -
            -
            -

            upgrade->duplicateProject;?>

            -
            -
            - - - - - - - $objectList):?> - $object):?> - id == end($objectList)->id) echo "class='group-end'";?>> - - - - - - - - - -
            $type->id;?>$type->name;?>upgrade->editedName;?>
            id;?>name;?>id]", '', "class='form-control'");?>
            -
            -
            -
            - diff --git a/module/upgrade/view/selectmergemode.html.php b/module/upgrade/view/selectmergemode.html.php deleted file mode 100644 index 2f91db60fc..0000000000 --- a/module/upgrade/view/selectmergemode.html.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @package upgrade - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
            - -
            - diff --git a/module/upgrade/view/selectversion.html.php b/module/upgrade/view/selectversion.html.php deleted file mode 100644 index 2dafc30131..0000000000 --- a/module/upgrade/view/selectversion.html.php +++ /dev/null @@ -1,39 +0,0 @@ - - * @package upgrade - * @version $Id: selectversion.html.php 4129 2013-01-18 01:58:14Z wwccss $ - */ -?> - - -
            -
            '> - -
            -
            - diff --git a/module/upgrade/view/to18guide.html.php b/module/upgrade/view/to18guide.html.php deleted file mode 100644 index c3cfa3987e..0000000000 --- a/module/upgrade/view/to18guide.html.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @package upgrade - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
            - -
            - diff --git a/module/user/model.php b/module/user/model.php index f4491bd950..a681dfa14a 100644 --- a/module/user/model.php +++ b/module/user/model.php @@ -1830,10 +1830,11 @@ class userModel extends model * @param array $teams * @param array $stakeholders * @param array $whiteList + * @param array $executionStakeholderGroup * @access private * @return string */ - private function getSprintView(string $account, array $allSprints, array $manageObjects, array $teams, array $stakeholders, array $whiteList): string + private function getSprintView(string $account, array $allSprints, array $manageObjects, array $teams, array $stakeholders, array $whiteList, array $executionStakeholderGroup): string { $sprintView = ''; if(!empty($manageObjects['executions']['isAdmin'])) @@ -1850,6 +1851,7 @@ class userModel extends model $sprintTeams = !empty($teams['execution'][$sprintID]) ? $teams['execution'][$sprintID] : array(); $sprintStakeholders = !empty($stakeholders['execution'][$sprintID]) ? $stakeholders['execution'][$sprintID] : array(); $sprintWhiteList = !empty($whiteList['sprint'][$sprintID]) ? $whiteList['sprint'][$sprintID] : array(); + if($sprint->acl == 'private') $sprintStakeholders += zget($executionStakeholderGroup, $sprintID, array()); if($this->checkProjectPriv($sprint, $account, $sprintStakeholders, $sprintTeams, $sprintWhiteList)) $sprints[$sprintID] = $sprintID; /* 如果有某个迭代管理权限,也可以访问该迭代。 */ @@ -1949,8 +1951,9 @@ class userModel extends model { /* Compute parent stakeholders. */ $this->loadModel('stakeholder'); - $programStakeholderGroup = $this->stakeholder->getParentStakeholderGroup(array_keys($allPrograms)); - $projectStakeholderGroup = $this->stakeholder->getParentStakeholderGroup(array_keys($allProjects)); + $programStakeholderGroup = $this->stakeholder->getParentStakeholderGroup(array_keys($allPrograms)); + $projectStakeholderGroup = $this->stakeholder->getParentStakeholderGroup(array_keys($allProjects)); + $executionStakeholderGroup = $this->stakeholder->getParentStakeholderGroup(array_keys($allSprints)); /* 按照类型分组获取当前用户所拥有的的项目管理权限。 */ $manageObjects = $this->getManageListGroupByType($account); @@ -1959,7 +1962,7 @@ class userModel extends model $userView->programs = $this->getProgramView($account, $allPrograms, $manageObjects, $stakeholders, $whiteList, $programStakeholderGroup); $userView->products = $this->getProductView($account, $allProducts, $manageObjects, $whiteList); $userView->projects = $this->getProjectView($account, $allProjects, $manageObjects, $teams, $stakeholders, $whiteList, $projectStakeholderGroup); - $userView->sprints = $this->getSprintView($account, $allSprints, $manageObjects, $teams, $stakeholders, $whiteList); + $userView->sprints = $this->getSprintView($account, $allSprints, $manageObjects, $teams, $stakeholders, $whiteList, $executionStakeholderGroup); } /* 更新访问权限表。 */ diff --git a/module/user/test/model/getsprintview.php b/module/user/test/model/getsprintview.php new file mode 100755 index 0000000000..a4bc580aef --- /dev/null +++ b/module/user/test/model/getsprintview.php @@ -0,0 +1,85 @@ +#!/usr/bin/env php +getProductMembers(); +timeout=0 +cid=0 + +- 查看user1可访问的执行 @1 +- 查看user2可访问的执行 @1 +- 查看user3可访问的执行 @2 +- 查看user4可访问的执行 @2 +- 查看user5可访问的执行 @1 +- 查看user6可访问的执行 @2 +- 查看user7可访问的执行 @1 +- 查看user8可访问的执行 @2 +- 查看user9可访问的执行 @1 +- 查看user10可访问的执行 @2 +- 查看admin可访问的执行 @1,2,3 + +*/ +include dirname(__FILE__, 5) . '/test/lib/init.php'; +include dirname(__FILE__, 2) . '/lib/user.unittest.class.php'; + +su('admin'); + +$allSprints = array( + 1 => (object)array('id' => 1, 'program' => 0, 'acl' => 'private', 'PO' => 'admin', 'PM' => 'projectManager', 'QD' => 'QD', 'RD' => 'RD', 'type' => 'sprint', 'project' => 0), + 2 => (object)array('id' => 2, 'program' => 0, 'acl' => 'private', 'PO' => 'admin', 'PM' => 'projectManager', 'QD' => 'QD', 'RD' => 'RD', 'type' => 'sprint', 'project' => 0), + 3 => (object)array('id' => 3, 'program' => 0, 'acl' => 'private', 'PO' => 'admin', 'PM' => 'projectManager', 'QD' => 'QD', 'RD' => 'RD', 'type' => 'sprint', 'project' => 0) +); + +$teams = array( + 'execution' => array( + 1 => array('user1' => 'user1', 'user2' => 'user2'), + 2 => array('user3' => 'user3', 'user4' => 'user4'), + 3 => array() + ) +); + +$stakeholders = array( + 'execution' => array( + 1 => array('user5' => 'user5'), + 2 => array('user6' => 'user6'), + 3 => array() + ) +); + +$whiteList = array( + 'sprint' => array( + 1 => array('user7' => 'user7'), + 2 => array('user8' => 'user8'), + 3 => array() + ) +); + +$executionStakeholderGroup = array( + 1 => array('user9' => 'user9'), + 2 => array('user10' => 'user10'), + 3 => array() +); + +global $tester; +$userModel = $tester->loadModel('user'); +$ref = new ReflectionMethod($userModel, 'getSprintView'); +$ref->setAccessible(true); + +$result = array(); +foreach(array('user1', 'user2', 'user3', 'user4', 'user5', 'user6', 'user7', 'user8', 'user9', 'user10', 'admin') as $account) +{ + $result[$account] = $ref->invokeArgs($userModel, array($account, $allSprints, array(), $teams, $stakeholders, $whiteList, $executionStakeholderGroup)); +} + +r($result['user1']) && p() && e(1); // 查看user1可访问的执行 +r($result['user2']) && p() && e(1); // 查看user2可访问的执行 +r($result['user3']) && p() && e(2); // 查看user3可访问的执行 +r($result['user4']) && p() && e(2); // 查看user4可访问的执行 +r($result['user5']) && p() && e(1); // 查看user5可访问的执行 +r($result['user6']) && p() && e(2); // 查看user6可访问的执行 +r($result['user7']) && p() && e(1); // 查看user7可访问的执行 +r($result['user8']) && p() && e(2); // 查看user8可访问的执行 +r($result['user9']) && p() && e(1); // 查看user9可访问的执行 +r($result['user10']) && p() && e(2); // 查看user10可访问的执行 +r($result['admin']) && p() && e('1,2,3'); // 查看admin可访问的执行 \ No newline at end of file diff --git a/module/user/test/zen/getfeaturebarmenus.php b/module/user/test/zen/getfeaturebarmenus.php new file mode 100644 index 0000000000..22563061c9 --- /dev/null +++ b/module/user/test/zen/getfeaturebarmenus.php @@ -0,0 +1,51 @@ +#!/usr/bin/env php +gen(3); +su('admin'); + +global $tester, $app, $config; +$userModel = $tester->loadModel('user'); + +$app->moduleName = 'user'; +$app->methodName = 'todo'; +$config->webRoot = '/'; +$config->requestType = 'PATH_INFO'; +$config->edition = 'ipd'; +$config->systemMode = 'PLM'; +$config->vision = 'rnd'; + +$zen = initReference('user'); +$func = $zen->getMethod('getFeatureBarMenus'); +$user = $userModel->fetchByID(1); + +$menus = $func->invokeArgs($zen->newInstance(), array($user)); +r(count($menus)) && p() && e('12'); // 检查返回菜单个数。 +r($menus['todo']) && p('url,active,text') && e('/user-view-1.html,1,日程'); // 检查日程菜单信息。 + +$config->vision = 'lite'; +$menus = $func->invokeArgs($zen->newInstance(), array($user)); +r(isset($menus['requirement'])) && p() && e('0'); // vision=lite, 检查需求菜单不存在。 + +$config->edition = 'biz'; +r(count($func->invokeArgs($zen->newInstance(), array($user)))) && p() && e('9'); // edition=biz, 检查返回菜单个数。 + +$config->systemMode = 'light'; +r(count($func->invokeArgs($zen->newInstance(), array($user)))) && p() && e('8'); // systemMode=light, 检查返回菜单个数。 \ No newline at end of file diff --git a/module/user/view/batchcreate.html.php b/module/user/view/batchcreate.html.php deleted file mode 100644 index 44d7dbb747..0000000000 --- a/module/user/view/batchcreate.html.php +++ /dev/null @@ -1,154 +0,0 @@ - - * @package story - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - - - -
            -
            -

            user->batchCreate;?>

            -
            user->typeList , 'inside', "onclick='changeType(this.value)'");?>
            -
            - createLink('custom', 'ajaxSaveCustomFields', 'module=user§ion=custom&key=batchCreateFields')?> - -
            -
            - user->availableBatchCreateFields},", ",{$field},") === false) continue; - if($field) $visibleFields[$field] = ''; - } - - foreach(explode(',', $config->user->create->requiredFields) as $field) - { - if($field) - { - $requiredFields[$field] = ''; - if(strpos(",{$config->user->availableBatchCreateFields},", ",{$field},") !== false) $visibleFields[$field] = ''; - } - } - $minWidth = (count($visibleFields) > 3) ? 'w-150px' : ''; - $showVisionList = count($visionList) > 1; - ?> -
            - -
            - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $lang->user->ditto)?> - user->roleList = $lang->user->roleList + array('ditto' => $lang->user->ditto)?> - $lang->user->ditto);?> - $lang->user->ditto);?> - user->batchCreate; $i++):?> - - - - - - - - - - config->vision);?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
            idAB;?>'>user->company;?>'> user->dept;?>user->account;?>user->realname;?>user->visions;?>'>user->role;?>user->group;?>'>user->email;?>'>user->gender;?>user->password;?>'> user->commiter;?>'> user->join;?>'> user->skype;?>'> user->qq;?>'>user->dingding;?>'> user->weixin;?>'> user->mobile;?>'> user->slack;?>'>user->whatsapp;?>'> user->phone;?>'> user->address;?>'> user->zipcode;?>
            -
            - 1 ? 'ditto' : '', "class='form-control chosen'");?> - company->create);?> -
            -
            ' style='overflow:visible'> 1 ? 'ditto' : $deptID, "class='form-control chosen'");?> - 1 ? 'ditto' : (isset($visionList[$this->config->vision]) ? $this->config->vision : key($visionList)), "class='form-control chosen' multiple");?> - user->roleList, $i > 1 ? 'ditto' : '', "class='form-control' onchange='changeGroup(this.value, $i)'");?> 1 ? 'ditto' : '', "class='form-control chosen' multiple");?>>>user->genderList, 'm');?> -
            - "; - if($i != 1) echo " 1 ? "checked" : '') . " /> {$lang->user->ditto}"; - ?> -
            -
            '>'> '> '> '>'> '> '> '>'> '> '>
            user->verifyPassword?> -
            - - user->placeholder->verify}'");?> -
            - save);?> - -
            -
            -
            -
            - -user->passwordStrengthList)?> -user->batchCreate)?> - diff --git a/module/user/view/batchedit.html.php b/module/user/view/batchedit.html.php deleted file mode 100644 index 47b1cd5aed..0000000000 --- a/module/user/view/batchedit.html.php +++ /dev/null @@ -1,133 +0,0 @@ - - * @package story - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -
            -
            -

            user->batchEdit;?>

            -
            - createLink('custom', 'ajaxSaveCustomFields', 'module=user§ion=custom&key=batchEditFields')?> - -
            -
            - user->availableBatchEditFields},", ",{$field},") === false) continue; - if($field)$visibleFields[$field] = ''; - } - - foreach(explode(',', $config->user->edit->requiredFields) as $field) - { - if($field) - { - $requiredFields[$field] = ''; - if(strpos(",{$config->user->availableBatchEditFields},", ",{$field},") !== false) $visibleFields[$field] = ''; - } - } - $minWidth = (count($visibleFields) > 7) ? 'w-120px' : ''; - $showVisionList = count($visionList) > 1; - ?> -
            -
            - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $lang->user->ditto) + $depts;?> - user->roleList = array('' => '', 'ditto' => $lang->user->ditto) + $lang->user->roleList;?> - - - dept)) ? 0 : (empty($user->dept) ? 'ditto' : $user->dept); - $role = ($first and empty($user->role)) ? 0 : (empty($user->role) ? 'ditto' : $user->role); - $type = empty($user->type) ? 'inside' : $user->type; - $first = false; - ?> - - - - - - - - - id][]", $this->config->vision);?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
            idAB;?>'> user->dept;?>user->account;?>user->realname;?>user->visions;?>user->role;?>user->type;?>'>user->commiter;?>'> user->email;?>'> user->join;?>'> user->skype;?>'> user->qq;?>'>user->dingding;?>'> user->weixin;?>'> user->mobile;?>'> user->slack;?>'>user->whatsapp;?>'> user->phone;?>'> user->address;?>'> user->zipcode;?>
            id;?>' style='overflow:visible'>id]", $depts, $dept, "class='form-control chosen'");?>id]", $user->account, "class='form-control' readonly");?>id]", $user->realname, "class='form-control'");?>id][]", $visionList, $user->visions, "class='form-control chosen' multiple");?>id]", $lang->user->roleList, $role, "class='form-control'");?>id]", $lang->user->typeList, $type, "class='form-control'");?>'>id]", $user->commiter, "class='form-control'");?>'> id]", $user->email, "class='form-control'");?>'> id]", $user->join, "class='form-control form-date'");?>'> id]", $user->skype, "class='form-control'");?>'> id]", $user->qq, "class='form-control'");?>'>id]", $user->dingding, "class='form-control'");?>'> id]", $user->weixin, "class='form-control'");?>'> id]", $user->mobile, "class='form-control'");?>'> id]", $user->slack, "class='form-control'");?>'>id]", $user->whatsapp, "class='form-control'");?>'> id]", $user->phone, "class='form-control'");?>'> id]", $user->address, "class='form-control'");?>'> id]", $user->zipcode, "class='form-control'");?>
            user->verifyPassword?> -
            - - - user->placeholder->verify}'");?> -
            - save);?> - -
            -
            -
            -
            - - diff --git a/module/user/view/bug.html.php b/module/user/view/bug.html.php deleted file mode 100644 index e212b38e7f..0000000000 --- a/module/user/view/bug.html.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @package dashboard - * @version $Id: bug.html.php 4771 2013-05-05 07:41:02Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - -
            - - -
            - - id}&type=$type&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}"; ?> - - - - - - - - - - - - - - - - - - - - - - - - - - -
            idAB);?> bug->title);?>bug->severity;?>>bug->abbr->severity);?>priAB);?> bug->type);?> openedByAB);?> bug->resolvedBy);?>bug->abbr->resolution);?>
            createLink('bug', 'view', "bugID=$bug->id", '', true), $bug->id, '', "class='iframe'");?>createLink('bug', 'view', "bugID=$bug->id", '', true), $bug->title, '', "class='iframe'");?>bug->severityList, $bug->severity, $bug->severity)?>' data-severity='severity;?>'>bug->severityList, $bug->severity, $bug->severity)?>bug->priList, $bug->pri, $bug->pri)?>'>bug->priList, $bug->pri, $bug->pri)?>bug->typeList, $bug->type, '');?>openedBy);?>resolvedBy);?>bug->resolutionList, $bug->resolution);?>
            - - - -
            -
            - diff --git a/module/user/view/create.html.php b/module/user/view/create.html.php deleted file mode 100644 index 1065a620f6..0000000000 --- a/module/user/view/create.html.php +++ /dev/null @@ -1,124 +0,0 @@ - - * @package user - * @version $Id: create.html.php 4728 2013-05-03 06:14:34Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - -user->placeholder->password1 = zget($lang->user->placeholder->passwordStrength, !empty($config->safe->mode) ? $config->safe->mode : 0, '');?> -user->placeholder);?> - - 1; -?> -
            -
            -
            -

            user->create;?>

            -
            -
            - - - - - - - - - - - - - - - - - - - - - - - - - - - - > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
            user->type;?>user->typeList , 'inside', "onclick='changeType(this.value)'");?>
            user->company;?> -
            - - company->create);?> -
            -
            user->dept;?>
            user->account;?>
            user->password;?> - - - - - - user->placeholder->password1;?>
            user->password2;?>
            user->visions;?>config->vision]) ? $this->config->vision : key($visionList), "class='form-control'");?>
            user->realname;?>
            user->join;?>
            user->role;?>user->roleList, '', "class='form-control' onchange='changeGroup(this.value)'");?>user->placeholder->role?>
            user->group;?>user->placeholder->group?>
            user->email;?>
            user->commiter;?>
            user->gender;?>user->genderList, 'm');?>
            user->verifyPassword;?> - user->placeholder->verify}'");?> -
            - config->vision);?> - - - createLink('company', 'browse'), $lang->goback, '', "class='btn btn-wide'")?> -
            -
            - -
            -
            -user->passwordStrengthList)?> - diff --git a/module/user/view/cropavatar.html.php b/module/user/view/cropavatar.html.php deleted file mode 100644 index 37ea3f6e90..0000000000 --- a/module/user/view/cropavatar.html.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @package user - * @version $Id: cropavatar.html.php 8669 2021-01-18 16:58:48Z sunguangming$ - * @link http://www.zdoo.com - */ -?> - - - -app->getWebRoot() . 'js/zui/imgcutter/min.js');?> -app->getWebRoot() . 'js/zui/imgcutter/min.css');?> -
            -
            -
            -

            user->cropAvatar;?>

            -
            -
            -
            - webPath);?> -
            -
            -
            user->cropAvatarTip;?>
            -
            - -
            -
            -
            -
            - - diff --git a/module/user/view/delete.html.php b/module/user/view/delete.html.php deleted file mode 100644 index ac6e024540..0000000000 --- a/module/user/view/delete.html.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @package user - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -
            -
            -

            user->noticeDelete, $user->realname);?>

            -
            -
            - - - - - - - - - -
            - user->verifyPassword;?> - -
            - user->placeholder->verify}'");?> -
            delete);?>
            -
            -
            - - diff --git a/module/user/view/deny.html.php b/module/user/view/deny.html.php deleted file mode 100644 index 20ef86eb9c..0000000000 --- a/module/user/view/deny.html.php +++ /dev/null @@ -1,64 +0,0 @@ - - * @package ZenTaoPMS - * @version $Id: deny.html.php 4129 2013-01-18 01:58:14Z wwccss $ - */ -include '../../common/view/header.lite.html.php'; -?> -
            - -
            - - - - diff --git a/module/user/view/dynamic.html.php b/module/user/view/dynamic.html.php deleted file mode 100644 index 63ad3c6f52..0000000000 --- a/module/user/view/dynamic.html.php +++ /dev/null @@ -1,100 +0,0 @@ - - * @package user - * @version $Id: dynamic.html.php 1477 2011-03-01 15:25:50Z wwccss $ - * @link https://www.zentao.net - */ -?> - - - - -
            -
            - user->featureBar['dynamic'] as $period => $label):?> - $label"; - $active = ''; - if($period == $type) - { - $active = 'btn-active-text'; - $label .= " {$recTotal}"; - } - echo html::a(inlink('dynamic', "userID={$user->id}&type=$period"), $label, '', "class='btn btn-link $active' id='{$period}'") - ?> - -
            - -
            '> - - - $actions):?> - -
            -
            - - action->dynamic->today;?> - - - -
            -
              - - $action):?> - -
            • major) echo "class='active'";?>> -
              - time?> - - actor);?> - actionLabel;?> - objectLabel;?> - objectID;?> - objectName) echo "" . (!empty($action->objectLink) ? html::a($action->objectLink, $action->objectName, '', "data-app=''") : $action->objectName) . '';?> - -
              -
            • - -
            -
            - - -
            - action->noDynamic;?> -
            - -
            -
            - -originalDate) + 24 * 3600); -$lastDate = substr($action->originalDate, 0, 10); -$hasPre = $this->action->hasPreOrNext($firstDate, 'pre'); -$hasNext = $this->action->hasPreOrNext($lastDate, 'next'); -$preLink = $hasPre ? inlink('dynamic', "userID={$user->id}&type=$type&recTotal={$recTotal}&date=" . strtotime($firstDate) . '&direction=pre') : 'javascript:;'; -$nextLink = $hasNext ? inlink('dynamic', "userID={$user->id}&type=$type&recTotal={$recTotal}&date=" . strtotime($lastDate) . '&direction=next') : 'javascript:;'; -?> - -
            - -
            - - - - diff --git a/module/user/view/edit.html.php b/module/user/view/edit.html.php deleted file mode 100644 index ea12f7239b..0000000000 --- a/module/user/view/edit.html.php +++ /dev/null @@ -1,131 +0,0 @@ - - * @package user - * @version $Id: edit.html.php 4728 2013-05-03 06:14:34Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - -type);?> -
            -
            -
            -

            - id;?> - id", $user->realname)) echo $user->realname;?> (account;?>) - arrow . $lang->user->edit;?> -

            -
            -
            - - - - - - - - - - - - - - - - - - - - - - - - - -
            user->basicInfo;?>
            user->realname;?>realname, "class='form-control'");?>user->role;?>user->roleList, $user->role, "class='form-control'");?>
            user->dept;?>dept, "class='form-control chosen'");?>user->join;?>join), "class='form-control form-date'");?>
            group->priv;?>user->company;?> -
            - company, "class='form-control chosen'");?> - company->create);?> -
            -
            user->type;?>user->typeList , $user->type, "onclick='changeType(this.value)'");?>user->gender;?>user->genderList, $user->gender);?>
            - - - - - - - - - - - - - - - - - - - - -
            user->accountInfo;?>
            user->account;?>account, "class='form-control' readonly");?>user->email;?> - email, "class='form-control'");?> - -
            user->password;?> - - - user->placeholder->passwordStrength, $config->safe->mode, '') . "'");?> - - - user->password2;?>
            user->commiter;?>commiter, "class='form-control'");?>user->visions;?>visions, "class='form-control chosen' multiple");?>
            - - - user->contactField)):?> - - user->contactField) as $field):?> - ';?> - - - - ';?> - - - - - - - - -
            user->contactInfo;?>
            >user->$field;?>>$field, "class='form-control'");?>
            user->address;?>address, "class='form-control'");?>user->zipcode;?>zipcode, "class='form-control'");?>
            - - - - - - - - - - - -
            user->verify;?>
            user->verifyPassword;?> -
            - user->placeholder->verify}'");?> -
            - - - -
            -
            - -
            -
            -user->passwordStrengthList)?> - diff --git a/module/user/view/execution.html.php b/module/user/view/execution.html.php deleted file mode 100644 index e1f0bc0bbb..0000000000 --- a/module/user/view/execution.html.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @package dashboard - * @version $Id: project.html.php 4129 2013-01-18 01:58:14Z wwccss $ - * @link https://www.zentao.net - */ -?> - - - -
            -
            - - id}&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}"; ?> - - - - - - - - - - - - - - - createLink('execution', 'view', "executionID=$execution->id");?> - - - - delay)):?> - - - - - - - - - - - - -
            idAB);?>user->name);?> statusAB);?> team->role;?> execution->begin);?> execution->end);?> team->join;?> team->hours;?>
            id, '', "data-app='execution'");?> - config->edition, array('max', 'ipd'))):?> - user->executionTypeList, $execution->type);?> - - name, '', "data-app='execution'");?> - execution->delayed;?>processStatus('execution', $execution);?>role;?>begin;?>end;?>join;?>hours;?>
            - - - -
            -
            - diff --git a/module/user/view/featurebar.html.php b/module/user/view/featurebar.html.php deleted file mode 100755 index aefef5d10c..0000000000 --- a/module/user/view/featurebar.html.php +++ /dev/null @@ -1,69 +0,0 @@ -getExtViewFile(__FILE__)){include $extView; return helper::cd();}?> - - diff --git a/module/user/view/forgetpassword.html.php b/module/user/view/forgetpassword.html.php deleted file mode 100644 index e1391ee128..0000000000 --- a/module/user/view/forgetpassword.html.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @package ZenTaoPMS - * @version $Id: forgetpassword.html.php 5084 2022-06-20 15:00:38Z $ - */ -include '../../common/view/header.lite.html.php'; -?> -
            -
            -
            -

            admin->resetPWDByMail;?>

            -
            -
            - - -
            - - user->placeholder->loginAccount}'");?> -
            -
            - - user->placeholder->email}'");?> -
            - user->resetTitle, '', "class='resetBox'");?> - - - - -
            - user->submit); - echo html::a(inlink('login'), $lang->goback, '', 'class="btn btn-wide"'); - ?> -
            -
            -
            -
            -
            - - diff --git a/module/user/view/login.html.php b/module/user/view/login.html.php deleted file mode 100644 index b86e67392c..0000000000 --- a/module/user/view/login.html.php +++ /dev/null @@ -1,151 +0,0 @@ - - * @package ZenTaoPMS - * @version $Id: login.html.php 5084 2013-07-10 01:31:38Z wyd621@gmail.com $ - */ -include '../../common/view/header.lite.html.php'; -if(empty($config->notMd5Pwd))js::import($jsRoot . 'md5.js'); -?> -user->error->loginTimeoutTip);?> -app->getBasePath());?> -
            -
            -
            -
            -

            welcome, $app->company->name);?>

            - -
            -
            -
            - -
            -
            -
            - - - -

            user->loginExpired;?>

            - - - - - - - - - - config->safe->loginCaptcha)):?> - - - - - - - - - - - - - - -
            user->account;?>
            user->password;?>
            user->captcha;?> -
            - - -
            -
            user->keepLogin, $keepLogin);?>
            - login, '', 'btn btn-primary'); - if($app->company->guest) echo html::linkButton($lang->user->asGuest, $this->createLink($config->default->module)); - echo html::hidden('referer', $referer); - $resetLink = (isset($this->config->resetPWDByMail) and $this->config->resetPWDByMail) ? inlink('forgetPassword') : inlink('reset'); - echo html::a($resetLink, $lang->user->resetPassword); - ?> -
            -
            -
            -
            - 0 or count($plugins['expiring']) > 0):?> -
            -
            - - - misc->expiredPluginTips, $expiredPlugins);?> - misc->expiringPluginTips, $expiringPlugins);?> - - - - -
             misc->expiredCountTips, $pluginTips, $pluginTotal);?>
            -
            -
            - - config->global->showDemoUsers)):?> - dao->select('account,password,realname')->from(TABLE_USER)->where('account')->in($demoUsers)->andWhere('deleted')->eq(0)->andWhere('password')->eq($md5Password)->fetchAll('account'); - ?> -
            - user->loginWithDemoUser;?> - $demoUser) - { - if($demoUser->password != $md5Password) continue; - echo html::a($link . "account={$demoAccount}&password=" . md5($md5Password . $this->session->rand), $demoUser->realname); - } - ?> -
            - -
            -
            -
            -
            - - - - checkVersion):?> - - -
            -
            -
            -
            -
            - $site) - { - $path = $site['path']; - if(strpos($path, 'xampp') !== false) $isXampp = true; - - $paths[] = $site['path']; - $databases[] = $site['database']; - } - - $process4Safe = $isXampp ? $lang->user->process4DB : $lang->user->process4DIR; - $process4Safe = sprintf($process4Safe, join(' ', $isXampp ? $databases : $paths)); - js::set('process4Safe', $process4Safe); -} -?> - diff --git a/module/user/view/profile.html.php b/module/user/view/profile.html.php deleted file mode 100644 index 0536e6cfdf..0000000000 --- a/module/user/view/profile.html.php +++ /dev/null @@ -1,132 +0,0 @@ - - * @package user - * @version $Id: profile.html.php 4976 2013-07-02 08:15:31Z wyd621@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - - - - -user->roleList, $user->role, '')):?> - - -
            -
            -
            -
            - avatar ? html::image($user->avatar) : strtoupper($user->account[0]);?> -
            -
            realname;?>
            - user->roleList, $user->role, '')):?> -
            user->roleList, $user->role, '');?>
            - -
            -
            - - - - - - - - - - - - - - - - - - - - - - - - - -
            user->realname;?>realname;?>user->gender;?>user->genderList, $user->gender);?>
            user->account;?>account;?>user->email;?>email);?>
            user->dept;?> - $dept) - { - if($dept->name) echo $dept->name; - if(isset($deptPath[$key + 1])) echo $lang->arrow; - } - } - ?> - user->role;?>user->roleList, $user->role, '');?>
            user->abbr->join;?>join);?>user->priv;?>name . ' ';?>
            -
            - - - - - - - - - - - - - - - - - - - -
            user->mobile;?>mobile;?>user->weixin;?>weixin;?>
            user->phone;?>phone;?>user->qq;?>qq;?>
            user->zipcode;?>zipcode;?>user->abbr->address;?>address;?>
            - -
            - - - - - - - - - - - - - - - - - - - - - - - - - -
            user->commiter;?>commiter;?>user->skype;?>skype) echo html::a("callto://$user->skype", $user->skype);?>
            user->visits;?>visits;?>user->whatsapp;?>whatsapp;?>
            user->last;?>last;?>user->slack;?>slack;?>
            user->ip;?>ip;?>user->dingding;?>dingding;?>
            - -
            -
            -
            - diff --git a/module/user/view/reset.html.php b/module/user/view/reset.html.php deleted file mode 100644 index 089b094685..0000000000 --- a/module/user/view/reset.html.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @package user - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - - -
            -
            -
            - user->resetPassword?> -
            -
            -
            - user->noticeResetFile, $resetFileName);?> -
            -
            - lang->refresh, '', "class='btn btn-primary btn-wide'")?> - -
            -
            -
            -
            - -
            -
            -
            - user->resetPassword?> -
            -
            - - - - - - - - - - - - - - - - - - -
            user->account?>
            user->password?>
            user->password2?>
            -
            -
            -
            - - diff --git a/module/user/view/resetpassword.html.php b/module/user/view/resetpassword.html.php deleted file mode 100644 index a6580fa57a..0000000000 --- a/module/user/view/resetpassword.html.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @package ZenTaoPMS - * @version $Id: resetpassword.html.php 5084 2022-06-21 09:47:38Z $ - */ -include '../../common/view/header.lite.html.php'; -?> - - - - -
            -
            user->linkExpired . sprintf($lang->user->jumping, inlink('login'));?>
            -
            - -
            -
            -
            -

            user->resetPWD;?>

            -
            -
            - - -
            - - - user->placeholder->loginPassword, $config->safe->mode, '') . "' onkeyup='checkPassword(this.value)'");?> - - -
            -
            - - user->placeholder->loginPassword}'");?> -
            - - - - -
            - account); - echo html::hidden('passwordStrength', ''); - echo html::hidden('passwordLength', 0); - echo html::submitButton($lang->user->submit); - echo html::a(inlink('login'), $lang->goback, '', 'class="btn btn-wide"'); - ?> -
            -
            - -
            -
            -
            - - -user->passwordStrengthList)?> - diff --git a/module/user/view/story.html.php b/module/user/view/story.html.php deleted file mode 100644 index 90af68dd34..0000000000 --- a/module/user/view/story.html.php +++ /dev/null @@ -1,89 +0,0 @@ - - * @package dashboard - * @version $Id: story.html.php 4771 2013-05-05 07:41:02Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - - -
            - - -
            - - id}&storyType=$storyType&type=$type&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}"; ?> - - - - - - - config->vision == 'lite'):?> - - - - - config->vision != 'lite'):?> - - - - - config->vision != 'lite'):?> - - - - - - $story):?> - createLink('story', 'view', "id=$story->id", '', true);?> - - - - - - - config->vision != 'lite'):?> - - - - - config->vision != 'lite'):?> - - - - - -
            idAB);?>story->title);?>priAB);?>statusAB);?>story->project);?>story->product);?>story->plan);?>openedByAB);?>story->estimateAB);?>story->stageAB);?>
            id), '', "class='iframe'");?>title, '', "class='iframe'");?>story->priList, $story->pri, $story->pri);?>processStatus('story', $story);?>productTitle;?>planTitle;?>openedBy);?>estimate . $config->hourUnit;?>story->stageList[$story->stage];?>
            - - - -
            -
            - diff --git a/module/user/view/task.html.php b/module/user/view/task.html.php deleted file mode 100644 index 5689a93234..0000000000 --- a/module/user/view/task.html.php +++ /dev/null @@ -1,81 +0,0 @@ - - * @package dashboard - * @version $Id: task.html.php 4771 2013-05-05 07:41:02Z chencongzhi520@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - -
            - - -
            - - id}&type=$type&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}"; ?> - - - - - - - - - - - - - - - - - - - - - executionMultiple ? 'execution' : 'project';?> - - - - - - - - -
            idAB);?>task->name);?>priAB);?>statusAB);?>task->execution);?>task->deadlineAB);?>task->estimateAB);?>task->consumedAB);?>task->leftAB);?>
            createLink('task', 'view', "taskID=$task->id", '', true), sprintf('%03d', $task->id), '', "class='iframe'");?> - team)) echo '' . $this->lang->task->multipleAB . ' ';?> - parent > 0) echo '' . $this->lang->task->childrenAB . ' ';?> - createLink('task', 'view', "taskID=$task->id", '', true, $task->project), $task->name, null, "class='iframe' data-width='80%' style='color: $task->color' title='$task->name'");?> - task->priList, $task->pri, $task->pri);?>processStatus('task', $task);?>createLink('execution', 'browse', "executionID=$task->executionID"), $task->executionName, '', "data-app='$tab'");?>deadline, 0, 4) > 0) echo '' . $task->deadline . '';?>estimate . $lang->execution->workHourUnit;?>consumed . $lang->execution->workHourUnit;?>left . $lang->execution->workHourUnit;?>
            - - - -
            -
            - diff --git a/module/user/view/testcase.html.php b/module/user/view/testcase.html.php deleted file mode 100755 index e21dd80889..0000000000 --- a/module/user/view/testcase.html.php +++ /dev/null @@ -1,85 +0,0 @@ - - * @package dashboard - * @version $Id: test.html.php 1191 2010-11-13 07:30:35Z jajacn@126.com $ - * @link https://www.zentao.net - */ -?> - - -
            - - -
            - - id}&type=$type&orderBy=%s&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID"; - $this->app->loadLang('testtask'); - ?> - - - - - - - - - - - - - - - - case : $case->id?> - - - - - - - - - - - - - -
            idAB);?> testcase->title);?> priAB);?> testcase->type);?>statusAB);?> testcase->openedByAB);?> testtask->lastRunAccount);?> testtask->lastRunTime);?>testtask->lastRunResult);?>
            createLink('testcase', 'view', "testcaseID=$caseID&version=$case->version"), sprintf('%03d', $caseID), '', "data-app='qa'");?>createLink('testcase', 'view', "testcaseID=$caseID&version=$case->version"), $case->title, '', "data-app='qa'");?>testcase->priList, $case->pri, $case->pri)?>'>testcase->priList, $case->pri, $case->pri)?>testcase->typeList[$case->type];?> - needconfirm) - { - print("{$this->lang->story->changed}"); - } - elseif(isset($case->fromCaseVersion) and $case->fromCaseVersion > $case->version and !$case->needconfirm) - { - print("{$this->lang->testcase->changed}"); - } - else - { - print("" . $this->processStatus('testcase', $case) . ""); - } - ?> - openedBy);?>lastRunner);?>lastRunDate) ? '' : substr($case->lastRunDate, 5, 11);?>lastRunResult) echo $lang->testcase->resultList[$case->lastRunResult];?>
            - - - -
            -
            - diff --git a/module/user/view/testtask.html.php b/module/user/view/testtask.html.php deleted file mode 100755 index ccb672657c..0000000000 --- a/module/user/view/testtask.html.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @package dashboard - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -
            - - -
            - - id}&orderBy=%s&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID"; ?> - - - - - - - - - - - - - - - status == 'wait') $waitCount ++;?> - status == 'doing') $testingCount ++;?> - status == 'blocked') $blockedCount ++;?> - status == 'done') $doneCount ++;?> - - - - - - - - - - - -
            idAB);?> testtask->name);?> testtask->execution);?> testtask->build);?> testtask->begin);?> testtask->end);?>statusAB);?>
            createLink('testtask', 'view', "taskID=$task->id", '', true), sprintf('%03d', $task->id), '', "class='iframe'");?>createLink('testtask', 'view', "taskID=$task->id", '', true), $task->name, '', "class='iframe'");?>executionName?>build == 'trunk' ? print($lang->trunk) : print(html::a($this->createLink('build', 'view', "buildID=$task->build"), $task->buildName));?>begin?>end?>processStatus('testtask', $task);?>
            - - - -
            -
            - diff --git a/module/user/view/todo.html.php b/module/user/view/todo.html.php deleted file mode 100644 index 72bb258ac0..0000000000 --- a/module/user/view/todo.html.php +++ /dev/null @@ -1,84 +0,0 @@ - - * @package dashboard - * @version $Id: todo.html.php 4744 2013-05-04 02:41:05Z wyd621@gmail.com $ - * @link https://www.zentao.net - */ -?> - - - -id);?> - -
            - - -
            ' data-ride='table' id='todoform' class='main-table table-todo'> - - id}&type=$type&status=$status&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}"; ?> - - - - - - - - - - - - - - - - - status == 'wait') $waitCount ++;?> - status == 'doing') $doingCount ++;?> - - - - - - - - - - - -
            idAB);?> todo->name);?> priAB);?> todo->date);?>todo->status);?> todo->type);?> todo->beginAB);?> todo->endAB);?>
            id;?> - private and $this->app->user->account != $todo->account) ? $todo->name : html::a($this->createLink('todo', 'view', "id=$todo->id&from=company", '', true), $todo->name, '', "class='iframe'");?> - todo->priList, $todo->pri, $todo->pri);?>'>todo->priList, $todo->pri, $todo->pri);?>date == '2030-01-01' ? $lang->todo->periods['future'] : $todo->date;?>todo->statusList[$todo->status];?>todo->typeList[$todo->type];?>begin;?>end;?>
            - - - - - -
            -
            - - diff --git a/module/user/zen.php b/module/user/zen.php index 362c4484f6..9e79e79daa 100644 --- a/module/user/zen.php +++ b/module/user/zen.php @@ -93,7 +93,7 @@ class userZen extends user $params = "userID={$user->id}"; $featureBarMenus = array(); - if(common::hasPriv($moduleName, 'todo')) $featureBarMenus['todo'] = array('active' => false, 'url' => $this->createLink($moduleName, 'todo', "$params&type=all"), 'text' => $this->lang->user->schedule); + if(common::hasPriv($moduleName, 'todo')) $featureBarMenus['todo'] = array('active' => false, 'url' => $this->createLink($moduleName, 'view', $params), 'text' => $this->lang->user->schedule); if(common::hasPriv($moduleName, 'task')) $featureBarMenus['task'] = array('active' => false, 'url' => $this->createLink($moduleName, 'task', $params), 'text' => $this->lang->user->task); if($this->config->URAndSR && $this->config->vision == 'rnd') $featureBarMenus['requirement'] = array('active' => false, 'url' => $this->createLink($moduleName, 'story', "$params&storyType=requirement"), 'text' => $this->lang->URCommon); diff --git a/module/webhook/view/bind.html.php b/module/webhook/view/bind.html.php deleted file mode 100644 index 1591b3b5bc..0000000000 --- a/module/webhook/view/bind.html.php +++ /dev/null @@ -1,88 +0,0 @@ - -
            -
            -
            -

            webhook->bind?>

            -
            -
            - - - - - - - - - - - - - - - account])) - { - $userid = $bindedUsers[$user->account]; - $bindStatus = 1; - } - elseif(isset($oauthUsers[$user->realname])) - { - $userid = $oauthUsers[$user->realname]; - } - ?> - - - - - - - -
            webhook->zentaoUser?> - type == 'dinguser') echo $lang->webhook->dingUserid; - if($webhook->type == 'wechatuser') echo $lang->webhook->wechatUserid; - if($webhook->type == 'feishuuser') echo $lang->webhook->feishuUserid; - ?> - actions;?> - type == 'dinguser') echo $lang->webhook->dingBindStatus; - if($webhook->type == 'wechatuser') echo $lang->webhook->wechatBindStatus; - if($webhook->type == 'feishuuser') echo $lang->webhook->feishuBindStatus; - ?> -
            account;?> realname;?> - ' . zget($useridPairs, $userid) . '';?> - account}]", $userid, 'class="form-control hidden"');?> - account . ']">';?>webhook->dingBindStatusList, $bindStatus, '');?>
            - - - -
            -
            webhook->bind;?>
            -
            - - - -
            -
            -
            - - diff --git a/module/webhook/view/browse.html.php b/module/webhook/view/browse.html.php deleted file mode 100644 index d0f93b1b24..0000000000 --- a/module/webhook/view/browse.html.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @package webhook - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -webhook->confirmDelete);?> -
            -
            - - - - recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?> - - - - - - - - - $webhook):?> - - - - - - - - - -
            webhook->id);?>webhook->type);?>webhook->name);?>webhook->url);?>actions;?>
            webhook->typeList, $webhook->type);?>name;?>url;?> - type == 'dinguser' or $webhook->type == 'feishuuser') common::printIcon('webhook', 'chooseDept', "webhookID=$id", '', 'list', 'link'); - if($webhook->type == 'wechatuser') common::printIcon('webhook', 'bind', "webhookID=$id", '', 'list', 'link'); - common::printIcon('webhook', 'log', "webhookID=$id", '', 'list', 'file-text'); - common::printIcon('webhook', 'edit', "webhookID=$id", '', 'list'); - if(common::hasPriv('webhook', 'delete')) - { - $deleteURL = $this->createLink('webhook', 'delete', "webhookID=$id&confirm=yes"); - echo html::a("javascript:ajaxDelete(\"$deleteURL\", \"webhookList\", confirmDelete)", '', '', "title='{$lang->webhook->delete}' class='btn'"); - } - ?> -
            - - - -
            -
            - diff --git a/module/webhook/view/choosedept.html.php b/module/webhook/view/choosedept.html.php deleted file mode 100644 index b75815b7e7..0000000000 --- a/module/webhook/view/choosedept.html.php +++ /dev/null @@ -1,230 +0,0 @@ - - * @package webhook - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -
            -
            -
            -

            webhook->chooseDept?>

            -
            - -
            -
            webhook->friendlyTips;?>
            -
            -

            webhook->loadPrompt;?>

            - -
              -
              - save, '', 'btn btn-primary save');?> - createLink('webhook', 'browse'), $lang->goback, '', "class='btn'");?> -
              -
              -
              - - - -webhook->error->requestError);?> -createLink('webhook', 'ajaxGetFeishuDeptList', array('webhookID' => $webhookID)));?> - - diff --git a/module/webhook/view/create.html.php b/module/webhook/view/create.html.php deleted file mode 100644 index ee512ee1f0..0000000000 --- a/module/webhook/view/create.html.php +++ /dev/null @@ -1,122 +0,0 @@ - - * @package webhook - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -webhook->note->typeList);?> -
              -
              -
              -

              webhook->create;?>

              -
              -
              - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
              webhook->type;?>webhook->typeList, '', "class='form-control chosen'");?>
              webhook->name;?>
              webhook->url;?>webhook->note->typeList['default'];?>
              webhook->secret;?>
              webhook->dingAgentId;?>webhook->note->dingHelp;?>
              webhook->dingAppKey;?>
              webhook->dingAppSecret;?>
              webhook->wechatCorpId;?>webhook->note->wechatHelp;?>
              webhook->wechatCorpSecret;?>
              webhook->wechatAgentId;?>
              webhook->feishuAppId;?>
              webhook->feishuAppSecret;?>
              webhook->domain;?>
              webhook->sendType;?>webhook->sendTypeList, '', "class='form-control'");?>webhook->note->async;?>
              webhook->product;?>webhook->note->product;?>
              webhook->execution;?>webhook->note->execution;?>
              -
              - - -
              -
              webhook->paramsList, 'text');?>
              webhook->desc;?>
              - - -
              -
              -
              -
              - diff --git a/module/webhook/view/edit.html.php b/module/webhook/view/edit.html.php deleted file mode 100644 index ab0f6aa7f7..0000000000 --- a/module/webhook/view/edit.html.php +++ /dev/null @@ -1,137 +0,0 @@ - - * @package webhook - * @version $Id$ - * @link https://www.zentao.net - */ -?> - - -
              -
              -
              -

              webhook->edit;?>

              -
              -
              - - - - - - - - - - - - '> - - - - - type == 'dinggroup' or $webhook->type == 'feishugroup'):?> - - - - - - type == 'dinguser'):?> - secret);?> - - - - - - - - - - - - - - - type == 'wechatuser'):?> - secret);?> - - - - - - - - - - - - - - - - - type == 'feishuuser'):?> - secret);?> - - - - - - - - - - - - - - - - type) === false):?> - - - - - - - - - - - - - - - - - type,") === false):?> - - - - - - - - - - - - - -
              webhook->type;?>webhook->typeList, $webhook->type);?>type);?>
              webhook->name;?>name, "class='form-control'");?>
              webhook->url;?>url, "class='form-control'");?>webhook->note->typeList, $webhook->type, '');?>
              webhook->secret;?>secret, "class='form-control'");?>
              webhook->dingAgentId;?>agentId, "class='form-control'");?>webhook->note->dingHelp;?>
              webhook->dingAppKey;?>appKey, "class='form-control'");?>
              webhook->dingAppSecret;?>appSecret, "class='form-control'");?>
              webhook->wechatCorpId;?>appKey, "class='form-control'")?>webhook->note->wechatHelp;?>
              webhook->wechatCorpSecret;?>appSecret, "class='form-control'")?>
              webhook->wechatAgentId;?>agentId, "class='form-control'")?>
              webhook->feishuAppId;?>appId, "class='form-control'")?>
              webhook->feishuAppSecret;?>appSecret, "class='form-control'")?>
              webhook->domain;?>domain, "class='form-control'");?>
              webhook->sendType;?>webhook->sendTypeList, $webhook->sendType, "class='form-control'");?>webhook->note->async;?>
              webhook->product;?>products, "class='form-control chosen' multiple");?>webhook->note->product;?>
              webhook->execution;?>executions, "class='form-control chosen' multiple");?>webhook->note->execution;?>
              -
              - - -
              -
              webhook->paramsList, $webhook->params);?>
              webhook->desc;?>desc, "rows='3' class='form-control'");?>
              - - -
              -
              -
              -
              - diff --git a/module/webhook/view/log.html.php b/module/webhook/view/log.html.php deleted file mode 100644 index 93d4393435..0000000000 --- a/module/webhook/view/log.html.php +++ /dev/null @@ -1,66 +0,0 @@ - - * @package log - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -
              -
              -

              - webhook->common);?> - name;?> - webhook->log;?> -

              -
              -
              -
              - " . $lang->webhook->setting, '', "class='btn btn-primary iframe'", '', true);?> -
              -
              -
              -
              - - - - id}&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?> - - - - - - - - - - $log):?> - - - - - - actionURL = $this->createLink($log->module, 'view', "id=$log->moduleID", '' , true)?> - action):?> - - - - - - - - - -
              webhook->id);?>webhook->date);?>webhook->url);?>webhook->action);?>webhook->contentType);?>webhook->result);?>
              date;?>url;?>actionURL, $log->action, '', $iframe);?>webhook->approval;?>contentType;?>result;?>
              - - - -
              - diff --git a/module/zahost/view/browse.html.php b/module/zahost/view/browse.html.php deleted file mode 100644 index a149db1b3b..0000000000 --- a/module/zahost/view/browse.html.php +++ /dev/null @@ -1,91 +0,0 @@ - - * @package host - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -zahost->confirmDelete)?> - - - - -
              ' data-module='zahost'>
              -
              -
              - -
              -

              - zahost->empty;?> - ' . $lang->zahost->create, '', 'class="btn btn-info"');?> -

              -
              - - - - - recTotal}&recPerPage={$pager->recPerPage}";?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
              idAB);?> zahost->name);?> zahost->type);?> zahost->extranet);?> zahost->cpuCores);?> zahost->memory);?> zahost->diskSize);?> zahost->vsoft);?> zahost->status);?> zahost->registerDate);?>actions;?>
              hostID);?>inlink('view', "id=$host->hostID"), $host->name, '', "");?>zahost->zaHostTypeList, $host->hostType);?>extranet;?>cpuCores;?>memory . $lang->zahost->unitList['GB'];?>diskSize . $lang->zahost->unitList['GB'];?>zahost->softwareList, $host->vsoft);?>host->statusList, $host->status);?>heartbeat) ? '' : $host->heartbeat;?> - status == 'wait') ? 'disabled' : '';?> - status == 'wait') ? $lang->zahost->uninitNotice: $lang->zahost->image->browseImage;?> - hostID}", $host, 'list', 'mirror', '', "iframe $disabled", true, "data-width='80%'", $title);?> - hostID]) ? 'disabled' : '';?> - hostID]) ? $lang->zahost->undeletedNotice : $lang->zahost->delete;?> - hostID}", $host, 'list');?> - createLink('zahost', 'delete', "hostID={$host->id}"), '', 'hiddenwin', "title='$title' class='btn $disabled'");;?> -
              - - -
              -
              -getModuleRoot() . 'common/view/footer.html.php';?> diff --git a/module/zahost/view/browseimage.html.php b/module/zahost/view/browseimage.html.php deleted file mode 100755 index 70a16ff5f8..0000000000 --- a/module/zahost/view/browseimage.html.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @package zahost - * @version $Id$ - * @link https://www.zentao.net - */ -?> -getModuleRoot() . 'common/view/header.html.php';?> - - -
              ' data-module='vmTemplate'>
              -
              - recTotal}&recPerPage={$pager->recPerPage}";?> - -
              -

              - zahost->image->imageEmpty;?> -

              -
              - - - - - - - - - - - - - - - - status == 'completed' ? zget($image, 'path', '') : '';?> - - - - - - - - - -
              zahost->image->name);?>zahost->image->os);?>zahost->status;?>zahost->image->path;?>zahost->image->progress;?>actions;?>
              name;?>osName;?>'>zahost->image->statusList, $image->status, '');?>'> - createLink('zahost', 'downloadImage', "hostID={$hostID}&imageID={$image->id}"), '', 'hiddenwin', zget($image, 'downloadMisc', ''));?> - createLink('zahost', 'cancelDownload', "id={$image->id}"), '', 'hiddenwin', zget($image, 'cancelMisc', ''));?> -
              - - -
              -getModuleRoot() . 'common/view/footer.html.php';?> diff --git a/module/zahost/view/create.html.php b/module/zahost/view/create.html.php deleted file mode 100644 index 62111d2ca1..0000000000 --- a/module/zahost/view/create.html.php +++ /dev/null @@ -1,82 +0,0 @@ - - * @package zahost - * @version $Id$ - * @link https://www.zentao.net - */ -?> -getModuleRoot() . 'common/view/header.html.php';?> -getModuleRoot() . 'common/view/kindeditor.html.php';?> -
              -
              -
              -
              -

              zahost->create;?>

              - -
              -
              - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
              zahost->vsoft;?>zahost->softwareList, '', "class='form-control chosen'");?>
              zahost->zaHostType;?>zahost->zaHostTypeList, 'virtual', "class='form-control chosen'");?>
              zahost->name;?>
              zahost->extranet;?>
              zahost->cpuCores;?>zahost->cpuCoreList, '2', "class='form-control chosen'");?>
              zahost->memory;?> -
              - - GB -
              -
              zahost->diskSize;?> -
              - - - GB - -
              -
              zahost->desc ?>
              - - - -
              -
              -
              -
              -
              -getModuleRoot() . 'common/view/footer.html.php';?> diff --git a/module/zahost/view/edit.html.php b/module/zahost/view/edit.html.php deleted file mode 100644 index 4860a5dd5f..0000000000 --- a/module/zahost/view/edit.html.php +++ /dev/null @@ -1,81 +0,0 @@ - - * @package zahost - * @version $Id$ - * @link https://www.zentao.net - */ -?> -getModuleRoot() . 'common/view/header.html.php';?> -getModuleRoot() . 'common/view/kindeditor.html.php';?> -
              -
              -
              -
              -

              zahost->editAction;?>

              - -
              -
              - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
              zahost->vsoft;?>zahost->softwareList, $host->vsoft, "class='form-control chosen'");?>
              zahost->zaHostType;?>zahost->zaHostTypeList, $host->hostType, "class='form-control chosen'");?>
              zahost->name;?>name, "class='form-control'");?>
              zahost->IP;?>extranet, "class='form-control' readonly");?>
              zahost->cpuCores;?>zahost->cpuCoreList, $host->cpuCores, "class='form-control chosen'");?>
              zahost->memory;?> -
              - memory, "class='form-control'");?> - GB -
              -
              zahost->diskSize;?> -
              - diskSize, "class='form-control'");?> - - GB - -
              -
              zahost->desc ?>desc, "class='form-control'")?>
              - - -
              -
              -
              -
              -
              -getModuleRoot() . 'common/view/footer.html.php';?> diff --git a/module/zahost/view/view.html.php b/module/zahost/view/view.html.php deleted file mode 100644 index 5c8de2618b..0000000000 --- a/module/zahost/view/view.html.php +++ /dev/null @@ -1,165 +0,0 @@ - - * @package zahost - * @version $Id: view.html.php $ - * @link https://www.zentao.net - */ -?> -getModuleRoot() . 'common/view/header.html.php';?> -getModuleRoot() . 'common/view/kindeditor.html.php'; ?> -id);?> -zahost);?> -session->zahostList ? $this->session->zahostList : $this->createLink('zahost', 'browse', "");?> -hostID}&orderBy=%s";?> - -
              -
              -
              -
              -
              zahost->baseInfo;?>
              -
              -
              -
              -
              -
              zahost->extranet;?>:
              -
              extranet;?>
              -
              -
              -
              -
              -
              zahost->cpuCores;?>:
              -
              cpuCores . ' ' . $lang->zahost->cpuUnit;?>
              -
              -
              -
              -
              -
              zahost->zaHostType;?>:
              -
              zahost->zaHostTypeList[$zahost->hostType];?>
              -
              -
              -
              -
              -
              -
              -
              zahost->status;?>:
              -
              zahost->statusList, $zahost->status);?>
              -
              -
              -
              -
              -
              zahost->memory;?>:
              -
              memory . ' ' . $lang->zahost->unitList['GB'];;?>
              -
              -
              -
              -
              -
              zahost->vsoft;?>:
              -
              zahost->softwareList, $zahost->vsoft);?>
              -
              -
              -
              -
              -
              -
              -
              zahost->registerDate;?>:
              -
              heartbeat) ? '' : $zahost->heartbeat;?>
              -
              -
              -
              -
              -
              zahost->diskSize;?>:
              -
              diskSize . ' ' . $lang->zahost->unitList['GB'];?>
              -
              -
              -
              -
              -
              -
              -
              -
              -
              -
              -
              zahost->desc;?>
              -
              desc) ? htmlspecialchars_decode($zahost->desc) : $lang->noData;?>
              -
              -
              -
              -
              -
              - zahost->init->statusTitle;?> - -
              -
              -
              -
              - -
              -
              - createLink('zahost', 'browseImage', "hostID=$zahost->id", '', true), $lang->zahost->image->downloadImage, '', "class='iframe'");?> - createLink('zanode', 'create', "hostID=$zahost->id"), $lang->zahost->createZanode);?> -
              zahost->init->initSuccessNotice, $imageLink, $createNode);?>
              -
              - zahost->init->initFailNotice;?> - -
              - "; ?> -
              -
              -
              -
              -
              -
              -
              - -
              -
              -
              zahost->browseNode;?>
              - -
              - createLink('zanode', 'nodeList', "hostID=$zahost->id", '', true) . "' frameborder='no' allowfullscreen='true' mozallowfullscreen='true' webkitallowfullscreen='true' allowtransparency='true' scrolling='auto' onload='setIframeHeight(this)' style='min-height:300px;'>";?> -
              - -
              noData;?>
              - -
              - createLink('action', 'comment', "objectType=zahost&objectID=$zahost->hostID"); - ?> -
              - - printExtendFields($zahost, 'div', "position=left&inForm=0&inCell=1");?> -
              -
              - ' . $lang->goback, $browseLink, 'self', "data-app='{$app->tab}'", 'btn btn-secondary');?> -
              - zahost->buildOperateMenu($zahost, 'view');?> -
              -
              -
              -
              -
              -
              -
              - -
              - -
              - diff --git a/module/zanode/view/browse.html.php b/module/zanode/view/browse.html.php deleted file mode 100644 index 70c600bdcd..0000000000 --- a/module/zanode/view/browse.html.php +++ /dev/null @@ -1,148 +0,0 @@ - - * @package zanode - * @version $Id$ - * @link https://www.zentao.net - */ -?> -getModuleRoot() . 'common/view/header.html.php'; ?> -zanode->confirmDelete) ?> -zanode->confirmBoot) ?> -zanode->confirmReboot) ?> -zanode->confirmShutdown) ?> -zanode->actionSuccess) ?> - - - -
              ' data-module='zanode'>
              -
              - recTotal}&recPerPage={$pager->recPerPage}"; ?> -
              - -
              -

              - zanode->empty; ?> - ' . $lang->zanode->create, '', 'class="btn btn-info"'); ?> -

              -
              - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
              idAB); ?>zanode->name); ?>zahost->type); ?>zanode->extranet); ?>zanode->cpuCores); ?>zanode->memory); ?>zanode->diskSize); ?>zanode->osName); ?>zanode->status); ?>zanode->hostName); ?> - actions ?>
              id; ?>inlink('view', "id=$node->id"), $node->name, '', ""); ?>hostType == 'physics' ? $this->lang->zanode->typeList['physics'] : $this->lang->zanode->typeList['node']; ?>extranet; ?>zanode->os->cpuCores, $node->cpuCores); ?>memory . $this->lang->zahost->unitList['GB']; ?>diskSize . $this->lang->zahost->unitList['GB']; ?>osName; ?>zanode->statusList, $node->status); ?>hostName; ?> - zanode->suspend}' target='hiddenwin'"; - $suspendAttr .= $node->hostType == 'physics' || $node->status != 'running' ? ' class="btn disabled"' : "class='btn' target='hiddenwin' onclick='if(confirm(\"{$lang->zanode->confirmSuspend}\")==false) return false;'"; - - $resumeAttr = "title='{$lang->zanode->resume}' target='hiddenwin'"; - $resumeAttr .= $node->hostType == 'physics' || $node->status == 'running' || $node->status == 'wait' ? ' class="btn disabled"' : "class='btn' target='hiddenwin' onclick='if(confirm(\"{$lang->zanode->confirmResume}\")==false) return false;'"; - - $rebootAttr = "title='{$lang->zanode->reboot}' target='hiddenwin'"; - $rebootAttr .= $node->hostType == 'physics' || in_array($node->status, array('wait', 'creating_img', 'creating_snap', 'restoring', 'shutoff')) ? ' class="btn disabled"' : "class='btn' target='hiddenwin' onclick='if(confirm(\"{$lang->zanode->confirmReboot}\")==false) return false;'"; - - $closeAttr = "title='{$lang->zanode->shutdown}'"; - $closeAttr .= $node->hostType == 'physics' || in_array($node->status, array('wait', 'creating_img', 'creating_snap', 'restoring')) ? ' class="btn disabled"' : ' class="btn iframe"'; - - $startAttr = "title='{$lang->zanode->boot}'"; - $startAttr .= $node->hostType == 'physics' || in_array($node->status, array('wait', 'creating_img', 'creating_snap', 'restoring')) ? ' class="btn disabled"' : ' class="btn iframe"'; - - $snapshotAttr = "title='{$lang->zanode->createSnapshot}'"; - $snapshotAttr .= $node->hostType == 'physics' || $node->status != 'running' ? ' class="btn disabled"' : ' class="btn iframe"'; - - $imageAttr = $node->hostType == 'physics' || $node->status != 'running' && $node->status != 'creating_img' ? ' class="btn btn-action iframe createImage disabled"' : ' class="btn btn-action iframe createImage"'; - - common::printLink('zanode', 'getVNC', "id={$node->id}", " ", (in_array($node->status ,array('running', 'launch', 'wait')) ? '_blank' : ''), "title='{$lang->zanode->getVNC}' class='btn desktop " . ($node->hostType == '' && in_array($node->status ,array('running', 'launch', 'wait')) ? '':'disabled') . "'", ''); - if($node->status == "suspend") - { - common::printLink('zanode', 'resume', "zanodeID={$node->id}", " ", '', $resumeAttr); - } - else - { - common::printLink('zanode', 'suspend', "zanodeID={$node->id}", " ", '', $suspendAttr); - } - - if($node->status == "shutoff") - { - common::printLink('zanode', 'start', "zanodeID={$node->id}", " ", '', $startAttr); - } - else - { - common::printLink('zanode', 'close', "zanodeID={$node->id}", " ", '', $closeAttr); - } - - common::printLink('zanode', 'reboot', "zanodeID={$node->id}", " ", '', $rebootAttr); - common::printLink('zanode', 'createSnapshot', "zanodeID={$node->id}", " ", '', $snapshotAttr, true, true); - - if(common::hasPriv('zanode', 'createImage') or common::hasPriv('zanode', 'destroy')) - { - echo "
              "; - echo ""; - echo ""; - echo "
              "; - } - ?> -
              -
              - - -
              - -getModuleRoot() . 'common/view/footer.html.php'; ?> diff --git a/module/zanode/view/browsesnapshot.html.php b/module/zanode/view/browsesnapshot.html.php deleted file mode 100644 index c4e247e170..0000000000 --- a/module/zanode/view/browsesnapshot.html.php +++ /dev/null @@ -1,75 +0,0 @@ - - * @package zahost - * @version $Id$ - * @link https://www.zentao.net - */ -?> -getModuleRoot() . 'common/view/header.html.php';?> - -
              - recTotal}&recPerPage={$pager->recPerPage}";?> - -
              -

              - zanode->snapshotEmpty;?> -

              -
              - - - - - - - - - - - - - - - status = ($snapshot->status == 'restoring' && time() - strtotime($snapshot->restoreDate) > 600) ? 'restore_failed' : $snapshot->status; - - $editAttr = $snapshot->status == 'failed' ? 'class="btn disabled"' : "title={$lang->zanode->editSnapshot} onclick='window.parent.editSnapshot(\"" . $this->createLink('zanode', 'editSnapshot', "snapshotID={$snapshot->id}") . "\")' class='btn'"; - - $restoreAttr = "title='{$lang->zanode->restoreSnapshot}' target='hiddenwin'"; - $restoreAttr .= ($node->status !='running' or in_array($snapshot->status, array('creating', 'failed', 'restoring'))) ? ' class="btn disabled"' : 'class="btn"'; - - $deleteAttr = "title='{$lang->zanode->deleteSnapshot}' target='hiddenwin'"; - $deleteAttr .= ($snapshot->status == 'restoring' or $snapshot->status == 'creating') ? ' class="btn disabled"' : 'class="btn"'; - - $isDefalut = $snapshot->name == 'defaultSnap' && $snapshot->createdBy == 'system'; - if($isDefalut) $editAttr = $deleteAttr = 'class="btn disabled"'; - $name = $snapshot->localName ? $snapshot->localName : $snapshot->name; - $title = $snapshot->name; - if($snapshot->name == 'defaultSnap' && $snapshot->createdBy == 'system') - { - $name = $lang->zanode->snapshot->defaultSnapName; - $title = $name; - } - ?> - - - - - - - - -
              zahost->image->name);?>zahost->status;?>zahost->createdBy;?>zahost->createdDate;?>actions;?>
              zanode->snapshot->statusList, $snapshot->status, '');?>name == 'defaultSnap' && $snapshot->createdBy == 'system' ? $lang->zanode->snapshot->defaultSnapUser : zget($users, $snapshot->createdBy, '')?>createdDate;?> - ', 'hiddenwin', $editAttr);?> - createLink('zanode', 'restoreSnapshot', "nodeID={$nodeID}&snapshotID={$snapshot->id}"), '', 'hiddenwin', $restoreAttr);?> - createLink('zanode', 'deleteSnapshot', "snapshotID={$snapshot->id}"), '', 'hiddenwin', $deleteAttr);?> -
              - - -
              diff --git a/module/zanode/view/create.html.php b/module/zanode/view/create.html.php deleted file mode 100644 index b5e1269a56..0000000000 --- a/module/zanode/view/create.html.php +++ /dev/null @@ -1,98 +0,0 @@ - - * @package host - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -getModuleRoot() . 'common/view/kindeditor.html.php';?> - -zanode->linuxList);?> -zanode->windowsList);?> -
              -
              -
              -
              -

              zanode->create;?>

              - -
              -
              - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
              zahost->type;?>zanode->typeList, 'virtual', "class='form-control chosen' onchange='zanodeType()'")?>
              zanode->hostName;?>createLink('zahost', 'create', array(), '', true), $lang->zahost->create, '', "class='text-primary iframe'");?>
              zanode->name;?>zanode->nameValid}\"");?>
              zanode->image;?>
              zanode->cpuCores;?>zanode->os->cpuCores, '', "class='form-control chosen'")?>
              zanode->memory;?> -
              - - GB -
              -
              zanode->diskSize;?> -
              - - - GB - -
              -
              zanode->osName;?> - - -
              zanode->desc ?>
              - - goback, '', "class='btn btn-wide btn-back'");?> -
              -
              -
              -
              -
              -getModuleRoot() . 'common/view/footer.html.php';?> diff --git a/module/zanode/view/createimage.html.php b/module/zanode/view/createimage.html.php deleted file mode 100644 index 611ff74339..0000000000 --- a/module/zanode/view/createimage.html.php +++ /dev/null @@ -1,124 +0,0 @@ - - * @package task - * @version $Id: cancel.html.php 935 2010-07-06 07:49:24Z jajacn@126.com $ - * @link https://www.zentao.net - */ -?> - - - -task);?> -id);?> -zanode); ?> - - -
              -
              -
              -

              - zanode->createImage;?> -

              -
              - -
              zanode->pending;?>
              -
              -
              -
              -
              - parent}"); - $link = str_replace('onlybody=yes', '', $link); - $link = trim($link, '?'); - ?> -
              zanode->createImageSuccess . html::a($link, $lang->zanode->createImageButton, "_parent", "style='color:#2e7fff;'");?>
              -
              zanode->createImageFail;?>
              - -
              - - - - - - - - - - - - - -
              zanode->imageName;?>
              zanode->desc;?>
              - status, array('shutdown', 'shutoff')) ? html::submitButton('', "") : html::submitButton('', "onclick='if(confirm(\"{$lang->zanode->createImageNotice}\")==false) return false;'");?> -
              -
              - -
              -
              - - - - diff --git a/module/zanode/view/createsnapshot.html.php b/module/zanode/view/createsnapshot.html.php deleted file mode 100644 index fabd768275..0000000000 --- a/module/zanode/view/createsnapshot.html.php +++ /dev/null @@ -1,46 +0,0 @@ - - * @package task - * @version - * @link https://www.zentao.net - */ -?> - - -id);?> -zanode); ?> - -
              -
              -
              -

              - zanode->createSnapshot;?> -

              -
              -
              - - - - - - - - - - - - - -
              zanode->snapshotName;?>
              zanode->desc;?>
              - -
              -
              -
              -
              - diff --git a/module/zanode/view/edit.html.php b/module/zanode/view/edit.html.php deleted file mode 100644 index 7340a44e7e..0000000000 --- a/module/zanode/view/edit.html.php +++ /dev/null @@ -1,91 +0,0 @@ - - * @package host - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -getModuleRoot() . 'common/view/kindeditor.html.php';?> -
              -
              -
              -
              -

              zanode->editAction;?>

              - -
              -
              - - hostType != 'physics'):?> - - - - - - - - - - - hostType != 'physics'):?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
              zanode->hostName;?>name, "class='form-control' readonly='readonly'");?>
              zanode->name;?>name, "class='form-control' placeholder=\"{$lang->zanode->nameValid}\" " . ($zanode->hostType != 'physics' ? "readonly='readonly'" : ''));?>
              zanode->image;?>name, "class='form-control' readonly='readonly'");?>
              zanode->IP;?>extranet, "class='form-control' readonly='readonly'");?>
              zanode->cpuCores;?>zanode->os->cpuCores, $zanode->cpuCores), "class='form-control' readonly='readonly'");?>
              zanode->memory;?> -
              - memory, "class='form-control' readonly='readonly'");?> - GB -
              -
              zanode->diskSize;?> -
              - diskSize, "class='form-control' readonly='readonly'");?> - - GB - -
              -
              zanode->osName;?>hostType != 'physics' ? $zanode->osName : zget($config->zanode->linuxList, $zanode->osName, zget($config->zanode->windowsList, $zanode->osName)), "class='form-control' readonly='readonly'")?>
              zanode->desc ?>desc, "class='form-control'")?>
              - - goback, '', "class='btn btn-wide btn-back'");?> -
              -
              -
              -
              -
              -getModuleRoot() . 'common/view/footer.html.php';?> - diff --git a/module/zanode/view/editsnapshot.html.php b/module/zanode/view/editsnapshot.html.php deleted file mode 100644 index 6c79c7ada3..0000000000 --- a/module/zanode/view/editsnapshot.html.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @package task - * @version - * @link https://www.zentao.net - */ -?> - - -zanode); ?> - -
              -
              -
              -

              - zanode->editSnapshot;?> -

              -
              -
              - - - - - - - - - - - - - -
              zanode->snapshotName;?>localName ? $snapshot->localName : $snapshot->name, "class='form-control'");?>
              zanode->desc;?>desc, "rows='6' class='form-control'");?>
              - -
              -
              -
              -
              - diff --git a/module/zanode/view/getvnc.html.php b/module/zanode/view/getvnc.html.php deleted file mode 100644 index 9c3ffdf517..0000000000 --- a/module/zanode/view/getvnc.html.php +++ /dev/null @@ -1,23 +0,0 @@ - - * @package vm - * @version $Id$ - * @link https://www.zentao.net - */ -?> -getModuleRoot() . 'common/view/header.lite.html.php';?> -
              - ";?> -
              - diff --git a/module/zanode/view/nodelist.html.php b/module/zanode/view/nodelist.html.php deleted file mode 100644 index 519a5d1aa0..0000000000 --- a/module/zanode/view/nodelist.html.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @package zanode - * @version $Id$ - * @link https://www.zentao.net - */ -?> - -getModuleRoot() . 'common/view/header.html.php'; ?> -
              - - -
              -

              - zanode->empty; ?> - ' . $lang->zanode->create, '', 'class="btn btn-info"'); ?> -

              -
              - - - - - - - - - - - - - - - - - - - - - - - - -
              zahost->name);?>zanode->cpuCores);?>zanode->memory);?>zanode->diskSize);?>zanode->osName);?>zanode->status);?>
              inlink('view', "id=$node->id"), $node->name, '_blank', ""); ?>zanode->os->cpuCores, $node->cpuCores); ?>memory . $this->lang->zahost->unitList['GB']; ?>diskSize . $this->lang->zahost->unitList['GB']; ?>osName; ?>zanode->statusList, $node->status); ?>
              - - -
              - -getModuleRoot() . 'common/view/footer.html.php'; ?> - \ No newline at end of file diff --git a/module/zanode/view/view.html.php b/module/zanode/view/view.html.php deleted file mode 100644 index a2084c602f..0000000000 --- a/module/zanode/view/view.html.php +++ /dev/null @@ -1,302 +0,0 @@ - - * @package zanode - * @version $Id: view.html.php $ - * @link https://www.zentao.net - */ -?> -getModuleRoot() . 'common/view/header.html.php'; ?> -getModuleRoot() . 'common/view/kindeditor.html.php'; ?> -zanode->confirmDelete) ?> -zanode->confirmBoot) ?> -zanode->confirmReboot) ?> -zanode->confirmShutdown) ?> -zanode->actionSuccess) ?> -id) ?> -zanode); ?> -status); ?> -hostType); ?> - -session->zanodeList ? $this->session->zanodeList : $this->createLink('zanode', 'browse', "");?> -id}&orderBy=%s"; -$account = strpos(strtolower($zanode->osName), "windows") !== false ? $config->zanode->defaultWinAccount : $config->zanode->defaultAccount; -$ssh = $zanode->hostType == 'physics' ? ('ssh ' . $zanode->extranet) : ($zanode->ssh ? 'ssh ' . $account . '@' . $zanode->ip . ' -p ' . $zanode->ssh : ''); -?> - -
              -
              -
              - hostType == 'physics'):?> -
              -
              zanode->baseInfo; ?>
              -
              -
              -
              -
              -
              zanode->osName; ?>:
              -
              zanode->linuxList, $zanode->osName, zget($config->zanode->windowsList, $zanode->osName)); ?>
              -
              -
              -
              -
              -
              zanode->sshAddress; ?>:
              -
              " : ''; ?>
              -
              - -
              -
              -
              -
              zanode->cpuCores; ?>:
              -
              cpuCores . ' ' . $lang->zanode->cpuUnit; ?>
              -
              -
              -
              -
              -
              -
              -
              zanode->status; ?>:
              -
              zanode->statusList, $zanode->status); ?>
              -
              -
              -
              -
              -
              zanode->memory; ?>:
              -
              memory; ?> GB
              -
              -
              -
              -
              -
              zanode->diskSize; ?>:
              -
              diskSize; ?> GB
              -
              -
              -
              -
              -
              - -
              -
              zanode->baseInfo; ?>
              -
              -
              -
              -
              -
              zanode->osName; ?>:
              -
              osName; ?>
              -
              -
              -
              -
              -
              zanode->sshCommand; ?>:
              -
              " : ''; ?>
              -
              - -
              -
              -
              -
              zanode->cpuCores; ?>:
              -
              cpuCores . ' ' . $lang->zanode->cpuUnit; ?>
              -
              -
              -
              -
              -
              -
              -
              zanode->status; ?>:
              -
              zanode->statusList, $zanode->status); ?>
              -
              -
              -
              -
              -
              zanode->defaultUser; ?>:
              -
              -
              -
              -
              -
              -
              zanode->memory; ?>:
              -
              memory; ?> GB
              -
              -
              -
              -
              -
              -
              -
              zanode->hostName; ?>:
              -
              hostName; ?>
              -
              -
              -
              -
              -
              zanode->defaultPwd; ?>:
              -
              ' . str_repeat('*', strlen($config->zanode->defaultPwd)) . '' - . ' ' - . "" - . ""; - ?>
              - -
              -
              -
              -
              -
              zanode->diskSize; ?>:
              -
              diskSize; ?> GB
              -
              -
              -
              -
              -
              -
              - -
              -
              zanode->desc; ?>
              -
              desc) ? htmlspecialchars_decode($zanode->desc) : $lang->noData; ?>
              -
              - - createLink('action', 'comment', "objectType=zanode&objectID=$zanode->id"); - ?> -
              -
              -
              -
              - zanode->init->statusTitle; ?> - -
              -
              - hostType != 'physics'):?> -
              - ● -  ZenAgent   - zanode->initializing; ?> - -
              - -
              - ● -  ZTF   - zanode->initializing; ?>  - -
              -
              - zanode->init->initSuccessNoticeTitle, "{$lang->zanode->manual}", html::a(helper::createLink('testcase', 'automation', "", '', true), $lang->zanode->automation, '', "class='iframe' title='{$lang->zanode->automation}' data-width='800px'", '')); ?> - hostType == 'physics'):?> -
              - hostType == 'physics' ? $lang->zanode->init->initFailNoticeOnPhysics : $lang->zanode->init->initFailNotice;?> - -
              - "; ?> -
              -
              - -
              -
              -
              -
              - hostType == ''):?> -
              -
              -
              - zanode->browseSnapshot;?> -
              - status == 'running'){ - $snapshotAttr = "title='{$lang->zanode->createSnapshot}'"; - $snapshotAttr .= $zanode->status != 'running' ? ' class="btn btn-snap-create disabled"' : ' class="btn btn-primary btn-snap-create iframe"'; - common::printLink('zanode', 'createSnapshot', "zanodeID={$zanode->id}", " " . $lang->zanode->createSnapshot, '', $snapshotAttr, true, true); - } - ?> -
              -
              - -
              - createLink('zanode', 'browseSnapshot', "nodeID=$zanode->id", '', true) . "' frameborder='no' allowfullscreen='true' mozallowfullscreen='true' webkitallowfullscreen='true' allowtransparency='true' scrolling='auto' style='min-height:300px;'>";?> -
              - -
              noData; ?>
              - -
              -
              - - printExtendFields($zanode, 'div', "position=left&inForm=0&inCell=1"); ?> -
              -
              - ' . $lang->goback, $browseLink, 'self', "data-app='{$app->tab}'", 'btn btn-secondary');?> -
              - deleted)) { - $suspendAttr = "title='{$lang->zanode->suspend}' target='hiddenwin'"; - $suspendAttr .= $zanode->hostType == 'physics' || $zanode->status != 'running' ? ' class="btn disabled"' : "class='btn' target='hiddenwin' onclick='if(confirm(\"{$lang->zanode->confirmSuspend}\")==false) return false;'"; - - $resumeAttr = "title='{$lang->zanode->resume}' target='hiddenwin'"; - $resumeAttr .= $zanode->hostType == 'physics' || $zanode->status == 'running' ? ' class="btn disabled"' : "class='btn' target='hiddenwin' onclick='if(confirm(\"{$lang->zanode->confirmResume}\")==false) return false;'"; - - $rebootAttr = "title='{$lang->zanode->reboot}' target='hiddenwin'"; - $rebootAttr .= $zanode->hostType == 'physics' || in_array($zanode->status, array('wait', 'creating_img', 'creating_snap', 'restoring', 'shutoff')) ? ' class="btn disabled"' : "class='btn' target='hiddenwin' onclick='if(confirm(\"{$lang->zanode->confirmReboot}\")==false) return false;'"; - - $closeAttr = "title='{$lang->zanode->shutdown}'"; - $closeAttr .= $zanode->hostType == 'physics' || in_array($zanode->status, array('wait', 'creating_img', 'creating_snap', 'restoring')) ? ' class="btn disabled"' : ' class="btn iframe"'; - - $startAttr = "title='{$lang->zanode->boot}'"; - $startAttr .= $zanode->hostType == 'physics' || in_array($zanode->status, array('wait', 'creating_img', 'creating_snap', 'restoring')) ? ' class="btn disabled"' : ' class="btn iframe"'; - - $snapshotAttr = "title='{$lang->zanode->createSnapshot}'"; - $snapshotAttr .= $zanode->hostType == 'physics' || $zanode->status != 'running' ? ' class="btn disabled"' : ' class="btn iframe"'; - common::printLink('zanode', 'getVNC', "id={$zanode->id}", " " . $lang->zanode->getVNC, in_array($zanode->status ,array('running', 'launch', 'wait')) ? '_blank' : '', "title='{$lang->zanode->getVNC}' class='btn desktop " . ($zanode->hostType == '' && in_array($zanode->status ,array('running', 'launch', 'wait')) ? '':'disabled') . "'", ''); - - if($zanode->status == "suspend") - { - common::printLink('zanode', 'resume', "zanodeID={$zanode->id}", " " . $lang->zanode->resumeNode, '', $resumeAttr); - } - else - { - common::printLink('zanode', 'suspend', "zanodeID={$zanode->id}", " " . $lang->zanode->suspendNode, '', $suspendAttr); - } - - if($zanode->status == "shutoff") - { - common::printLink('zanode', 'start', "zanodeID={$zanode->id}", " " . $lang->zanode->bootNode, '', $startAttr); - } - else - { - common::printLink('zanode', 'close', "zanodeID={$zanode->id}", " " . $lang->zanode->shutdownNode, '', $closeAttr); - } - - common::printLink('zanode', 'reboot', "zanodeID={$zanode->id}", " " . $lang->zanode->rebootNode, '', $rebootAttr); - common::printLink('zanode', 'createSnapshot', "zanodeID={$zanode->id}", " " . $lang->zanode->createSnapshot, '', $snapshotAttr, true, true); - - } - ?> -
              - zanode->buildOperateMenu($zanode, 'view'); ?> - -
              -
              -
              -
              -
              - -
              - -
              - diff --git a/test/lib/rest.php b/test/lib/rest.php index 17ddfc77eb..18b19fe44e 100644 --- a/test/lib/rest.php +++ b/test/lib/rest.php @@ -117,6 +117,7 @@ class rest { $headers['Accept'] = 'application/json'; $headers['Content-Type'] = 'application/json'; + $data = json_encode($data); $resp = requests::put($this->base . $url, $headers, $data, $options = array()); try diff --git a/test/lib/ui.php b/test/lib/ui.php index 568eeae0bd..feef2de5b3 100644 --- a/test/lib/ui.php +++ b/test/lib/ui.php @@ -241,18 +241,22 @@ class tester extends result * Switch a zentao vision. * * @param string $vision - * @param int $refreshTime + * @param int $waitTime * @access public * @return object */ - public function switchVision($vision, $refreshTime = 2) + public function switchVision($vision, $waitTime = 2) { - $currentVision = $this->page->getCookie('vision'); - if($currentVision) $this->page->deleteCookie('vision'); + if(empty($this->lang->visionList->{$vision})) return false; + $visionName = $this->lang->visionList->{$vision}; - $this->page->addCookie(array('name' => 'vision', 'value' => $vision)); - $this->page->wait($refreshTime)->refresh(); + $this->page->wait(2); + $this->page->dom->switchToIframe(); + $this->page->dom->visionSwitcher->click(); + $this->page->wait(2); + $this->page->dom->btn($visionName)->click(); + $this->page->wait($waitTime); return $this; } diff --git a/www/js/zui3/icons/ZentaoIcon.eot b/www/js/zui3/icons/ZentaoIcon.eot index 5e7d185706..12d251a632 100755 Binary files a/www/js/zui3/icons/ZentaoIcon.eot and b/www/js/zui3/icons/ZentaoIcon.eot differ diff --git a/www/js/zui3/icons/ZentaoIcon.svg b/www/js/zui3/icons/ZentaoIcon.svg index cc2f7995e9..4632452d13 100755 --- a/www/js/zui3/icons/ZentaoIcon.svg +++ b/www/js/zui3/icons/ZentaoIcon.svg @@ -358,6 +358,13 @@ + + + + + + + diff --git a/www/js/zui3/icons/ZentaoIcon.ttf b/www/js/zui3/icons/ZentaoIcon.ttf index 33e3b0c0f8..0d2c98d8aa 100755 Binary files a/www/js/zui3/icons/ZentaoIcon.ttf and b/www/js/zui3/icons/ZentaoIcon.ttf differ diff --git a/www/js/zui3/icons/ZentaoIcon.woff b/www/js/zui3/icons/ZentaoIcon.woff index 40fd268a7b..563a9c0865 100755 Binary files a/www/js/zui3/icons/ZentaoIcon.woff and b/www/js/zui3/icons/ZentaoIcon.woff differ diff --git a/www/js/zui3/zin.js b/www/js/zui3/zin.js index d6fa4f71cc..f4629825f4 100644 --- a/www/js/zui3/zin.js +++ b/www/js/zui3/zin.js @@ -168,7 +168,8 @@ function showFatalError(data, _info, options) { - zui.Modal.showError({error: data.startsWith('URL: ${options.url}
              ${data}`, size: 'lg'}) + const isNormalPage = data.startsWith('URL: ${options.url}
              ${data}`, size: 'lg', html: !isNormalPage}) } function initZinbar() diff --git a/www/js/zui3/zui.zentao.css b/www/js/zui3/zui.zentao.css index b47e2edbc2..6cf71db8ff 100644 --- a/www/js/zui3/zui.zentao.css +++ b/www/js/zui3/zui.zentao.css @@ -1,2 +1,2 @@ -*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*! tailwindcss v3.4.17 | MIT License | https://tailwindcss.com*/*,:after,:before{border-color:rgb(var(--color-gray-200-rgb));border-style:solid;border-width:0;box-sizing:border-box}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;font-family:-apple-system,Noto Sans,Helvetica Neue,Helvetica,Nimbus Sans L,Arial,Liberation Sans,PingFang SC,Hiragino Sans GB,Noto Sans CJK SC,Source Han Sans SC,Source Han Sans CN,Microsoft YaHei,Wenquanyi Micro Hei,WenQuanYi Zen Hei,ST Heiti,SimHei,WenQuanYi Zen Hei Sharp,sans-serif;font-feature-settings:normal;font-variation-settings:normal;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-tap-highlight-color:transparent}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-size:1em;font-variation-settings:normal}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{color:inherit;font-family:inherit;font-feature-settings:inherit;font-size:100%;font-variation-settings:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:rgb(var(--color-gray-400-rgb));opacity:1}input::placeholder,textarea::placeholder{color:rgb(var(--color-gray-400-rgb));opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]:where(:not([hidden=until-found])){display:none}:root{--screen-2xl:1720px;--color-gray-50:#fcfdfe;--color-gray-100:#eff1f3;--color-gray-200:#ebedf3;--color-gray-300:#d2d6e5;--color-gray-400:#b2b9c5;--color-gray-500:#64758b;--color-gray-600:#4a577f;--color-gray-700:#3d4667;--color-gray-800:#353d57;--color-gray-900:#30394a;--color-gray-950:#0b0f18;--color-gray-50-rgb:252,253,254;--color-gray-100-rgb:239,241,243;--color-gray-200-rgb:235,237,243;--color-gray-300-rgb:210,214,229;--color-gray-400-rgb:178,185,197;--color-gray-500-rgb:100,117,139;--color-gray-600-rgb:74,87,127;--color-gray-700-rgb:61,70,103;--color-gray-800-rgb:53,61,87;--color-gray-900-rgb:48,57,74;--color-gray-950-rgb:11,15,24;--color-primary-50:#eef6ff;--color-primary-100:#d9eaff;--color-primary-200:#bcdcff;--color-primary-300:#8ec6ff;--color-primary-400:#59a5ff;--color-primary-500:#3883fa;--color-primary-600:#2b67e5;--color-primary-700:#144ce1;--color-primary-800:#173db6;--color-primary-900:#19388f;--color-primary-950:#142457;--color-primary-50-rgb:238,246,255;--color-primary-100-rgb:217,234,255;--color-primary-200-rgb:188,220,255;--color-primary-300-rgb:142,198,255;--color-primary-400-rgb:89,165,255;--color-primary-500-rgb:56,131,250;--color-primary-600-rgb:43,103,229;--color-primary-700-rgb:20,76,225;--color-primary-800-rgb:23,61,182;--color-primary-900-rgb:25,56,143;--color-primary-950-rgb:20,36,87;--color-secondary-50:#e7f6ff;--color-secondary-100:#cdecff;--color-secondary-200:#9bd9ff;--color-secondary-300:#77cbff;--color-secondary-400:#60c2ff;--color-secondary-500:#37b2fe;--color-secondary-600:#18a6fd;--color-secondary-700:#1099ed;--color-secondary-800:#078ada;--color-secondary-900:#046bab;--color-secondary-950:#062a4b;--color-secondary-50-rgb:231,246,255;--color-secondary-100-rgb:205,236,255;--color-secondary-200-rgb:155,217,255;--color-secondary-300-rgb:119,203,255;--color-secondary-400-rgb:96,194,255;--color-secondary-500-rgb:55,178,254;--color-secondary-600-rgb:24,166,253;--color-secondary-700-rgb:16,153,237;--color-secondary-800-rgb:7,138,218;--color-secondary-900-rgb:4,107,171;--color-secondary-950-rgb:6,42,75;--color-success-50:#effaf6;--color-success-100:#d6f2e7;--color-success-200:#ade5ce;--color-success-300:#83d7b6;--color-success-400:#5aca9d;--color-success-500:#31bd85;--color-success-600:#2ba675;--color-success-700:#28996c;--color-success-800:#21805a;--color-success-900:#185e3b;--color-success-950:#0e3421;--color-success-50-rgb:239,250,246;--color-success-100-rgb:214,242,231;--color-success-200-rgb:173,229,206;--color-success-300-rgb:131,215,182;--color-success-400-rgb:90,202,157;--color-success-500-rgb:49,189,133;--color-success-600-rgb:43,166,117;--color-success-700-rgb:40,153,108;--color-success-800-rgb:33,128,90;--color-success-900-rgb:24,94,59;--color-success-950-rgb:14,52,33;--color-warning-50:#fff4ea;--color-warning-100:#ffecdb;--color-warning-200:#ffd2a9;--color-warning-300:#ffbc7e;--color-warning-400:#ffaf65;--color-warning-500:#ff9f46;--color-warning-600:#f38f19;--color-warning-700:#ed8307;--color-warning-800:#d17100;--color-warning-900:#af5f01;--color-warning-950:#441506;--color-warning-50-rgb:255,244,234;--color-warning-100-rgb:255,236,219;--color-warning-200-rgb:255,210,169;--color-warning-300-rgb:255,188,126;--color-warning-400-rgb:255,175,101;--color-warning-500-rgb:255,159,70;--color-warning-600-rgb:243,143,25;--color-warning-700-rgb:237,131,7;--color-warning-800-rgb:209,113,0;--color-warning-900-rgb:175,95,1;--color-warning-950-rgb:68,21,6;--color-danger-50:#ffebeb;--color-danger-100:#ffd5d5;--color-danger-200:#ffb1b1;--color-danger-300:#ff9292;--color-danger-400:#ff7c7c;--color-danger-500:#fc5959;--color-danger-600:#fb2b2b;--color-danger-700:#d91b1b;--color-danger-800:#ba1313;--color-danger-900:#a20606;--color-danger-950:#470808;--color-danger-50-rgb:255,235,235;--color-danger-100-rgb:255,213,213;--color-danger-200-rgb:255,177,177;--color-danger-300-rgb:255,146,146;--color-danger-400-rgb:255,124,124;--color-danger-500-rgb:252,89,89;--color-danger-600-rgb:251,43,43;--color-danger-700-rgb:217,27,27;--color-danger-800-rgb:186,19,19;--color-danger-900-rgb:162,6,6;--color-danger-950-rgb:71,8,8;--color-important-50:#fff8f5;--color-important-100:#ffe2d9;--color-important-200:#ffcebf;--color-important-300:#ffb29b;--color-important-400:#ff8c68;--color-important-500:#ff8058;--color-important-600:#ff6f42;--color-important-700:#ff4912;--color-important-800:#c83509;--color-important-900:#611700;--color-important-950:#440609;--color-important-50-rgb:255,248,245;--color-important-100-rgb:255,226,217;--color-important-200-rgb:255,206,191;--color-important-300-rgb:255,178,155;--color-important-400-rgb:255,140,104;--color-important-500-rgb:255,128,88;--color-important-600-rgb:255,111,66;--color-important-700-rgb:255,73,18;--color-important-800-rgb:200,53,9;--color-important-900-rgb:97,23,0;--color-important-950-rgb:68,6,9;--color-special-50:#efecfa;--color-special-100:#e4dff7;--color-special-200:#c4b6ff;--color-special-300:#a38cff;--color-special-400:#8a6ff5;--color-special-500:#8166ee;--color-special-600:#7055df;--color-special-700:#513baa;--color-special-800:#452da5;--color-special-900:#30216e;--color-special-950:#271560;--color-special-50-rgb:239,236,250;--color-special-100-rgb:228,223,247;--color-special-200-rgb:196,182,255;--color-special-300-rgb:163,140,255;--color-special-400-rgb:138,111,245;--color-special-500-rgb:129,102,238;--color-special-600-rgb:112,85,223;--color-special-700-rgb:81,59,170;--color-special-800-rgb:69,45,165;--color-special-900-rgb:48,33,110;--color-special-950-rgb:39,21,96;--color-inherit:inherit;--color-transparent:transparent;--color-current:currentColor;--color-black:#000;--color-white:#fff;--color-canvas:#fff;--color-canvas-light:#fff;--color-canvas-dark:#fcfdfe;--color-inverse:#000;--color-surface:#eff1f3;--color-surface-light:#fcfdfe;--color-surface-strong:#ebedf3;--color-fore:#30394a;--color-fore-in-light:#30394a;--color-fore-in-dark:#fff;--color-focus:#bcdcff;--color-link:#2b47a2;--color-link-hover:#144ce1;--color-link-visited:#6328a4;--color-link-active:#144ce1;--color-placeholder:#64758b;--color-border:#ebedf3;--color-border-strong:#d2d6e5;--color-border-light:#eff1f3;--color-black-rgb:0,0,0;--color-white-rgb:255,255,255;--color-canvas-rgb:255,255,255;--color-canvas-light-rgb:255,255,255;--color-canvas-dark-rgb:252,253,254;--color-inverse-rgb:0,0,0;--color-surface-rgb:239,241,243;--color-surface-light-rgb:252,253,254;--color-surface-strong-rgb:235,237,243;--color-fore-rgb:48,57,74;--color-fore-in-light-rgb:48,57,74;--color-fore-in-dark-rgb:255,255,255;--color-focus-rgb:188,220,255;--color-link-rgb:43,71,162;--color-link-hover-rgb:20,76,225;--color-link-visited-rgb:99,40,164;--color-link-active-rgb:20,76,225;--color-placeholder-rgb:100,117,139;--color-border-rgb:235,237,243;--color-border-strong-rgb:210,214,229;--color-border-light-rgb:239,241,243;--radius-none:0px;--radius-sm:0.0625rem;--radius:0.125rem;--radius-md:0.25rem;--radius-lg:0.375rem;--radius-xl:0.5rem;--radius-2xl:0.75rem;--radius-3xl:1rem;--radius-full:9999px;--shadow-sm:0 1px 2px 0 rgba(0,0,0,.04),0 0 2px -1px rgba(0,0,0,.01);--shadow:0 3px 8px 0 rgba(0,0,0,.04),0 1px 2px -1px rgba(0,0,0,.01);--shadow-md:0 2px 6px -1px rgba(0,0,0,.2),0 1px 4px -2px rgba(0,0,0,.15);--shadow-lg:0 5px 15px -3px rgba(0,0,0,.2),0 2px 6px -4px rgba(0,0,0,.15);--shadow-xl:0 10px 25px -5px rgba(0,0,0,.2),0 4px 10px -6px rgba(0,0,0,.15);--shadow-2xl:0 10px 50px -10px rgba(0,0,0,.4),0 8px 20px -10px rgba(0,0,0,.3);--shadow-inner:inset 0 2px 4px 0 rgba(0,0,0,.05);--shadow-none:none;--space:0.25rem;--font-size-article:0.875rem;--font-size-root:16px;--font-size-page-lineHeight:1.5384615385}.dark{--color-gray-50:#0b0f18;--color-gray-100:#30394a;--color-gray-200:#353d57;--color-gray-300:#3d4667;--color-gray-400:#4a577f;--color-gray-500:#64758b;--color-gray-600:#b2b9c5;--color-gray-700:#d2d6e5;--color-gray-800:#ebedf3;--color-gray-900:#eff1f3;--color-gray-950:#fcfdfe;--color-gray-50-rgb:11,15,24;--color-gray-100-rgb:48,57,74;--color-gray-200-rgb:53,61,87;--color-gray-300-rgb:61,70,103;--color-gray-400-rgb:74,87,127;--color-gray-500-rgb:100,117,139;--color-gray-600-rgb:178,185,197;--color-gray-700-rgb:210,214,229;--color-gray-800-rgb:235,237,243;--color-gray-900-rgb:239,241,243;--color-gray-950-rgb:252,253,254;--color-primary-50:#142457;--color-primary-100:#19388f;--color-primary-200:#173db6;--color-primary-300:#144ce1;--color-primary-400:#2b67e5;--color-primary-500:#3883fa;--color-primary-600:#59a5ff;--color-primary-700:#8ec6ff;--color-primary-800:#bcdcff;--color-primary-900:#d9eaff;--color-primary-950:#eef6ff;--color-primary-50-rgb:20,36,87;--color-primary-100-rgb:25,56,143;--color-primary-200-rgb:23,61,182;--color-primary-300-rgb:20,76,225;--color-primary-400-rgb:43,103,229;--color-primary-500-rgb:56,131,250;--color-primary-600-rgb:89,165,255;--color-primary-700-rgb:142,198,255;--color-primary-800-rgb:188,220,255;--color-primary-900-rgb:217,234,255;--color-primary-950-rgb:238,246,255;--color-secondary-50:#062a4b;--color-secondary-100:#046bab;--color-secondary-200:#078ada;--color-secondary-300:#1099ed;--color-secondary-400:#18a6fd;--color-secondary-500:#37b2fe;--color-secondary-600:#60c2ff;--color-secondary-700:#77cbff;--color-secondary-800:#9bd9ff;--color-secondary-900:#cdecff;--color-secondary-950:#e7f6ff;--color-secondary-50-rgb:6,42,75;--color-secondary-100-rgb:4,107,171;--color-secondary-200-rgb:7,138,218;--color-secondary-300-rgb:16,153,237;--color-secondary-400-rgb:24,166,253;--color-secondary-500-rgb:55,178,254;--color-secondary-600-rgb:96,194,255;--color-secondary-700-rgb:119,203,255;--color-secondary-800-rgb:155,217,255;--color-secondary-900-rgb:205,236,255;--color-secondary-950-rgb:231,246,255;--color-success-50:#0e3421;--color-success-100:#185e3b;--color-success-200:#21805a;--color-success-300:#28996c;--color-success-400:#2ba675;--color-success-500:#31bd85;--color-success-600:#5aca9d;--color-success-700:#83d7b6;--color-success-800:#ade5ce;--color-success-900:#d6f2e7;--color-success-950:#effaf6;--color-success-50-rgb:14,52,33;--color-success-100-rgb:24,94,59;--color-success-200-rgb:33,128,90;--color-success-300-rgb:40,153,108;--color-success-400-rgb:43,166,117;--color-success-500-rgb:49,189,133;--color-success-600-rgb:90,202,157;--color-success-700-rgb:131,215,182;--color-success-800-rgb:173,229,206;--color-success-900-rgb:214,242,231;--color-success-950-rgb:239,250,246;--color-warning-50:#441506;--color-warning-100:#af5f01;--color-warning-200:#d17100;--color-warning-300:#ed8307;--color-warning-400:#f38f19;--color-warning-500:#ff9f46;--color-warning-600:#ffaf65;--color-warning-700:#ffbc7e;--color-warning-800:#ffd2a9;--color-warning-900:#ffecdb;--color-warning-950:#fff4ea;--color-warning-50-rgb:68,21,6;--color-warning-100-rgb:175,95,1;--color-warning-200-rgb:209,113,0;--color-warning-300-rgb:237,131,7;--color-warning-400-rgb:243,143,25;--color-warning-500-rgb:255,159,70;--color-warning-600-rgb:255,175,101;--color-warning-700-rgb:255,188,126;--color-warning-800-rgb:255,210,169;--color-warning-900-rgb:255,236,219;--color-warning-950-rgb:255,244,234;--color-danger-50:#470808;--color-danger-100:#a20606;--color-danger-200:#ba1313;--color-danger-300:#d91b1b;--color-danger-400:#fb2b2b;--color-danger-500:#fc5959;--color-danger-600:#ff7c7c;--color-danger-700:#ff9292;--color-danger-800:#ffb1b1;--color-danger-900:#ffd5d5;--color-danger-950:#ffebeb;--color-danger-50-rgb:71,8,8;--color-danger-100-rgb:162,6,6;--color-danger-200-rgb:186,19,19;--color-danger-300-rgb:217,27,27;--color-danger-400-rgb:251,43,43;--color-danger-500-rgb:252,89,89;--color-danger-600-rgb:255,124,124;--color-danger-700-rgb:255,146,146;--color-danger-800-rgb:255,177,177;--color-danger-900-rgb:255,213,213;--color-danger-950-rgb:255,235,235;--color-important-50:#440609;--color-important-100:#611700;--color-important-200:#c83509;--color-important-300:#ff4912;--color-important-400:#ff6f42;--color-important-500:#ff8058;--color-important-600:#ff8c68;--color-important-700:#ffb29b;--color-important-800:#ffcebf;--color-important-900:#ffe2d9;--color-important-950:#fff8f5;--color-important-50-rgb:68,6,9;--color-important-100-rgb:97,23,0;--color-important-200-rgb:200,53,9;--color-important-300-rgb:255,73,18;--color-important-400-rgb:255,111,66;--color-important-500-rgb:255,128,88;--color-important-600-rgb:255,140,104;--color-important-700-rgb:255,178,155;--color-important-800-rgb:255,206,191;--color-important-900-rgb:255,226,217;--color-important-950-rgb:255,248,245;--color-special-50:#271560;--color-special-100:#30216e;--color-special-200:#452da5;--color-special-300:#513baa;--color-special-400:#7055df;--color-special-500:#8166ee;--color-special-600:#8a6ff5;--color-special-700:#a38cff;--color-special-800:#c4b6ff;--color-special-900:#e4dff7;--color-special-950:#efecfa;--color-special-50-rgb:39,21,96;--color-special-100-rgb:48,33,110;--color-special-200-rgb:69,45,165;--color-special-300-rgb:81,59,170;--color-special-400-rgb:112,85,223;--color-special-500-rgb:129,102,238;--color-special-600-rgb:138,111,245;--color-special-700-rgb:163,140,255;--color-special-800-rgb:196,182,255;--color-special-900-rgb:228,223,247;--color-special-950-rgb:239,236,250;--color-canvas:#0b0f18;--color-inverse:#fff;--color-surface:#353d57;--color-surface-light:#30394a;--color-surface-strong:#3d4667;--color-fore:#ebedf3;--color-focus:#173db6;--color-link:#59a5ff;--color-link-hover:#3883fa;--color-link-visited:#bcdcff;--color-link-active:#bcdcff;--color-placeholder:#4a577f;--color-border:#353d57;--color-border-strong:#3d4667;--color-border-light:#30394a;--color-canvas-rgb:11,15,24;--color-inverse-rgb:255,255,255;--color-surface-rgb:53,61,87;--color-surface-light-rgb:48,57,74;--color-surface-strong-rgb:61,70,103;--color-fore-rgb:235,237,243;--color-focus-rgb:23,61,182;--color-link-rgb:89,165,255;--color-link-hover-rgb:56,131,250;--color-link-visited-rgb:188,220,255;--color-link-active-rgb:188,220,255;--color-placeholder-rgb:74,87,127;--color-border-rgb:53,61,87;--color-border-strong-rgb:61,70,103;--color-border-light-rgb:48,57,74}.light-in-dark{--color-gray-50:#fcfdfe;--color-gray-100:#eff1f3;--color-gray-200:#ebedf3;--color-gray-300:#d2d6e5;--color-gray-400:#b2b9c5;--color-gray-500:#64758b;--color-gray-600:#4a577f;--color-gray-700:#3d4667;--color-gray-800:#353d57;--color-gray-900:#30394a;--color-gray-950:#0b0f18;--color-gray-50-rgb:252,253,254;--color-gray-100-rgb:239,241,243;--color-gray-200-rgb:235,237,243;--color-gray-300-rgb:210,214,229;--color-gray-400-rgb:178,185,197;--color-gray-500-rgb:100,117,139;--color-gray-600-rgb:74,87,127;--color-gray-700-rgb:61,70,103;--color-gray-800-rgb:53,61,87;--color-gray-900-rgb:48,57,74;--color-gray-950-rgb:11,15,24;--color-primary-50:#eef6ff;--color-primary-100:#d9eaff;--color-primary-200:#bcdcff;--color-primary-300:#8ec6ff;--color-primary-400:#59a5ff;--color-primary-500:#3883fa;--color-primary-600:#2b67e5;--color-primary-700:#144ce1;--color-primary-800:#173db6;--color-primary-900:#19388f;--color-primary-950:#142457;--color-primary-50-rgb:238,246,255;--color-primary-100-rgb:217,234,255;--color-primary-200-rgb:188,220,255;--color-primary-300-rgb:142,198,255;--color-primary-400-rgb:89,165,255;--color-primary-500-rgb:56,131,250;--color-primary-600-rgb:43,103,229;--color-primary-700-rgb:20,76,225;--color-primary-800-rgb:23,61,182;--color-primary-900-rgb:25,56,143;--color-primary-950-rgb:20,36,87;--color-secondary-50:#e7f6ff;--color-secondary-100:#cdecff;--color-secondary-200:#9bd9ff;--color-secondary-300:#77cbff;--color-secondary-400:#60c2ff;--color-secondary-500:#37b2fe;--color-secondary-600:#18a6fd;--color-secondary-700:#1099ed;--color-secondary-800:#078ada;--color-secondary-900:#046bab;--color-secondary-950:#062a4b;--color-secondary-50-rgb:231,246,255;--color-secondary-100-rgb:205,236,255;--color-secondary-200-rgb:155,217,255;--color-secondary-300-rgb:119,203,255;--color-secondary-400-rgb:96,194,255;--color-secondary-500-rgb:55,178,254;--color-secondary-600-rgb:24,166,253;--color-secondary-700-rgb:16,153,237;--color-secondary-800-rgb:7,138,218;--color-secondary-900-rgb:4,107,171;--color-secondary-950-rgb:6,42,75;--color-success-50:#effaf6;--color-success-100:#d6f2e7;--color-success-200:#ade5ce;--color-success-300:#83d7b6;--color-success-400:#5aca9d;--color-success-500:#31bd85;--color-success-600:#2ba675;--color-success-700:#28996c;--color-success-800:#21805a;--color-success-900:#185e3b;--color-success-950:#0e3421;--color-success-50-rgb:239,250,246;--color-success-100-rgb:214,242,231;--color-success-200-rgb:173,229,206;--color-success-300-rgb:131,215,182;--color-success-400-rgb:90,202,157;--color-success-500-rgb:49,189,133;--color-success-600-rgb:43,166,117;--color-success-700-rgb:40,153,108;--color-success-800-rgb:33,128,90;--color-success-900-rgb:24,94,59;--color-success-950-rgb:14,52,33;--color-warning-50:#fff4ea;--color-warning-100:#ffecdb;--color-warning-200:#ffd2a9;--color-warning-300:#ffbc7e;--color-warning-400:#ffaf65;--color-warning-500:#ff9f46;--color-warning-600:#f38f19;--color-warning-700:#ed8307;--color-warning-800:#d17100;--color-warning-900:#af5f01;--color-warning-950:#441506;--color-warning-50-rgb:255,244,234;--color-warning-100-rgb:255,236,219;--color-warning-200-rgb:255,210,169;--color-warning-300-rgb:255,188,126;--color-warning-400-rgb:255,175,101;--color-warning-500-rgb:255,159,70;--color-warning-600-rgb:243,143,25;--color-warning-700-rgb:237,131,7;--color-warning-800-rgb:209,113,0;--color-warning-900-rgb:175,95,1;--color-warning-950-rgb:68,21,6;--color-danger-50:#ffebeb;--color-danger-100:#ffd5d5;--color-danger-200:#ffb1b1;--color-danger-300:#ff9292;--color-danger-400:#ff7c7c;--color-danger-500:#fc5959;--color-danger-600:#fb2b2b;--color-danger-700:#d91b1b;--color-danger-800:#ba1313;--color-danger-900:#a20606;--color-danger-950:#470808;--color-danger-50-rgb:255,235,235;--color-danger-100-rgb:255,213,213;--color-danger-200-rgb:255,177,177;--color-danger-300-rgb:255,146,146;--color-danger-400-rgb:255,124,124;--color-danger-500-rgb:252,89,89;--color-danger-600-rgb:251,43,43;--color-danger-700-rgb:217,27,27;--color-danger-800-rgb:186,19,19;--color-danger-900-rgb:162,6,6;--color-danger-950-rgb:71,8,8;--color-important-50:#fff8f5;--color-important-100:#ffe2d9;--color-important-200:#ffcebf;--color-important-300:#ffb29b;--color-important-400:#ff8c68;--color-important-500:#ff8058;--color-important-600:#ff6f42;--color-important-700:#ff4912;--color-important-800:#c83509;--color-important-900:#611700;--color-important-950:#440609;--color-important-50-rgb:255,248,245;--color-important-100-rgb:255,226,217;--color-important-200-rgb:255,206,191;--color-important-300-rgb:255,178,155;--color-important-400-rgb:255,140,104;--color-important-500-rgb:255,128,88;--color-important-600-rgb:255,111,66;--color-important-700-rgb:255,73,18;--color-important-800-rgb:200,53,9;--color-important-900-rgb:97,23,0;--color-important-950-rgb:68,6,9;--color-special-50:#efecfa;--color-special-100:#e4dff7;--color-special-200:#c4b6ff;--color-special-300:#a38cff;--color-special-400:#8a6ff5;--color-special-500:#8166ee;--color-special-600:#7055df;--color-special-700:#513baa;--color-special-800:#452da5;--color-special-900:#30216e;--color-special-950:#271560;--color-special-50-rgb:239,236,250;--color-special-100-rgb:228,223,247;--color-special-200-rgb:196,182,255;--color-special-300-rgb:163,140,255;--color-special-400-rgb:138,111,245;--color-special-500-rgb:129,102,238;--color-special-600-rgb:112,85,223;--color-special-700-rgb:81,59,170;--color-special-800-rgb:69,45,165;--color-special-900-rgb:48,33,110;--color-special-950-rgb:39,21,96;--color-inherit:inherit;--color-transparent:transparent;--color-current:currentColor;--color-black:#000;--color-white:#fff;--color-canvas:#fff;--color-canvas-light:#fff;--color-canvas-dark:#fcfdfe;--color-inverse:#000;--color-surface:#eff1f3;--color-surface-light:#fcfdfe;--color-surface-strong:#ebedf3;--color-fore:#30394a;--color-fore-in-light:#30394a;--color-fore-in-dark:#fff;--color-focus:#bcdcff;--color-link:#2b47a2;--color-link-hover:#144ce1;--color-link-visited:#6328a4;--color-link-active:#144ce1;--color-placeholder:#64758b;--color-border:#ebedf3;--color-border-strong:#d2d6e5;--color-border-light:#eff1f3;--color-black-rgb:0,0,0;--color-white-rgb:255,255,255;--color-canvas-rgb:255,255,255;--color-canvas-light-rgb:255,255,255;--color-canvas-dark-rgb:252,253,254;--color-inverse-rgb:0,0,0;--color-surface-rgb:239,241,243;--color-surface-light-rgb:252,253,254;--color-surface-strong-rgb:235,237,243;--color-fore-rgb:48,57,74;--color-fore-in-light-rgb:48,57,74;--color-fore-in-dark-rgb:255,255,255;--color-focus-rgb:188,220,255;--color-link-rgb:43,71,162;--color-link-hover-rgb:20,76,225;--color-link-visited-rgb:99,40,164;--color-link-active-rgb:20,76,225;--color-placeholder-rgb:100,117,139;--color-border-rgb:235,237,243;--color-border-strong-rgb:210,214,229;--color-border-light-rgb:239,241,243}body{--btn-bg:var(--color-gray-50)}@media (prefers-color-scheme:dark){.dark-auto{--color-gray-50:#0b0f18;--color-gray-100:#30394a;--color-gray-200:#353d57;--color-gray-300:#3d4667;--color-gray-400:#4a577f;--color-gray-500:#64758b;--color-gray-600:#b2b9c5;--color-gray-700:#d2d6e5;--color-gray-800:#ebedf3;--color-gray-900:#eff1f3;--color-gray-950:#fcfdfe;--color-gray-50-rgb:11,15,24;--color-gray-100-rgb:48,57,74;--color-gray-200-rgb:53,61,87;--color-gray-300-rgb:61,70,103;--color-gray-400-rgb:74,87,127;--color-gray-500-rgb:100,117,139;--color-gray-600-rgb:178,185,197;--color-gray-700-rgb:210,214,229;--color-gray-800-rgb:235,237,243;--color-gray-900-rgb:239,241,243;--color-gray-950-rgb:252,253,254;--color-primary-50:#142457;--color-primary-100:#19388f;--color-primary-200:#173db6;--color-primary-300:#144ce1;--color-primary-400:#2b67e5;--color-primary-500:#3883fa;--color-primary-600:#59a5ff;--color-primary-700:#8ec6ff;--color-primary-800:#bcdcff;--color-primary-900:#d9eaff;--color-primary-950:#eef6ff;--color-primary-50-rgb:20,36,87;--color-primary-100-rgb:25,56,143;--color-primary-200-rgb:23,61,182;--color-primary-300-rgb:20,76,225;--color-primary-400-rgb:43,103,229;--color-primary-500-rgb:56,131,250;--color-primary-600-rgb:89,165,255;--color-primary-700-rgb:142,198,255;--color-primary-800-rgb:188,220,255;--color-primary-900-rgb:217,234,255;--color-primary-950-rgb:238,246,255;--color-secondary-50:#062a4b;--color-secondary-100:#046bab;--color-secondary-200:#078ada;--color-secondary-300:#1099ed;--color-secondary-400:#18a6fd;--color-secondary-500:#37b2fe;--color-secondary-600:#60c2ff;--color-secondary-700:#77cbff;--color-secondary-800:#9bd9ff;--color-secondary-900:#cdecff;--color-secondary-950:#e7f6ff;--color-secondary-50-rgb:6,42,75;--color-secondary-100-rgb:4,107,171;--color-secondary-200-rgb:7,138,218;--color-secondary-300-rgb:16,153,237;--color-secondary-400-rgb:24,166,253;--color-secondary-500-rgb:55,178,254;--color-secondary-600-rgb:96,194,255;--color-secondary-700-rgb:119,203,255;--color-secondary-800-rgb:155,217,255;--color-secondary-900-rgb:205,236,255;--color-secondary-950-rgb:231,246,255;--color-success-50:#0e3421;--color-success-100:#185e3b;--color-success-200:#21805a;--color-success-300:#28996c;--color-success-400:#2ba675;--color-success-500:#31bd85;--color-success-600:#5aca9d;--color-success-700:#83d7b6;--color-success-800:#ade5ce;--color-success-900:#d6f2e7;--color-success-950:#effaf6;--color-success-50-rgb:14,52,33;--color-success-100-rgb:24,94,59;--color-success-200-rgb:33,128,90;--color-success-300-rgb:40,153,108;--color-success-400-rgb:43,166,117;--color-success-500-rgb:49,189,133;--color-success-600-rgb:90,202,157;--color-success-700-rgb:131,215,182;--color-success-800-rgb:173,229,206;--color-success-900-rgb:214,242,231;--color-success-950-rgb:239,250,246;--color-warning-50:#441506;--color-warning-100:#af5f01;--color-warning-200:#d17100;--color-warning-300:#ed8307;--color-warning-400:#f38f19;--color-warning-500:#ff9f46;--color-warning-600:#ffaf65;--color-warning-700:#ffbc7e;--color-warning-800:#ffd2a9;--color-warning-900:#ffecdb;--color-warning-950:#fff4ea;--color-warning-50-rgb:68,21,6;--color-warning-100-rgb:175,95,1;--color-warning-200-rgb:209,113,0;--color-warning-300-rgb:237,131,7;--color-warning-400-rgb:243,143,25;--color-warning-500-rgb:255,159,70;--color-warning-600-rgb:255,175,101;--color-warning-700-rgb:255,188,126;--color-warning-800-rgb:255,210,169;--color-warning-900-rgb:255,236,219;--color-warning-950-rgb:255,244,234;--color-danger-50:#470808;--color-danger-100:#a20606;--color-danger-200:#ba1313;--color-danger-300:#d91b1b;--color-danger-400:#fb2b2b;--color-danger-500:#fc5959;--color-danger-600:#ff7c7c;--color-danger-700:#ff9292;--color-danger-800:#ffb1b1;--color-danger-900:#ffd5d5;--color-danger-950:#ffebeb;--color-danger-50-rgb:71,8,8;--color-danger-100-rgb:162,6,6;--color-danger-200-rgb:186,19,19;--color-danger-300-rgb:217,27,27;--color-danger-400-rgb:251,43,43;--color-danger-500-rgb:252,89,89;--color-danger-600-rgb:255,124,124;--color-danger-700-rgb:255,146,146;--color-danger-800-rgb:255,177,177;--color-danger-900-rgb:255,213,213;--color-danger-950-rgb:255,235,235;--color-important-50:#440609;--color-important-100:#611700;--color-important-200:#c83509;--color-important-300:#ff4912;--color-important-400:#ff6f42;--color-important-500:#ff8058;--color-important-600:#ff8c68;--color-important-700:#ffb29b;--color-important-800:#ffcebf;--color-important-900:#ffe2d9;--color-important-950:#fff8f5;--color-important-50-rgb:68,6,9;--color-important-100-rgb:97,23,0;--color-important-200-rgb:200,53,9;--color-important-300-rgb:255,73,18;--color-important-400-rgb:255,111,66;--color-important-500-rgb:255,128,88;--color-important-600-rgb:255,140,104;--color-important-700-rgb:255,178,155;--color-important-800-rgb:255,206,191;--color-important-900-rgb:255,226,217;--color-important-950-rgb:255,248,245;--color-special-50:#271560;--color-special-100:#30216e;--color-special-200:#452da5;--color-special-300:#513baa;--color-special-400:#7055df;--color-special-500:#8166ee;--color-special-600:#8a6ff5;--color-special-700:#a38cff;--color-special-800:#c4b6ff;--color-special-900:#e4dff7;--color-special-950:#efecfa;--color-special-50-rgb:39,21,96;--color-special-100-rgb:48,33,110;--color-special-200-rgb:69,45,165;--color-special-300-rgb:81,59,170;--color-special-400-rgb:112,85,223;--color-special-500-rgb:129,102,238;--color-special-600-rgb:138,111,245;--color-special-700-rgb:163,140,255;--color-special-800-rgb:196,182,255;--color-special-900-rgb:228,223,247;--color-special-950-rgb:239,236,250;--color-canvas:#0b0f18;--color-inverse:#fff;--color-surface:#353d57;--color-surface-light:#30394a;--color-surface-strong:#3d4667;--color-fore:#ebedf3;--color-focus:#173db6;--color-link:#59a5ff;--color-link-hover:#3883fa;--color-link-visited:#bcdcff;--color-link-active:#bcdcff;--color-placeholder:#4a577f;--color-border:#353d57;--color-border-strong:#3d4667;--color-border-light:#30394a;--color-canvas-rgb:11,15,24;--color-inverse-rgb:255,255,255;--color-surface-rgb:53,61,87;--color-surface-light-rgb:48,57,74;--color-surface-strong-rgb:61,70,103;--color-fore-rgb:235,237,243;--color-focus-rgb:23,61,182;--color-link-rgb:89,165,255;--color-link-hover-rgb:56,131,250;--color-link-visited-rgb:188,220,255;--color-link-active-rgb:188,220,255;--color-placeholder-rgb:74,87,127;--color-border-rgb:53,61,87;--color-border-strong-rgb:61,70,103;--color-border-light-rgb:48,57,74}}*,:after,:before{--tw-border-opacity:1;border-color:rgba(var(--color-border-rgb),var(--tw-border-opacity,1))}:focus-visible{outline-color:transparent}html{font-size:var(--font-size-root)}body{--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1));font-size:.8125rem;line-height:1.5384615385}.dark,body{--tw-text-opacity:1;color:rgba(var(--color-fore-rgb),var(--tw-text-opacity,1))}:root{--font-h1-size:2.25rem;--article-p-space:0.5em;--article-heading-space:0.5em;--article-hr-space:1.5em;--article-cell-padding:0.25rem 0.75rem}a,a.disabled:hover{--tw-text-opacity:1;color:rgba(var(--color-link-rgb),var(--tw-text-opacity,1))}a:hover{--tw-text-opacity:1;color:rgba(var(--color-link-hover-rgb),var(--tw-text-opacity,1))}a:focus-visible{outline-color:rgb(var(--color-focus-rgb));outline-offset:2px;outline-width:2px}.code,code{background-color:rgba(var(--color-important-500-rgb),.1);border-radius:var(--radius);padding-left:.25rem;padding-right:.25rem;--tw-text-opacity:1;color:rgba(var(--color-important-500-rgb),var(--tw-text-opacity,1))}pre{font-size:.75rem;line-height:1rem;overflow:auto;padding:.5rem}pre code{background-color:transparent;color:inherit;padding:0}samp,var{font-weight:700}.blockquote,blockquote{border-left-width:4px;font-size:.875rem;line-height:1.3rem;padding-left:.75rem;text-wrap:pretty}.blockquote figcaption,blockquote figcaption{font-size:.75rem;line-height:1rem;--tw-text-opacity:1;color:rgba(var(--color-gray-500-rgb),var(--tw-text-opacity,1))}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-weight:700;line-height:1.5;text-wrap:balance}.h1,h1{font-size:1.75rem}.h2,h2{font-size:1.5rem}.h3,h3{font-size:1.25rem}.h4,h4{font-size:1rem}.h5,h5{font-size:.875rem}.h6,h6{font-size:.75rem}ul{list-style-type:disc}ol,ul{padding-left:1.5em}ol{list-style-type:decimal}dt{font-weight:700}dd{padding-left:2em}.article{color:var(--font-size-article);-webkit-hyphens:auto;hyphens:auto;overflow-wrap:break-word;white-space:pre-wrap}.article h1,.article h2,.article h3,.article h4{margin-bottom:var(--article-heading-space);margin-top:var(--article-heading-space)}.article audio,.article blockquote,.article figure,.article img,.article ol,.article p,.article table,.article ul,.article video{margin-bottom:var(--article-p-space);margin-top:var(--article-p-space);text-wrap:pretty}.article p{min-height:1em}.article p:empty:before{content:" ";display:inline-block}.article hr{margin-bottom:var(--article-hr-space);margin-top:var(--article-hr-space)}.article table{border-width:1px}.article td,.article th{border-bottom-width:1px;padding:var(--article-cell-padding)}.article thead{background-color:var(--table-head-bg,var(--color-gray-100))}.article ol *,.article table *,.article ul *{margin-bottom:0;margin-top:0}.article pre{border-radius:var(--radius);border-width:1px;--tw-bg-opacity:1;background-color:rgba(var(--color-gray-50-rgb),var(--tw-bg-opacity,1))}:root{--alert-bg:var(--color-surface)}.alert{align-items:center;background-color:var(--alert-bg);border-radius:var(--radius);display:flex;gap:.75rem;padding:.5rem .75rem}.alert-content{display:flex;flex:1 1 auto;flex-direction:column;gap:1rem}.alert-close{margin-bottom:-.375rem;margin-right:-.5rem;margin-top:-.375rem}.alert-link{color:inherit;font-weight:700}.alert-link:hover{color:inherit;text-decoration-line:underline}.alert-heading{font-weight:700;margin:0}.alert-text{flex:1 1 auto;white-space:pre-line}.alert-actions{align-items:center;display:flex;gap:.5rem}:root{--breadcrumb-divider:"/";--breadcrumb-divider-color:var(--color-gray-500);--breadcrumb-color-active:var(--color-gray-500)}.breadcrumb{display:flex;gap:1.25rem;list-style-type:none;padding-left:0}.breadcrumb>li{position:relative}.breadcrumb>li+li:before{color:var(--breadcrumb-divider-color);content:var(--breadcrumb-divider);display:block;left:-1.25rem;position:absolute;text-align:center;width:1.25rem}.breadcrumb>.active{color:var(--breadcrumb-color-active)}:root{--btn-radius:var(--radius);--btn-bg:var(--color-surface);--btn-border-color:var(--color-gray-300);--btn-height:2rem}.btn{align-items:center;background-color:var(--btn-bg);border-radius:var(--btn-radius);display:inline-flex;gap:.375rem;height:var(--btn-height);justify-content:center;padding-left:.75rem;padding-right:.75rem;white-space:nowrap;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:var(--btn-border-color)}.btn,.btn-default:hover{color:inherit}.btn-link{--tw-text-opacity:1;color:rgba(var(--color-link-rgb),var(--tw-text-opacity,1));text-decoration-line:underline;text-underline-offset:2px;--tw-ring-color:transparent}.btn-link:visited{color:rgba(var(--color-link-visited-rgb),var(--tw-text-opacity,1))}.btn-link:hover{--tw-text-opacity:1;color:rgba(var(--color-link-hover-rgb),var(--tw-text-opacity,1))}.btn-link{--btn-bg:transparent}.btn.size-xs,.size-xs>.btn{padding-left:.25rem;padding-right:.25rem;--btn-height:1.25rem}.btn.size-sm,.btn.size-xs,.size-sm>.btn,.size-xs>.btn{font-size:.75rem;line-height:1rem}.btn.size-sm,.size-sm>.btn{--btn-height:1.5rem}.btn.size-md,.btn.size-sm,.size-md>.btn,.size-sm>.btn{padding-left:.5rem;padding-right:.5rem}.btn.size-md,.size-md>.btn{--btn-height:1.75rem}.btn.size-lg,.size-lg>.btn{font-size:1rem;line-height:1.5rem;padding-left:1rem;padding-right:1rem;--btn-height:2.5rem}.btn.size-xl,.size-xl>.btn{font-size:1.125rem;line-height:1.75rem;padding-left:1.25rem;padding-right:1.25rem;--btn-height:3rem}.btn.square{aspect-ratio:1/1;gap:.125rem;padding-left:0;padding-right:0}@supports not (aspect-ratio:1/1){.btn.square{width:var(--btn-height)}}.btn.btn-caret{padding-left:.25rem;padding-right:.25rem}.btn.btn-wide{min-width:80px}:root{--checkbox-size:12px;--checkbox-color:var(--color-primary-500)}.checkbox,.radio{align-items:center;cursor:pointer;display:flex;gap:.375rem;min-height:20px}.checkbox>input[type=checkbox],.radio>input[type=radio]{accent-color:rgb(var(--color-primary-500-rgb));border-radius:var(--radius-lg)}.checkbox-primary,.radio-primary{display:flex;gap:.375rem;min-height:20px;position:relative}.checkbox-primary>input[type=checkbox],.radio-primary>input[type=radio]{bottom:0;left:0;opacity:0;position:absolute;right:0;top:0}.checkbox-primary>label,.radio-primary>label{cursor:pointer;padding-left:calc(var(--checkbox-size) + 8px);position:relative}.checkbox-primary>label:after,.checkbox-primary>label:before,.radio-primary>label:after,.radio-primary>label:before{display:block;height:var(--checkbox-size);left:0;position:absolute;transition-duration:.15s;transition-property:transform,background-color,color,opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);width:var(--checkbox-size);--tw-content:"";content:var(--tw-content);top:calc((20px - var(--checkbox-size))/2)}.checkbox-primary>label:before{border-radius:var(--radius-sm);border-width:1px;--tw-border-opacity:1;border-color:rgba(var(--color-gray-400-rgb),var(--tw-border-opacity,1));--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1))}.checkbox-primary>label:after{--tw-scale-x:.9;--tw-scale-y:.9;background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHBhdGggZmlsbD0iI2ZmZiIgZD0ibTkgMjAuNDItNi4yMS02LjIxIDIuODMtMi44M0w5IDE0Ljc3bDkuODgtOS44OSAyLjgzIDIuODN6Ii8+PC9zdmc+");transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.radio-primary>label:before{border-radius:var(--radius-full);border-width:1px;--tw-border-opacity:1;border-color:rgba(var(--color-gray-400-rgb),var(--tw-border-opacity,1))}.radio-primary>label:after{background-color:var(--checkbox-color);border-radius:var(--radius-full);opacity:0;--checkbox-radio-size:calc(var(--checkbox-size)*2/3);height:var(--checkbox-radio-size);left:calc((var(--checkbox-size) - var(--checkbox-radio-size))/2);top:calc((20px - var(--checkbox-radio-size))/2);width:var(--checkbox-radio-size)}.checkbox-primary>label:hover:before,.radio-primary>label:hover:before{border-color:var(--checkbox-color)}.checkbox-primary.focus>label:before,.checkbox-primary>input[type=checkbox]:focus+label:before,.radio-primary.focus>label:before,.radio-primary>input[type=radio]:focus+label:before{border-color:var(--checkbox-color);outline-color:rgb(var(--color-focus-rgb));outline-style:solid;outline-width:2px}.checkbox-primary.checked>label:before,.checkbox-primary>input[type=checkbox]:checked+label:before{background-color:var(--checkbox-color);border-color:var(--checkbox-color)}.radio-primary.checked>label:before,.radio-primary>input[type=radio]:checked+label:before{border-color:var(--checkbox-color)}.checkbox-primary.checked>label:after,.checkbox-primary>input[type=checkbox]:checked+label:after,.radio-primary.checked>label:after,.radio-primary>input[type=radio]:checked+label:after{opacity:1}.checkbox-primary.disabled>label,.checkbox-primary>input[type=checkbox]:disabled+label,.radio-primary.disabled>label,.radio-primary>input[type=radio]:disabled+label{cursor:not-allowed;opacity:.7;pointer-events:none;--tw-grayscale:grayscale(100%);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.checkbox-primary.indeterminate>label:after,.checkbox-primary>input[type=checkbox]:indeterminate+label:after{--tw-border-opacity:1;background-color:var(--checkbox-color);background-image:none;border-color:rgba(var(--color-canvas-rgb),var(--tw-border-opacity,1));border-width:calc((var(--checkbox-size) - 2px)/2) 2px;opacity:1}.check-list{align-items:flex-start;flex-direction:column;gap:.5rem}.check-list,.check-list-inline{display:flex;padding-bottom:.375rem;padding-top:.375rem}.check-list-inline{align-items:center;-moz-column-gap:1rem;column-gap:1rem;flex-direction:row;flex-wrap:wrap;row-gap:.5rem}.switch{display:flex;gap:.375rem;min-height:20px;padding-left:2.5rem;position:relative}.switch>input{bottom:0;left:0;opacity:0;position:absolute;right:0;top:0}.switch>label:after,.switch>label:before{border-radius:var(--radius-full);border-width:1px;height:1rem;left:0;position:absolute;top:.125rem;width:2rem;--tw-border-opacity:1;border-color:rgba(var(--color-border-strong-rgb),var(--tw-border-opacity,1));--tw-bg-opacity:1;background-color:rgba(var(--color-surface-rgb),var(--tw-bg-opacity,1));transition-duration:.3s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);--tw-content:"";content:var(--tw-content)}.switch>label:before{cursor:pointer;--tw-shadow:inset 0 2px 4px 0 rgba(0,0,0,.05);--tw-shadow-colored:inset 0 2px 4px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.switch>label:hover:before{--tw-border-opacity:1;border-color:rgba(var(--color-border-rgb),var(--tw-border-opacity,1))}.switch>label:after{height:.75rem;left:.125rem;top:.25rem;width:.75rem;--tw-border-opacity:1;border-color:rgba(var(--color-canvas-rgb),var(--tw-border-opacity,1));--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1));--tw-shadow:0 3px 8px 0 rgba(0,0,0,.04),0 1px 2px -1px rgba(0,0,0,.01);--tw-shadow-colored:0 3px 8px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.switch>input:checked+label:before{background-color:var(--checkbox-color);border-color:rgba(var(--color-inverse-rgb),.2)}.switch>input:checked+label:after{color:var(--checkbox-color);left:18px}.switch.focus>label:before,.switch>input:focus+label:before{border-color:var(--checkbox-color);outline-color:rgb(var(--color-focus-rgb));outline-style:solid;outline-width:2px}.switch.disabled>label:before,.switch>input:disabled+label:before{cursor:not-allowed;opacity:.7;pointer-events:none;--tw-grayscale:grayscale(100%);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}:root{--checkbox-size:12px;--checkbox-color:var(--color-primary-500)}.checkbox,.radio{align-items:center;cursor:pointer;display:flex;gap:.375rem;min-height:20px}.checkbox>input[type=checkbox],.radio>input[type=radio]{accent-color:rgb(var(--color-primary-500-rgb));border-radius:var(--radius-lg)}.checkbox-primary,.radio-primary{display:flex;gap:.375rem;min-height:20px;position:relative}.checkbox-primary>input[type=checkbox],.radio-primary>input[type=radio]{bottom:0;left:0;opacity:0;position:absolute;right:0;top:0}.checkbox-primary>label,.radio-primary>label{cursor:pointer;padding-left:calc(var(--checkbox-size) + 8px);position:relative}.checkbox-primary>label:after,.checkbox-primary>label:before,.radio-primary>label:after,.radio-primary>label:before{display:block;height:var(--checkbox-size);left:0;position:absolute;transition-duration:.15s;transition-property:transform,background-color,color,opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);width:var(--checkbox-size);--tw-content:"";content:var(--tw-content);top:calc((20px - var(--checkbox-size))/2)}.checkbox-primary>label:before{border-radius:var(--radius-sm);border-width:1px;--tw-border-opacity:1;border-color:rgba(var(--color-gray-400-rgb),var(--tw-border-opacity,1));--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1))}.checkbox-primary>label:after{--tw-scale-x:.9;--tw-scale-y:.9;background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHBhdGggZmlsbD0iI2ZmZiIgZD0ibTkgMjAuNDItNi4yMS02LjIxIDIuODMtMi44M0w5IDE0Ljc3bDkuODgtOS44OSAyLjgzIDIuODN6Ii8+PC9zdmc+");transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.radio-primary>label:before{border-radius:var(--radius-full);border-width:1px;--tw-border-opacity:1;border-color:rgba(var(--color-gray-400-rgb),var(--tw-border-opacity,1))}.radio-primary>label:after{background-color:var(--checkbox-color);border-radius:var(--radius-full);opacity:0;--checkbox-radio-size:calc(var(--checkbox-size)*2/3);height:var(--checkbox-radio-size);left:calc((var(--checkbox-size) - var(--checkbox-radio-size))/2);top:calc((20px - var(--checkbox-radio-size))/2);width:var(--checkbox-radio-size)}.checkbox-primary>label:hover:before,.radio-primary>label:hover:before{border-color:var(--checkbox-color)}.checkbox-primary.focus>label:before,.checkbox-primary>input[type=checkbox]:focus+label:before,.radio-primary.focus>label:before,.radio-primary>input[type=radio]:focus+label:before{border-color:var(--checkbox-color);outline-color:rgb(var(--color-focus-rgb));outline-style:solid;outline-width:2px}.checkbox-primary.checked>label:before,.checkbox-primary>input[type=checkbox]:checked+label:before{background-color:var(--checkbox-color);border-color:var(--checkbox-color)}.radio-primary.checked>label:before,.radio-primary>input[type=radio]:checked+label:before{border-color:var(--checkbox-color)}.checkbox-primary.checked>label:after,.checkbox-primary>input[type=checkbox]:checked+label:after,.radio-primary.checked>label:after,.radio-primary>input[type=radio]:checked+label:after{opacity:1}.checkbox-primary.disabled>label,.checkbox-primary>input[type=checkbox]:disabled+label,.radio-primary.disabled>label,.radio-primary>input[type=radio]:disabled+label{cursor:not-allowed;opacity:.7;pointer-events:none;--tw-grayscale:grayscale(100%);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.checkbox-primary.indeterminate>label:after,.checkbox-primary>input[type=checkbox]:indeterminate+label:after{--tw-border-opacity:1;background-color:var(--checkbox-color);background-image:none;border-color:rgba(var(--color-canvas-rgb),var(--tw-border-opacity,1));border-width:calc((var(--checkbox-size) - 2px)/2) 2px;opacity:1}.check-list{align-items:flex-start;flex-direction:column;gap:.5rem}.check-list,.check-list-inline{display:flex;padding-bottom:.375rem;padding-top:.375rem}.check-list-inline{align-items:center;-moz-column-gap:1rem;column-gap:1rem;flex-direction:row;flex-wrap:wrap;row-gap:.5rem}.switch{display:flex;gap:.375rem;min-height:20px;padding-left:2.5rem;position:relative}.switch>input{bottom:0;left:0;opacity:0;position:absolute;right:0;top:0}.switch>label:after,.switch>label:before{border-radius:var(--radius-full);border-width:1px;height:1rem;left:0;position:absolute;top:.125rem;width:2rem;--tw-border-opacity:1;border-color:rgba(var(--color-border-strong-rgb),var(--tw-border-opacity,1));--tw-bg-opacity:1;background-color:rgba(var(--color-surface-rgb),var(--tw-bg-opacity,1));transition-duration:.3s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);--tw-content:"";content:var(--tw-content)}.switch>label:before{cursor:pointer;--tw-shadow:inset 0 2px 4px 0 rgba(0,0,0,.05);--tw-shadow-colored:inset 0 2px 4px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.switch>label:hover:before{--tw-border-opacity:1;border-color:rgba(var(--color-border-rgb),var(--tw-border-opacity,1))}.switch>label:after{height:.75rem;left:.125rem;top:.25rem;width:.75rem;--tw-border-opacity:1;border-color:rgba(var(--color-canvas-rgb),var(--tw-border-opacity,1));--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1));--tw-shadow:0 3px 8px 0 rgba(0,0,0,.04),0 1px 2px -1px rgba(0,0,0,.01);--tw-shadow-colored:0 3px 8px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.switch>input:checked+label:before{background-color:var(--checkbox-color);border-color:rgba(var(--color-inverse-rgb),.2)}.switch>input:checked+label:after{color:var(--checkbox-color);left:18px}.switch.focus>label:before,.switch>input:focus+label:before{border-color:var(--checkbox-color);outline-color:rgb(var(--color-focus-rgb));outline-style:solid;outline-width:2px}.switch.disabled>label:before,.switch>input:disabled+label:before{cursor:not-allowed;opacity:.7;pointer-events:none;--tw-grayscale:grayscale(100%);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}:root{--form-control-radius:var(--radius);--form-control-border:var(--color-border);--form-control-focus:var(--color-primary-500);--form-control-disabled:var(--color-surface);--form-control-readonly:var(--color-surface)}.dark{--form-control-border:var(--color-border-strong)}input::-moz-placeholder,textarea::-moz-placeholder{--tw-placeholder-opacity:1;color:rgba(var(--color-placeholder-rgb),var(--tw-placeholder-opacity,1))}input::placeholder,textarea::placeholder{--tw-placeholder-opacity:1;color:rgba(var(--color-placeholder-rgb),var(--tw-placeholder-opacity,1))}.form-control{border-radius:var(--form-control-radius);display:block;height:2rem;width:100%;--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1));outline-color:transparent;outline-style:solid;outline-width:1px;padding:.25rem .5rem;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:var(--form-control-border);transition-duration:.15s;transition-property:outline,box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1)}.form-control.focus,.form-control:focus{outline-color:var(--form-control-focus);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:rgba(var(--color-focus-rgb),var(--tw-ring-opacity,1));--tw-ring-opacity:0.3}.form-control.disabled,.form-control[disabled]{background-color:var(--form-control-disabled);opacity:1}.form-control.readonly,.form-control[readonly]{background-color:var(--form-control-readonly)}select{-webkit-appearance:none;background-image:url("data:image/gif;base64,R0lGODlhBwAEAIAAAMvQ2////yH5BAEAAAEALAAAAAAHAAQAAAIIhA+BGWoNWSgAOw==");background-position:right 8px top 50%;background-repeat:no-repeat;background-size:8px auto;padding-right:1rem}select.form-control[multiple]{background-image:none}textarea.form-control{height:auto;min-height:32px}input[type=file].form-control{padding:.125rem}input[type=file].form-control::-webkit-file-upload-button{-webkit-appearance:none;appearance:none;border-radius:inherit;border-style:none;cursor:pointer;height:1.75rem;padding-left:.5rem;padding-right:.5rem}input[type=file].form-control::-webkit-file-upload-button:hover{background-color:rgba(var(--color-black-rgb),.1)}.has-error .form-control,.has-error.form-control{--tw-ring-color:rgba(var(--color-danger-500-rgb),0.6)}.has-error .form-control.focus,.has-error .form-control:focus,.has-error.form-control.focus,.has-error.form-control:focus{outline-color:rgb(var(--color-danger-500-rgb));--tw-ring-color:rgba(var(--color-danger-500-rgb),0.1)}.has-warning .form-control,.has-warning.form-control{--tw-ring-color:rgba(var(--color-warning-500-rgb),0.6)}.has-warning .form-control.focus,.has-warning .form-control:focus,.has-warning.form-control.focus,.has-warning.form-control:focus{outline-color:rgb(var(--color-warning-500-rgb));--tw-ring-color:rgba(var(--color-warning-500-rgb),0.2)}.has-success .form-control,.has-success.form-control{--tw-ring-color:rgba(var(--color-success-500-rgb),0.6)}.has-success .form-control.focus,.has-success .form-control:focus,.has-success.form-control.focus,.has-success.form-control:focus{outline-color:rgb(var(--color-success-500-rgb));--tw-ring-color:rgba(var(--color-success-500-rgb),0.2)}.form-control.size-sm,.size-sm>.form-control{font-size:.75rem;height:1.5rem;line-height:1rem;padding-left:.5rem;padding-right:.5rem}.form-control.size-md,.size-md>.form-control{height:1.75rem;padding-left:.5rem;padding-right:.5rem}.form-control.size-lg,.size-lg>.form-control{font-size:1rem;height:2.5rem;line-height:1.5rem;padding-left:.75rem;padding-right:.75rem}:root{--input-group-addon-bg:var(--color-gray-50)}.input-group{align-items:stretch;display:flex}.input-group>.form-control,.input-group>.input-control{flex:1 1 auto;z-index:1}.input-group-addon{align-items:center;background-color:var(--input-group-addon-bg);border-radius:var(--form-control-radius);display:flex;flex:none;height:2rem;padding-left:.5rem;padding-right:.5rem;z-index:0;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:var(--form-control-border)}.size-sm>.input-group-addon{font-size:.75rem;height:1.5rem;line-height:1rem;padding-left:.5rem;padding-right:.5rem}.size-lg>.input-group-addon{font-size:1rem;height:2.5rem;line-height:1.5rem;padding-left:.75rem;padding-right:.75rem}.input-group-control{flex:1 1 auto}.input-group>*+*,.input-group>*+* .form-control{border-bottom-left-radius:var(--radius-none);border-top-left-radius:var(--radius-none)}.input-group>:not(:last-child),.input-group>:not(:last-child) .form-control{border-bottom-right-radius:var(--radius-none);border-top-right-radius:var(--radius-none)}.input-group .btn:focus-visible,.input-group .form-control:focus{z-index:2}:root{--form-tip-color:var(--color-gray-400);--form-label-color:var(--color-gray-700);--form-horz-label-width:6rem;--form-grid-gap-x:1.25rem;--form-grid-gap-y:.75rem}.form{flex-direction:column;gap:1rem}.form,.form-label{display:flex}.form-label{align-items:center;color:var(--form-label-color);flex-direction:row;gap:.25rem;height:2rem;overflow:hidden;position:relative;text-overflow:ellipsis;white-space:nowrap}.form-label.required:after{content:"*";display:inline-block;margin-left:.25rem;--tw-translate-y:0.125rem;--tw-scale-x:1.25;--tw-scale-y:1.25;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-text-opacity:1;color:rgba(var(--color-danger-500-rgb),var(--tw-text-opacity,1))}.no-required .form-label.required:after{display:none}.form-label-actions{flex:1 1 auto;justify-content:flex-end}.form-label>.checkbox-primary{margin-left:.75rem}.form-tip{color:var(--form-tip-color);display:block;margin-top:.25rem}.has-error .form-tip{--tw-text-opacity:1;color:rgba(var(--color-danger-500-rgb),var(--tw-text-opacity,1))}.has-warning .form-tip{--tw-text-opacity:1;color:rgba(var(--color-warning-500-rgb),var(--tw-text-opacity,1))}.has-success .form-tip{--tw-text-opacity:1;color:rgba(var(--color-success-500-rgb),var(--tw-text-opacity,1))}.form-actions{display:flex;flex-direction:row;gap:1rem;justify-content:center}.form-grid{--form-grid-gap-x-half:calc(var(--form-grid-gap-x)/2);--form-grid-gap-y-half:calc(var(--form-grid-gap-y)/2);align-items:flex-start;flex-direction:row;flex-wrap:wrap;gap:0}.form-grid .form-group{padding:var(--form-grid-gap-y-half) var(--form-grid-gap-x-half)}.form-grid .form-label.required:after{margin-left:.25rem;order:-9999}.form-grid .form-label .checkbox{margin-left:.75rem;margin-right:.75rem}.form-grid .has-wrap-after:after{display:block;width:100%;--tw-content:"";content:var(--tw-content)}.form-grid-wrap{width:100%}.form-grid-row{display:flex;flex-direction:row;padding-bottom:var(--form-grid-gap-y-half);padding-top:var(--form-grid-gap-y-half);position:relative;width:100%}.form-grid-col{padding-left:var(--form-grid-gap-x-half);padding-right:var(--form-grid-gap-x-half)}.form-grid .form-actions{gap:1.5rem;justify-content:center;padding:var(--form-grid-gap-y) var(--form-grid-gap-x-half);width:100%}.form-grid .form-actions.is-pinned{border-top-width:1px}.form-horz .form-row{align-items:flex-start;display:flex;flex-direction:row}.form-horz .form-group{align-items:flex-start;display:flex;flex:none;flex-direction:row;flex-wrap:wrap;min-height:32px;min-width:0;padding-left:var(--form-horz-label-width);position:relative}.form-horz .form-row .form-group{flex:1 1 auto}.form-horz .form-group[class*=" w-"],.form-horz .form-group[class^=w-]{flex:none}.form-horz .form-group>*{min-width:0}.form-horz .form-group.no-label{padding-left:0}.form-horz .form-group.no-label>.check-list-inline{padding-left:1rem;padding-right:1rem}.form-horz .form-label{justify-content:flex-end;left:0;padding-left:1rem;padding-right:.5rem;position:absolute;top:0;width:var(--form-horz-label-width)}.form-horz .form-label.required:after{margin-left:0;order:-9999}.form-horz .form-tip{width:100%}.form-horz .form-tip,.form-horz .input-control,.form-horz .input-group{flex:1 1 auto}.form .form-group-wrapper,.form-horz .form-group-wrapper{flex:1 1 auto;min-width:0;width:100%;z-index:1}.form .form-group-wrapper.flex-none,.form-horz .form-group-wrapper.flex-none{flex:none}.form fieldset>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.5rem*var(--tw-space-y-reverse));margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)))}.form fieldset{padding-bottom:1rem;padding-left:1rem}.form-grid fieldset>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1rem*var(--tw-space-y-reverse));margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)))}.form legend{border-bottom-width:1px;display:flex;justify-content:flex-start;margin-left:-1rem;width:100%;--tw-border-opacity:1;border-bottom-color:rgba(var(--color-primary-100-rgb),var(--tw-border-opacity,1));width:calc(100% + 1rem)}.form-title{align-items:center;background-color:rgba(var(--color-primary-50-rgb),.5);display:flex;font-weight:700;height:1.75rem;padding-left:.75rem;padding-right:.75rem}:root{--input-control-fix-width-sm:2rem;--input-control-fix-width:4.375rem;--input-control-fix-width-lg:6.75rem}.input-control{position:relative;--input-control-prefix:8px;--input-control-suffix:8px}.input-control-prefix,.input-control-suffix{align-items:center;display:flex;height:100%;left:0;opacity:.5;padding-left:.5rem;padding-right:.5rem;position:absolute;top:0;white-space:nowrap;width:var(--input-control-prefix);z-index:1}.input-control-suffix{justify-content:flex-end;left:auto;right:0;width:var(--input-control-suffix)}.form-control:focus+.input-control-prefix,.form-control:focus+.input-control-suffix{opacity:1}.input-control>.form-control{padding-left:var(--input-control-prefix);padding-right:var(--input-control-suffix)}.input-control>select.form-control{background-position-x:calc(100% - var(--input-control-suffix) - 8px);padding-right:calc(var(--input-control-suffix) + 20px)}.has-prefix{--input-control-prefix:var(--input-control-fix-width)}.has-suffix{--input-control-suffix:var(--input-control-fix-width)}.has-prefix-sm{--input-control-prefix:var(--input-control-fix-width-sm)}.has-suffix-sm{--input-control-suffix:var(--input-control-fix-width-sm)}.has-prefix-lg{--input-control-prefix:var(--input-control-fix-width-lg)}.has-suffix-lg{--input-control-suffix:var(--input-control-fix-width-lg)}.has-prefix-icon{--input-control-prefix:32px}.has-suffix-icon{--input-control-suffix:32px}.input-control.has-prefix-icon{--input-control-prefix:32px}.input-control.has-suffix-icon{--input-control-suffix:32px}.input-control.has-prefix-icon>.input-control-prefix,.input-control.has-suffix-icon>.input-control-suffix{justify-content:center;padding:0}.input-control.size-sm>.form-control,.input-control.size-sm>.input-control-prefix,.input-control.size-sm>.input-control-suffix{font-size:.75rem;line-height:1rem}.input-control.size-lg>.form-control,.input-control.size-lg>.input-control-prefix,.input-control.size-lg>.input-control-suffix{font-size:1rem;line-height:1.5rem}:root{--label-bg:rgba(var(--color-canvas-rgb),.1);--label-border-color:var(--color-gray-300);--label-color:var(--color-gray-500);--label-radius:var(--radius)}.label{align-items:center;background-color:var(--label-bg);border-radius:var(--label-radius);color:var(--label-color);display:inline-flex;font-size:.75rem;height:1.25rem;justify-content:center;line-height:1rem;min-width:1.25rem;padding-left:.25rem;padding-right:.25rem;white-space:pre-line;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:var(--label-border-color)}.label.size-lg{font-size:.8125rem;height:1.5rem;line-height:1.25rem;min-width:1.5rem;padding-left:.5rem;padding-right:.5rem}.label.size-sm{height:1rem;min-width:1rem}.label-dot{aspect-ratio:1/1;border-radius:var(--radius-full);height:.5rem;min-width:0;padding-left:0;padding-right:0}.arrow,.arrow:before{background:inherit;height:calc(var(--arrow-size)*1.4142);position:absolute;width:calc(var(--arrow-size)*1.4142)}.arrow{visibility:hidden;--arrow-size:5px}.arrow:before{border:inherit;content:"";visibility:visible;--tw-rotate:45deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.arrow-top,.arrow-up{border-bottom:inherit;border-right:inherit;border-width:1px 0 0 1px;top:calc(1px - var(--arrow-size))}.white>.arrow-top,.white>.arrow-up{top:calc(0px - var(--arrow-size))}.arrow-bottom,.arrow-down{border-left:inherit;border-top:inherit;border-width:0 1px 1px 0;bottom:calc(1px - var(--arrow-size))}.white>.arrow-bottom,.white>.arrow-down{bottom:calc(0px - var(--arrow-size))}.arrow-left{border-right:inherit;border-top:inherit;border-width:0 0 1px 1px;left:calc(1px - var(--arrow-size))}.white>.arrow-left{left:calc(0px - var(--arrow-size))}.arrow-right{border-bottom:inherit;border-left:inherit;border-width:1px 1px 0 0;right:calc(1px - var(--arrow-size))}.white>.arrow-right{right:calc(0px - var(--arrow-size))}.caret,.caret-down,.caret-left,.caret-right,.caret-up{align-items:center;display:inline-flex;height:.75rem;justify-content:center;position:relative;width:.75rem}.caret-down:before,.caret-left:before,.caret-right:before,.caret-up:before,.caret:before{display:block;height:.35rem;transform-origin:center;width:.35rem;--tw-translate-y:-1px;--tw-rotate:45deg;border-color:currentColor;border-width:0 1px 1px 0;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-content:"";content:var(--tw-content)}.caret-left:before{--tw-translate-x:0.125rem;--tw-translate-y:0px;--tw-rotate:135deg}.caret-left:before,.caret-right:before{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.caret-right:before{--tw-translate-x:-0.125rem;--tw-translate-y:0px;--tw-rotate:-45deg}.caret-up:before{--tw-translate-y:0.125rem;--tw-rotate:225deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}:focus>.caret,:hover>.caret{opacity:inherit}.disabled .caret,.readonly .caret{opacity:var(--caret-opacity,.5)}:root{--toggle-icon-size:calc(var(--font-size-root)*3/4 + 1px)}.toggle-icon,.toggle-icon-collapse,.toggle-icon-expand{border-color:currentColor;border-width:1px;display:block;opacity:.5;position:relative}.toggle-icon-collapse:hover,.toggle-icon-expand:hover,.toggle-icon:hover{opacity:.9}.toggle-icon,.toggle-icon-collapse,.toggle-icon-expand{border-radius:inherit;height:var(--toggle-icon-size);width:var(--toggle-icon-size)}.is-collapsed .toggle-icon:after,.is-collapsed .toggle-icon:before,.is-expanded .toggle-icon:before,.toggle-icon-collapse:after,.toggle-icon-collapse:before,.toggle-icon-expand:before{background-color:currentColor;content:" ";display:block;height:1px;left:2px;position:absolute;right:2px;top:calc((var(--toggle-icon-size) - 3px)/2)}.is-collapsed .toggle-icon:after,.toggle-icon-collapse:after{--tw-rotate:90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.close{aspect-ratio:1/1;display:block;position:relative;width:1em}.close:after,.close:before{content:"";display:block;height:1px;left:0;position:absolute;width:100%;--tw-rotate:45deg;background-color:currentColor;border-radius:var(--radius-full);top:calc(50% - .5px)}.close:after,.close:before{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.close:after{--tw-rotate:-45deg}.spinner,.spinner:after,.spinner:before{display:block;height:1em;position:relative;width:1em}.spinner:after,.spinner:before{border-radius:var(--radius-full);content:" ";position:absolute}.spinner:before{animation:-spin 1s cubic-bezier(.6,0,.4,1) infinite;border:.16667em solid transparent;border-top-color:currentcolor}.spinner:after{border:.16667em solid;opacity:.2}.magnifier{display:inline-block;height:1em;position:relative;width:1em}.magnifier:after,.magnifier:before{border-radius:var(--radius-full);content:"";display:block;position:absolute}.magnifier:before{border:1px solid;height:.75em;width:.75em}.magnifier:after{height:1px;left:.55em;top:.7em;width:.5em;--tw-rotate:45deg;background-color:currentColor;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.more,.more-vert{margin:.5rem;position:relative}.more,.more-vert,.more-vert:after,.more-vert:before,.more:after,.more:before{background-color:currentColor;border-radius:var(--radius-full);height:.125rem;width:.125rem}.more-vert:after,.more-vert:before,.more:after,.more:before{display:block;left:-5px;position:absolute;top:0;--tw-content:"";content:var(--tw-content)}.more-vert:after,.more:after{left:5px}.more-vert{--tw-rotate:90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.chevron-down,.chevron-left,.chevron-right,.chevron-up{align-items:center;display:inline-flex;height:1em;justify-content:center;position:relative;width:1em}.chevron-down:before,.chevron-left:before,.chevron-right:before,.chevron-up:before{display:block;height:.6923077em;transform-origin:center;width:.6923077em;--tw-translate-y:-0.125rem;--tw-rotate:45deg;border-color:currentColor;border-width:0 1px 1px 0;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-content:"";content:var(--tw-content)}.chevron-left:before{--tw-translate-y:0px;--tw-translate-x:0.125rem;--tw-rotate:135deg}.chevron-left:before,.chevron-right:before{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.chevron-right:before{--tw-translate-y:0px;--tw-translate-x:-0.125rem;--tw-rotate:-45deg}.chevron-up:before{--tw-translate-y:0.125rem;--tw-rotate:225deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.i-time{border-color:currentColor;border-radius:50%;border-width:.08em;display:inline-block;height:1em;position:relative;width:1em}.i-time:after{border-color:currentColor;border-width:0 0 .08em .08em;height:.385em;left:.3846em;position:absolute;top:.08em;width:.385em;--tw-content:"";content:var(--tw-content)}.i-calendar{border-color:currentColor;border-radius:2px;border-width:.08em;display:inline-block;height:.79em;margin-top:.16em;position:relative;width:1em}.i-calendar:after,.i-calendar:before{border-color:currentColor;border-width:.08em;position:absolute;--tw-content:"";content:var(--tw-content)}.i-calendar:before{border-bottom-width:0;left:.15em;top:.307em;width:.6em}.i-calendar:after{border-bottom-width:0;border-top-width:0;height:.3077em;left:.17em;top:-.154em;width:.538em}.caret,.caret-down,.caret-left,.caret-right,.caret-up{align-items:center;display:inline-flex;height:.75rem;justify-content:center;position:relative;width:.75rem}.caret-down:before,.caret-left:before,.caret-right:before,.caret-up:before,.caret:before{display:block;height:.35rem;transform-origin:center;width:.35rem;--tw-translate-y:-1px;--tw-rotate:45deg;border-color:currentColor;border-width:0 1px 1px 0;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-content:"";content:var(--tw-content)}.caret-left:before{--tw-translate-x:0.125rem;--tw-translate-y:0px;--tw-rotate:135deg}.caret-left:before,.caret-right:before{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.caret-right:before{--tw-translate-x:-0.125rem;--tw-translate-y:0px;--tw-rotate:-45deg}.caret-up:before{--tw-translate-y:0.125rem;--tw-rotate:225deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}:focus>.caret,:hover>.caret{opacity:inherit}.disabled .caret,.readonly .caret{opacity:var(--caret-opacity,.5)}.listitem{align-items:center;border-radius:var(--radius);display:flex;flex-direction:row;flex-wrap:nowrap;gap:.5rem;padding:.25rem}.listitem.selected{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-50-rgb),var(--tw-bg-opacity,1))}.listitem.active{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-500-rgb),var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgba(var(--color-canvas-rgb),var(--tw-text-opacity,1))}.item-actions,.item-avatar,.item-icon,.item-trailing,.item-trailing-icon{flex:none}.item-icon.icon-EMPTY{display:none}.item-subtitle{font-size:.75rem;line-height:1rem;opacity:.8}.item-content,.item-text{flex:1 1 auto;min-width:0}.item-leading,.item-trailing{align-items:center;display:flex;flex:none;gap:.5rem}.item-checkbox{margin-right:-.5rem}.item-content{align-items:center;display:flex;gap:.5rem}.multiline>.item-content{align-items:flex-start;flex-direction:column;gap:.25rem}.list{list-style-type:none;padding-left:0}.list-heading-inner .item-title{font-weight:700;--tw-text-opacity:1;color:rgba(var(--color-gray-500-rgb),var(--tw-text-opacity,1))}.with-hover-actions>.item{position:relative}.with-hover-actions>.item>.item-inner .item-actions{opacity:0;pointer-events:none;position:absolute;right:.25rem;top:0;transition-duration:.15s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1)}.with-hover-actions>.item>.item-inner:hover .item-actions{display:flex;margin-top:-.25rem;opacity:1;pointer-events:auto;position:static}.list.is-nested-sub{padding-left:var(--list-indent)}.is-nested-collapsed{display:none}.nested-toggle-icon{align-items:center;border-radius:var(--radius);display:flex;height:1rem;justify-content:center;margin-right:-.25rem;width:1rem}.magnifier{display:inline-block;height:1em;position:relative;width:1em}.magnifier:after,.magnifier:before{border-radius:var(--radius-full);content:"";display:block;position:absolute}.magnifier:before{border:1px solid;height:.75em;width:.75em}.magnifier:after{height:1px;left:.55em;top:.7em;width:.5em;--tw-rotate:45deg;background-color:currentColor;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.close{aspect-ratio:1/1;display:block;position:relative;width:1em}.close:after,.close:before{content:"";display:block;height:1px;left:0;position:absolute;width:100%;--tw-rotate:45deg;background-color:currentColor;border-radius:var(--radius-full);top:calc(50% - .5px)}.close:after,.close:before{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.close:after{--tw-rotate:-45deg}.search-box.compact.has-prefix-icon{--input-control-prefix:24px}.search-box.compact.has-suffix-icon{--input-control-suffix:24px}:root{--menu-bg:var(--color-canvas);--menu-active-bg:var(--color-primary-500);--menu-active-color:var(--color-canvas);--menu-selected-bg:var(--color-primary-50);--menu-selected-color:var(--color-primary-500);--menu-icon-opacity:.5;--menu-icon-margin:1.75rem;--menu-min-width:3rem;--menu-heading-color:var(--color-gray-500)}.menu{background:var(--menu-bg);max-width:var(--menu-max-width);min-width:var(--menu-min-width);padding:.5rem}.menu-wrapper{display:flex;flex-direction:column;min-height:0}.menu-wrapper>.menu{flex:1 1 auto;min-height:0;overflow:auto}.menu-item>.item-inner,.menu-item>a{align-items:center;border-radius:var(--radius);color:inherit;cursor:pointer;display:flex;gap:.5rem;justify-content:space-between;overflow:hidden;padding:.25rem .5rem;position:relative;text-overflow:ellipsis;transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);white-space:nowrap}.menu-item>.selected{background:var(--menu-selected-bg);color:var(--menu-selected-color)}.menu-item>.active,.menu-item>a.hover,.menu-item>a:hover{background:var(--menu-active-bg);color:var(--menu-active-color)}.menu-item>a.no-hover.hover,.menu-item>a.no-hover:hover{background:unset;color:unset}.menu-item.disabled>a:hover,.menu-item>a.disabled:hover{background-color:inherit;color:inherit}.menu-item .item-title,.menu-item>a>.text{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:clip;white-space:nowrap}.menu>.divider{margin:.25rem}.menu-heading{align-items:center;color:var(--menu-heading-color);display:flex;font-size:.75rem;font-weight:700;height:2rem;line-height:1rem;padding-left:.25rem;padding-right:.25rem}.has-icons>.menu-item>a>.item-icon{align-items:center;display:flex;height:1rem;justify-content:center;opacity:var(--menu-icon-opacity);width:1rem}.menu-nested{--menu-indent:10px}.menu-nested .menu{background-color:transparent;margin-bottom:-.5rem;margin-left:var(--menu-indent);margin-top:-.5rem;padding-right:0}.menu-nested .menu-item>.item-inner{padding-left:0}.menu-nested .search-menu-footer,.menu-nested .search-menu-header{margin-bottom:.25rem;margin-left:var(--menu-indent);margin-top:-.125rem;padding-right:1px}.menu.compact .menu-item>a{padding-bottom:.125rem;padding-top:.125rem}.menu.compact .menu-heading{height:1.75rem}.search-menu-header{padding:.5rem .5rem .125rem}.search-menu-footer{padding:.125rem .5rem .5rem}.search-menu .item.is-not-match,.search-menu-footer:empty,.search-menu-header:empty{display:none}.search-menu .item.is-not-match.has-match-child{display:list-item}.search-menu .item.is-not-match.has-match-child>.item-inner{opacity:.5;pointer-events:none}.search-menu.no-toggle-on-search .nested-toggle-icon{pointer-events:none}.search-menu .is-match-keys{font-weight:700;text-decoration-line:underline}.search-menu-no-match-hint{display:none;font-size:.75rem;line-height:1rem;padding:.5rem;--tw-text-opacity:1;color:rgba(var(--color-gray-500-rgb),var(--tw-text-opacity,1))}.no-match-child .search-menu-no-match-hint{display:block}.no-match-child>.menu{display:none}.search-menu-exceed-limit-hint{font-size:.75rem;line-height:1rem;padding:.25rem;--tw-text-opacity:1;color:rgba(var(--color-gray-500-rgb),var(--tw-text-opacity,1))}:root{--alert-bg:var(--color-surface)}.alert{align-items:center;background-color:var(--alert-bg);border-radius:var(--radius);display:flex;gap:.75rem;padding:.5rem .75rem}.alert-content{display:flex;flex:1 1 auto;flex-direction:column;gap:1rem}.alert-close{margin-bottom:-.375rem;margin-right:-.5rem;margin-top:-.375rem}.alert-link{color:inherit;font-weight:700}.alert-link:hover{color:inherit;text-decoration-line:underline}.alert-heading{font-weight:700;margin:0}.alert-text{flex:1 1 auto;white-space:pre-line}.alert-actions{align-items:center;display:flex;gap:.5rem}.close{aspect-ratio:1/1;display:block;position:relative;width:1em}.close:after,.close:before{content:"";display:block;height:1px;left:0;position:absolute;width:100%;--tw-rotate:45deg;background-color:currentColor;border-radius:var(--radius-full);top:calc(50% - .5px)}.close:after,.close:before{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.close:after{--tw-rotate:-45deg}.messagers{align-items:flex-end;bottom:0;display:flex;flex-direction:column;gap:.5rem;justify-content:flex-end;left:0;padding:1rem;pointer-events:none;position:fixed;right:0;top:0;z-index:1900}.messagers-top-left,.messagers-top-right{justify-content:flex-start}.messagers-bottom-left,.messagers-top-left{align-items:flex-start}.messagers-bottom,.messagers-center,.messagers-top{align-items:center}.messagers-top,.messagers-top-left,.messagers-top-right{justify-content:flex-start}.messagers-center{justify-content:center}.messager{background-color:rgba(var(--color-inverse-rgb),.8);pointer-events:auto;--tw-text-opacity:1;color:rgba(var(--color-canvas-rgb),var(--tw-text-opacity,1));--tw-shadow:0 10px 25px -5px rgba(0,0,0,.2),0 4px 10px -6px rgba(0,0,0,.15);--tw-shadow-colored:0 10px 25px -5px var(--tw-shadow-color),0 4px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-backdrop-blur:blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);transition-duration:.3s}:root{--progress-radius:var(--radius);--progress-striped-size:40px;--progress-bg:var(--color-surface);--progress-bar-color:var(--color-primary-500)}.progress{background:var(--progress-bg);border-radius:var(--progress-radius);display:flex;height:1.25rem}.progress-bar{background:var(--progress-bar-color);height:100%;transition-duration:.5s;transition-property:width;transition-timing-function:cubic-bezier(.4,0,.2,1)}.progress-striped>.progress-bar{background-image:linear-gradient(45deg,rgba(var(--color-canvas-rgb),.15) 25%,transparent 25%,transparent 50%,rgba(var(--color-canvas-rgb),.15) 50%,rgba(var(--color-canvas-rgb),.15) 75%,transparent 75%,transparent);background-size:var(--progress-striped-size) var(--progress-striped-size)}.progress>.progress-bar:first-child{border-bottom-left-radius:inherit;border-top-left-radius:inherit}.progress>.progress-bar:last-child{border-bottom-right-radius:inherit;border-top-right-radius:inherit}.progress.active .progress-bar{animation:progress-bar-stripes 2s linear infinite}@keyframes progress-bar-stripes{0%{background-position:40px 0}to{background-position:0 0}}.scrollbar,:root{--scrollbar-size:10px;--scrollbar-opacity:.6;--scrollbar-bg:rgba(var(--color-inverse-rgb),.15);--scrollbar-inset:inset 0 0 0 1px rgba(var(--color-inverse-rgb),.05);--scrollbar-bar-bg:rgba(var(--color-inverse-rgb),.3);--scrollbar-hover-bg:rgba(var(--color-inverse-rgb),.4);--scrollbar-drag-bg:rgba(var(--color-inverse-rgb),.5);--scrollbar-radius:var(--radius-sm);--scrollbar-duration:.7s}::-webkit-scrollbar{height:var(--scrollbar-size);width:var(--scrollbar-size)}::-webkit-scrollbar-track{background:var(--scrollbar-bg);box-shadow:var(--scrollbar-shadow);-webkit-transition:background-color var(--scrollbar-duration);transition:background-color var(--scrollbar-duration)}::-webkit-scrollbar-track:hover,:hover::-webkit-scrollbar-track{background:var(--scrollbar-hover-bg)}::-webkit-scrollbar-thumb{background:var(--scrollbar-bar-bg);border-radius:var(--scrollbar-radius);min-height:var(--scrollbar-size);-webkit-transition:var(--scrollbar-duration);transition:var(--scrollbar-duration);-webkit-transition-property:background-color;transition-property:background-color}::-webkit-scrollbar-thumb:hover{background:var(--scrollbar-hover-bg)}::-webkit-scrollbar-thumb:active{background:var(--scrollbar-drag-bg)}@-moz-document url-prefix(){.scrollbar-thin{scrollbar-width:thin}}.scrollbar-thin::-webkit-scrollbar{height:calc(var(--scrollbar-size)/2);width:calc(var(--scrollbar-size)/2)}.scrollbar-hover::-webkit-scrollbar,.scrollbar-hover::-webkit-scrollbar-thumb,.scrollbar-hover::-webkit-scrollbar-track{visibility:hidden}.scrollbar-hover:hover::-webkit-scrollbar,.scrollbar-hover:hover::-webkit-scrollbar-thumb,.scrollbar-hover:hover::-webkit-scrollbar-track{visibility:visible}@font-face{font-family:ZentaoIcon;font-style:normal;font-weight:400;src:url(./icons/ZentaoIcon.eot?v=1.74);src:url(./icons/ZentaoIcon.woff?v=1.74) format("woff"),url(./icons/ZentaoIcon.ttf?v=1.74) format("truetype"),url(./icons/ZentaoIcon.svg?v=1.74#regular) format("svg")}.icon,[class*=" icon-"],[class^=icon-]{display:inline-block;font-display:block;font-family:ZentaoIcon;font-size:14px;font-style:normal;font-variant:normal;font-weight:400;line-height:1;text-transform:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.icon:before{display:inline-block;min-width:14px;text-align:center}.icon-xs:before{font-size:.7em}.icon-sm:before{font-size:.8em}.icon-lg:before{font-size:1.25em;vertical-align:-10%}.icon-2x{font-size:28px}.icon-3x{font-size:42px}.icon-4x{font-size:56px}.icon-5x{font-size:70px}.icon-run{position:relative}.icon-run:before{opacity:.5}.icon-run:after{bottom:0;content:"\ea07";display:block;left:0;position:absolute;right:0;text-align:center;top:0}.icon-docspace:before{content:"\ea1b"}.icon-doclib:before{content:"\ea1c"}.icon-guihua:before{content:"\ea02"}.icon-memory:before{content:"\e9fd"}.icon-cpu:before{content:"\e9fe"}.icon-pause-pure:before{content:"\e9ff"}.icon-exclamation-pure:before{content:"\ea00"}.icon-zentao:before{content:"\e901"}.icon-zentao-alt:before{content:"\e900"}.icon-safe:before{content:"\ea06"}.icon-ai:before{content:"\e983"}.icon-kanban:before{content:"\e997"}.icon-college:before{content:"\e9c8"}.icon-home:before,.icon-menu-my:before{content:"\e97a"}.icon-program:before{content:"\e9aa"}.icon-lightbulb-alt:before,.icon-product:before{content:"\e98f"}.icon-project:before,.icon-rocket:before{content:"\e99c"}.icon-run:before{content:"\e9a9"}.icon-run-alt:before{content:"\ea07"}.icon-test:before{content:"\e956"}.icon-devops:before,.icon-infinite:before{content:"\e9a3"}.icon-doc:before,.icon-menu-doc:before{content:"\e99b"}.icon-statistic:before{content:"\e999"}.icon-group:before,.icon-menu-users:before,.icon-persons:before,.icon-team:before{content:"\e97e"}.icon-assets:before,.icon-diamond:before{content:"\e9ae"}.icon-flow:before{content:"\e994"}.icon-backend:before,.icon-cog-outline:before{content:"\ea05"}.icon-help:before{content:"\e968"}.icon-download:before,.icon-import:before{content:"\e904"}.icon-export:before{content:"\e905"}.icon-lightbulb:before{content:"\e91c"}.icon-close:before{content:"\e936"}.icon-check:before{content:"\e5ca"}.icon-minus:before{content:"\e926"}.icon-expand-alt:before{content:"\e6f1"}.icon-collapse-alt:before{content:"\e6f2"}.icon-fullscreen:before{content:"\e96b"}.icon-star-empty:before{content:"\e94a"}.icon-star:before{content:"\e94b"}.icon-exclamation-sign:before{content:"\e930"}.icon-info-sign:before{content:"\e9d5"}.icon-flag:before{content:"\e937"}.icon-check-circle:before{content:"\e92f"}.icon-check-sign:before{content:"\e938"}.icon-chart-pie:before{content:"\e95b"}.icon-history:before{content:"\e95f"}.icon-pencil:before{content:"\e254"}.icon-search:before{content:"\e928"}.icon-restart:before{content:"\e95e"}.icon-cog:before{content:"\e93b"}.icon-chart-line:before{content:"\e95c"}.icon-bar-chart:before,.icon-chart-bar:before{content:"\e95d"}.icon-exchange:before{content:"\e927"}.icon-severity:before{content:"\e973"}.icon-book:before{content:"\f02d"}.icon-treemap-alt:before{content:"\e971"}.icon-severity-solid:before{content:"\e902"}.icon-chat-line:before{content:"\e998"}.icon-stack:before{content:"\e943"}.icon-cube:before{content:"\e967"}.icon-minus-sign:before{content:"\e939"}.icon-bars-sign:before{content:"\e93a"}.icon-chat:before,.icon-message:before{content:"\e940"}.icon-more:before{content:"\e744"}.icon-certificate:before{content:"\f0a3"}.icon-bell:before{content:"\e7f5"}.icon-columns:before{content:"\f0db"}.icon-envelope-o:before{content:"\e92a"}.icon-unfold-all:before{content:"\e931"}.icon-fold-all:before{content:"\e932"}.icon-bars:before{content:"\e948"}.icon-cards-view:before{content:"\e949"}.icon-ellipsis-v:before{content:"\e5d4"}.icon-spinner-indicator:before{content:"\e982"}.icon-up-circle:before{content:"\e92b"}.icon-right-circle:before{content:"\e92c"}.icon-down-circle:before{content:"\e92d"}.icon-left-circle:before{content:"\e92e"}.icon-angle-double-right:before{content:"\f101"}.icon-angle-down:before{content:"\e313"}.icon-angle-left:before{content:"\e314"}.icon-angle-right:before{content:"\e315"}.icon-angle-top:before{content:"\e316"}.icon-first-page:before{content:"\e5dc"}.icon-last-page:before{content:"\e5dd"}.icon-caret-down:before{content:"\f0d7"}.icon-caret-up:before{content:"\f0d8"}.icon-caret-left:before{content:"\f0d9"}.icon-caret-right:before{content:"\f0da"}.icon-sort:before{content:"\f0dc"}.icon-sort-down:before{content:"\f0dd"}.icon-sort-up:before{content:"\f0de"}.icon-arrow-up:before{content:"\e923"}.icon-arrow-down:before{content:"\e924"}.icon-arrow-left:before{content:"\e952"}.icon-arrow-right:before{content:"\e93e"}.icon-chevron-left:before{content:"\e934"}.icon-chevron-right:before{content:"\e935"}.icon-chevron-double-up:before{content:"\e959"}.icon-chevron-double-down:before{content:"\e95a"}.icon-folder-account:before{content:"\e942"}.icon-folder-move:before{content:"\e960"}.icon-folder-plus:before{content:"\e961"}.icon-folder-upload:before{content:"\e962"}.icon-folder-star:before{content:"\e963"}.icon-folder-edit:before{content:"\e964"}.icon-folder-download:before{content:"\e965"}.icon-folder-outline:before{content:"\e966"}.icon-folder:before{content:"\e944"}.icon-folder-o:before{content:"\e945"}.icon-folder-open-o:before{content:"\e946"}.icon-folder-open:before{content:"\e947"}.icon-paper-clip:before{content:"\e93d"}.icon-share:before{content:"\f064"}.icon-format-list-numbers:before{content:"\e969"}.icon-format-quote-close:before{content:"\e96a"}.icon-productplan:before{content:"\e9fc"}.icon-aiux:before{content:"\e99e"}.icon-qc:before{content:"\e986"}.icon-qc-q:before{content:"\e985"}.icon-qc-c:before{content:"\e987"}.icon-sonarqube:before{content:"\e9ba"}.icon-board:before{content:"\ea15"}.icon-market:before{content:"\ea01"}.icon-ztool:before{content:"\e9c1"}.icon-contacts:before{content:"\e9c3"}.icon-chats:before{content:"\e9c4"}.icon-ops:before{content:"\e903"}.icon-menu-backend:before{content:"\e993"}.icon-feedback:before{content:"\e991"}.icon-oa:before{content:"\e9a1"}.icon-more-circle:before{content:"\e988"}.icon-controls:before{content:"\e995"}.icon-account:before{content:"\e992"}.icon-about:before,.icon-info:before{content:"\e996"}.icon-exclamation:before{content:"\e9fa"}.icon-exit:before{content:"\e99a"}.icon-theme:before{content:"\e9a0"}.icon-globe:before,.icon-lang:before{content:"\f0ac"}.icon-template:before{content:"\e9fb"}.icon-seal:before{content:"\e9f8"}.icon-menu-arrow-left:before{content:"\e9f0"}.icon-menu-arrow-right:before{content:"\e9f1"}.icon-add-directory:before{content:"\e9ef"}.icon-design:before{content:"\e9ec"}.icon-download-alt:before{content:"\e9ea"}.icon-blame:before{content:"\e9e0"}.icon-draft-edit:before{content:"\e9dc"}.icon-sub-review-user:before{content:"\e9db"}.icon-sub-review:before{content:"\e9df"}.icon-ztf:before{content:"\e9dd"}.icon-save:before{content:"\e9d8"}.icon-list-box:before{content:"\e9b4"}.icon-usecase:before{content:"\e99d"}.icon-code:before{content:"\e990"}.icon-summary:before{content:"\e9ad"}.icon-more-alt:before{content:"\e9a7"}.icon-customer:before{content:"\e9d9"}.icon-alarm:before{content:"\ea16"}.icon-treeview:before{content:"\ea0d"}.icon-or:before{content:"\ea0b"}.icon-manager:before{content:"\ea0c"}.icon-target:before{content:"\ea0a"}.icon-ipd:before{content:"\e9f9"}.icon-wiki-lib:before{content:"\e9f5"}.icon-annex-lib:before{content:"\e9f6"}.icon-interface-lib:before{content:"\e9f7"}.icon-has-authority-pack:before{content:"\e9f3"}.icon-without-authority-pack:before{content:"\e9f4"}.icon-data-structure:before{content:"\e9f2"}.icon-waterfallplus:before{content:"\e9ed"}.icon-agileplus:before{content:"\e9ee"}.icon-horn:before{content:"\e9eb"}.icon-resume:before{content:"\e9e9"}.icon-mirror:before{content:"\e9e6"}.icon-remote:before{content:"\e9e7"}.icon-moon:before{content:"\e9e8"}.icon-ticket:before{content:"\e9e1"}.icon-gantt-alt:before{content:"\e9e2"}.icon-tree:before{content:"\e9c9"}.icon-list:before{content:"\e9cb"}.icon-gantt:before{content:"\e9cc"}.icon-group-view:before{content:"\e9cd"}.icon-inherit-space:before{content:"\e9c2"}.icon-card-archive:before{content:"\e9b8"}.icon-col-archive:before{content:"\e9b9"}.icon-col-add-right:before{content:"\e9bb"}.icon-col-add-left:before{content:"\e9bc"}.icon-col-split:before{content:"\e9bd"}.icon-waterfall:before{content:"\e9a4"}.icon-manual:before{content:"\e98d"}.icon-lane:before{content:"\e9b1"}.icon-analyze:before{content:"\ea1e"}.icon-var-x:before{content:"\ea1d"}.icon-mobile:before{content:"\ea18"}.icon-clear:before{content:"\ea19"}.icon-db:before{content:"\ea17"}.icon-unpinned:before{content:"\ea08"}.icon-pinned:before{content:"\ea09"}.icon-support-ticket:before{content:"\ea04"}.icon-snap-house:before{content:"\e9e3"}.icon-wrench:before{content:"\e9e4"}.icon-desktop:before{content:"\e9e5"}.icon-back-circle:before{content:"\e9da"}.icon-back:before{content:"\e9d3"}.icon-shield:before{content:"\e9ca"}.icon-meh:before{content:"\e9ce"}.icon-frown:before{content:"\e9cf"}.icon-smile:before{content:"\e9d0"}.icon-unlock-solid:before{content:"\e9d1"}.icon-lock-solid:before{content:"\e9d2"}.icon-ver:before{content:"\e9c6"}.icon-publish:before,.icon-send:before{content:"\e9c7"}.icon-tag:before{content:"\e9be"}.icon-tag-lock:before{content:"\e9bf"}.icon-code-fork:before{content:"\f126"}.icon-branch-lock:before{content:"\e9c0"}.icon-groups:before{content:"\e9af"}.icon-thumbs-up:before{content:"\f087"}.icon-thumbs-down:before{content:"\f088"}.icon-thumbs-up-solid:before{content:"\e9d6"}.icon-thumbs-down-solid:before{content:"\e9d7"}.icon-hash:before,.icon-version:before{content:"\e9ab"}.icon-p-square:before{content:"\e97b"}.icon-video-play:before{content:"\e97f"}.icon-plus-solid-circle:before{content:"\e974"}.icon-minuse-solid-circle:before{content:"\e9b6"}.icon-s:before{content:"\e975"}.icon-c:before{content:"\e976"}.icon-t:before{content:"\e977"}.icon-guide:before{content:"\e978"}.icon-todo:before{content:"\e979"}.icon-plus:before{content:"\e925"}.icon-side-left:before{content:"\e9b3"}.icon-side-right:before{content:"\e9b2"}.icon-fullscreen-exit:before{content:"\e972"}.icon-alert:before{content:"\e99f"}.icon-undo:before{content:"\e93f"}.icon-redo:before{content:"\e9d4"}.icon-swap:before{content:"\e9b0"}.icon-chat-solid:before{content:"\e9b5"}.icon-clock:before{content:"\e97c"}.icon-cost:before{content:"\e97d"}.icon-pencil-alt:before{content:"\e984"}.icon-size-height:before{content:"\e9c5"}.icon-list-collapse:before{content:"\ea52"}.icon-list-expand:before{content:"\ea53"}.icon-upload-file:before{content:"\ea03"}.icon-file-log:before{content:"\e9de"}.icon-rich-text:before{content:"\e913"}.icon-markdown:before{content:"\e916"}.icon-excel:before{content:"\e933"}.icon-text-link:before{content:"\e94d"}.icon-text-unlink:before{content:"\ea51"}.icon-ppt:before{content:"\e957"}.icon-word:before{content:"\e958"}.icon-doc-lib:before{content:"\e96f"}.icon-file-empty:before,.icon-file:before{content:"\f016"}.icon-file-text:before{content:"\f0f6"}.icon-file-alt:before{content:"\f15b"}.icon-file-text-alt:before{content:"\f15c"}.icon-file-pdf:before{content:"\f1c1"}.icon-file-word:before{content:"\f1c2"}.icon-file-excel:before{content:"\f1c3"}.icon-file-powerpoint:before{content:"\f1c4"}.icon-file-image:before{content:"\f1c5"}.icon-file-archive:before{content:"\f1c6"}.icon-file-audio:before{content:"\f1c7"}.icon-file-video:before{content:"\f1c8"}.icon-file-code:before{content:"\f1c9"}.icon-columns-2:before{content:"\ea54"}.icon-columns-3:before{content:"\ea55"}.icon-columns-4:before{content:"\ea56"}.icon-panel-right:before{content:"\ea57"}.icon-panel-left:before{content:"\ea58"}.icon-paragraph:before{content:"\ea50"}.icon-highlighter:before{content:"\ea4e"}.icon-eraser:before{content:"\ea4f"}.icon-paint-roller:before{content:"\ea4b"}.icon-brush-cleaning:before{content:"\ea4c"}.icon-add-divider:before{content:"\ea4d"}.icon-delete-row:before{content:"\ea42"}.icon-delete-column:before{content:"\ea43"}.icon-add-row:before{content:"\ea44"}.icon-add-column:before{content:"\ea45"}.icon-table-remove:before{content:"\ea46"}.icon-table-cells-split:before{content:"\ea47"}.icon-table-cells-merge:before{content:"\ea48"}.icon-sigma:before{content:"\ea49"}.icon-sigma-box:before{content:"\ea4a"}.icon-grid-2x2-remove:before{content:"\ea2f"}.icon-grid-2x2:before{content:"\ea30"}.icon-kanban-box:before{content:"\ea31"}.icon-align-center:before{content:"\ea32"}.icon-align-bottom:before{content:"\ea33"}.icon-align-top:before{content:"\ea34"}.icon-text-left:before{content:"\ea35"}.icon-text-center:before{content:"\ea36"}.icon-text-right:before{content:"\ea37"}.icon-text-justify:before{content:"\ea38"}.icon-code-block:before{content:"\ea39"}.icon-at:before{content:"\ea3a"}.icon-textbox:before{content:"\ea3b"}.icon-panel:before{content:"\ea3c"}.icon-task-box:before{content:"\ea3d"}.icon-check-list:before{content:"\ea3e"}.icon-text-sup:before{content:"\ea3f"}.icon-text-sub:before{content:"\ea40"}.icon-text-cols:before{content:"\ea41"}.icon-font-style:before{content:"\ea1f"}.icon-font-size:before{content:"\ea20"}.icon-quote:before{content:"\ea21"}.icon-background-color:before{content:"\ea22"}.icon-text-color:before{content:"\ea23"}.icon-formula:before{content:"\ea24"}.icon-format-heading-1:before{content:"\ea25"}.icon-format-heading-2:before{content:"\ea26"}.icon-format-heading-3:before{content:"\ea27"}.icon-format-heading-4:before{content:"\ea28"}.icon-format-heading-5:before{content:"\ea29"}.icon-format-heading-6:before{content:"\ea2a"}.icon-format-bold:before{content:"\e953"}.icon-format-italic:before{content:"\e955"}.icon-format-underline:before{content:"\ea2b"}.icon-format-strike:before{content:"\ea2c"}.icon-multi-input:before{content:"\ea1a"}.icon-cell-input:before{content:"\ea0e"}.icon-input:before{content:"\ea0f"}.icon-checkbox:before{content:"\ea10"}.icon-radio:before{content:"\ea11"}.icon-transition:before{content:"\ea12"}.icon-add-sub-chapter:before{content:"\ea13"}.icon-add-chapter:before{content:"\ea14"}.icon-color:before{content:"\e93c"}.icon-text:before{content:"\e929"}.icon-menu-collapse:before{content:"\e980"}.icon-menu-expand:before{content:"\e981"}.icon-format-list-bulleted:before{content:"\e9a8"}.icon-image:before{content:"\e96c"}.icon-table:before{content:"\e96d"}.icon-table-alt:before{content:"\ea2d"}.icon-data-table:before{content:"\ea2e"}.icon-estimate:before{content:"\e9ac"}.icon-sprint:before{content:"\e9a2"}.icon-shield-check:before{content:"\e9a5"}.icon-ok:before{content:"\e9a6"}.icon-printer:before{content:"\e906"}.icon-bullhorn:before{content:"\e910"}.icon-person:before{content:"\e941"}.icon-fields:before{content:"\e989"}.icon-trigger:before{content:"\e98a"}.icon-layout:before{content:"\e98b"}.icon-audit:before{content:"\e98c"}.icon-ban-circle:before,.icon-cancel:before{content:"\e951"}.icon-eye:before{content:"\e94e"}.icon-eye-off:before{content:"\e96e"}.icon-unlock:before{content:"\e94f"}.icon-lock:before,.icon-private:before{content:"\e950"}.icon-move:before{content:"\e94c"}.icon-hand-right:before{content:"\e907"}.icon-checked:before{content:"\e908"}.icon-off:before{content:"\e909"}.icon-play:before,.icon-start:before{content:"\e90a"}.icon-time:before{content:"\e90b"}.icon-edit:before{content:"\e90c"}.icon-trash:before{content:"\e90d"}.icon-link:before{content:"\e90e"}.icon-unlink:before{content:"\e90f"}.icon-bug:before{content:"\e911"}.icon-list-alt:before{content:"\e912"}.icon-alter:before,.icon-change:before{content:"\e970"}.icon-glasses:before,.icon-review:before{content:"\e914"}.icon-sitemap:before,.icon-testcase:before{content:"\e915"}.icon-pluses:before{content:"\e917"}.icon-report-list:before{content:"\e918"}.icon-active:before,.icon-magic:before{content:"\e919"}.icon-treemap:before{content:"\e91a"}.icon-confirm:before{content:"\e91b"}.icon-split:before{content:"\e98e"}.icon-calendar:before,.icon-delay:before{content:"\e91d"}.icon-pause:before{content:"\e91e"}.icon-ban:before{content:"\e91f"}.icon-plus-bold:before{content:"\e920"}.icon-copy:before{content:"\e921"}.icon-refresh:before{content:"\e922"}.icon-diff:before{content:"\e9b7"}.icon-format-header-pound:before{content:"\e954"}.status-active,.status-asked,.status-normal,.status-unconfirmed,.status-wait{color:var(--color-status-normal,#313c52)}.status-active.status-issue,.status-checking,.status-commenting,.status-confirmed,.status-doing{color:#ff6f42}.status-blocked,.status-hangup,.status-pause,.status-suspended{color:#b89664}.status-clarify,.status-draft{color:#8166ee}.status-noreview,.status-reviewing,.status-wait.status-testcase{color:#18a6fd}.status-active.status-risk,.status-changed,.status-changing,.status-fail{color:#fb2b2b}.status-checked,.status-done,.status-pass,.status-replied,.status-resolved,.status-success{color:#0dbb7d}.status-cancel,.status-canceled,.status-investigate{color:var(--color-status-cancel,#838a9d)}.status-closed,.status-testtask.status-done{color:var(--color-status-closed,#9ea3b0)}.dark{--color-status-normal:#eff1f3;--color-status-cancel:#9ea3b0;--color-status-closed:#838a9d}@media (prefers-color-scheme:dark){.dark-auto{--color-status-normal:#eff1f3;--color-status-cancel:#9ea3b0;--color-status-closed:#838a9d}}.pri,[class*=" pri-"],[class^=pri-]{border-color:currentColor;border-radius:var(--radius-full);border-width:1px;display:inline-block;font-size:.75rem;height:1rem;line-height:1rem;line-height:14px;max-width:54px;min-width:16px;overflow:hidden;padding-left:.125rem;padding-right:.125rem;text-align:center;white-space:nowrap;--tw-text-opacity:1;color:rgba(var(--color-gray-400-rgb),var(--tw-text-opacity,1))}.pri-1{color:rgb(255 73 18/var(--tw-text-opacity,1))}.pri-1,.pri-2{--tw-text-opacity:1}.pri-2{color:rgba(var(--color-warning-600-rgb),var(--tw-text-opacity,1))}.pri-3{color:rgb(59 130 246/var(--tw-text-opacity,1))}.pri-3,.pri-4{--tw-text-opacity:1}.pri-4{color:rgb(149 211 224/var(--tw-text-opacity,1))}.severity{display:inline-block;font-size:.75rem;height:1rem;line-height:1rem;line-height:14px;max-width:54px;min-width:16px;overflow:hidden;padding-left:.125rem;padding-right:.125rem;position:relative;text-align:center;white-space:nowrap;--tw-text-opacity:1;color:rgba(var(--color-gray-400-rgb),var(--tw-text-opacity,1))}.severity:before{background-color:currentColor;background-repeat:no-repeat;height:100%;left:0;position:absolute;top:0;width:100%;z-index:0;--tw-content:attr(data-severity);content:var(--tw-content);-webkit-mask:url('data:image/svg+xml;charset=utf-8,');mask:url('data:image/svg+xml;charset=utf-8,');-webkit-mask-size:100% 100%;mask-size:100% 100%}.severity:after,.severity:before{display:inline-block}.severity:after{--tw-scale-x:.75;--tw-scale-y:.75;content:attr(data-severity);line-height:20px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.severity[data-severity="1"]{--tw-text-opacity:1;color:rgb(185 28 28/var(--tw-text-opacity,1))}.severity[data-severity="2"]{--tw-text-opacity:1;color:rgb(249 115 22/var(--tw-text-opacity,1))}.severity[data-severity="3"]{--tw-text-opacity:1;color:rgb(250 174 26/var(--tw-text-opacity,1))}.severity[data-severity="4"]{--tw-text-opacity:1;color:rgb(184 150 100/var(--tw-text-opacity,1))}.severity[data-severity="5"]{--tw-text-opacity:1;color:rgb(158 163 176/var(--tw-text-opacity,1))}.severity-label{background-color:transparent}.severity-label:after,.severity-label:before{--tw-content:none;content:var(--tw-content)}.risk-high{color:rgb(220 38 38/var(--tw-text-opacity,1))}.risk-high,.risk-middle{--tw-text-opacity:1}.risk-middle{color:rgb(234 179 8/var(--tw-text-opacity,1))}.label.label-id{border-radius:var(--radius-full);flex:none;--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-gray-300-rgb),var(--tw-ring-opacity,1));--label-bg:rgba(var(--color-canvas-rgb),.1)}.nav-feature{--nav-active-bg:var(--color-primary-100);--nav-active-color:var(--color-fore)}.nav-feature .nav-checkbox>.checkbox,.nav-feature .nav-checkbox>.checkbox-primary,.nav-feature .nav-item>a{align-items:center;border-radius:var(--radius);height:2rem;padding-left:.625rem;padding-right:.625rem}.nav-feature .nav-item>a>.icon{--tw-text-opacity:1;color:rgba(var(--color-primary-500-rgb),var(--tw-text-opacity,1))}.sortable-list .listitem{cursor:move;--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1));padding-left:.5rem;padding-right:.5rem}.sortable-list .sortable-ghost>.listitem{--tw-bg-opacity:1;background-color:rgba(var(--color-warning-50-rgb),var(--tw-bg-opacity,1))}.sortable-empty-shadow{height:1px!important;left:0!important;opacity:0!important;pointer-events:none!important;position:absolute!important;top:0!important;width:1px!important}.chevron-down,.chevron-left,.chevron-right,.chevron-up{align-items:center;display:inline-flex;height:1em;justify-content:center;position:relative;width:1em}.chevron-down:before,.chevron-left:before,.chevron-right:before,.chevron-up:before{display:block;height:.6923077em;transform-origin:center;width:.6923077em;--tw-translate-y:-0.125rem;--tw-rotate:45deg;border-color:currentColor;border-width:0 1px 1px 0;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-content:"";content:var(--tw-content)}.chevron-left:before{--tw-translate-y:0px;--tw-translate-x:0.125rem;--tw-rotate:135deg}.chevron-left:before,.chevron-right:before{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.chevron-right:before{--tw-translate-y:0px;--tw-translate-x:-0.125rem;--tw-rotate:-45deg}.chevron-up:before{--tw-translate-y:0.125rem;--tw-rotate:225deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.split{display:flex;flex-direction:row}.split-vert{flex-direction:column}.split-cell{min-height:0;min-width:0}.has-animation>.split-cell{transition-duration:.15s;transition-property:width,height;transition-timing-function:cubic-bezier(.4,0,.2,1)}.gutter{align-items:stretch;border-radius:var(--radius);cursor:col-resize;display:flex;flex:none;flex-direction:row;justify-content:center;position:relative}.gutter-vert{cursor:row-resize;flex-direction:column}.gutter:before{display:block;--tw-bg-opacity:1;background-color:rgba(var(--color-border-rgb),var(--tw-bg-opacity,1));transition-duration:.15s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);--tw-content:"";content:var(--tw-content)}.gutter-horz:before{width:1px}.gutter-vert:before{height:1px}.gutter-horz:hover:before{width:75%}.gutter-vert:hover:before{height:75%}.gutter-resize-handler,.gutter-toggle{align-items:center;border-radius:var(--radius-lg);border-width:1px;display:flex;height:1.75rem;justify-content:center;margin-top:-.875rem;position:absolute;top:50%;width:.75rem;--tw-border-opacity:1;border-color:rgba(var(--color-border-rgb),var(--tw-border-opacity,1));--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgba(var(--color-fore-rgb),var(--tw-text-opacity,1));transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1)}.gutter-toggle>span{--tw-scale-x:.75;--tw-scale-y:.75;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));transition-duration:.15s;transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1)}.gutter:hover .gutter-toggle{--tw-border-opacity:1;border-color:rgba(var(--color-gray-500-rgb),var(--tw-border-opacity,1));--tw-bg-opacity:1;background-color:rgba(var(--color-gray-100-rgb),var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgba(var(--color-gray-500-rgb),var(--tw-text-opacity,1))}.gutter .gutter-toggle:hover{--tw-border-opacity:1;border-color:rgba(var(--color-primary-500-rgb),var(--tw-border-opacity,1));--tw-bg-opacity:1;background-color:rgba(var(--color-primary-500-rgb),var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgba(var(--color-canvas-rgb),var(--tw-text-opacity,1))}.is-last>.gutter-toggle{--tw-scale-x:-1}.is-first>.gutter-toggle,.is-last>.gutter-toggle{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.is-first>.gutter-toggle{--tw-scale-x:1}.gutter-vert .gutter-toggle{left:50%;margin-left:-.375rem;margin-top:0;top:auto;--tw-rotate:90deg}.gutter-vert .gutter-toggle,.gutter.is-next-collapsed>.gutter-toggle{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.gutter.is-next-collapsed>.gutter-toggle{--tw-scale-x:1}.gutter.is-prev-collapsed>.gutter-toggle{--tw-scale-x:-1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.gutter-horz.is-first.is-prev-collapsed{transform:translateX(calc(-1px - var(--split-gutter-size)/2))}.gutter-horz.is-last.is-next-collapsed{transform:translateX(calc(1px + var(--split-gutter-size)/2))}.gutter-vert.is-first.is-prev-collapsed{transform:translateY(calc(-1px - var(--split-gutter-size)/2))}.gutter-vert.is-last.is-next-collapsed{transform:translateY(calc(1px + var(--split-gutter-size)/2))}.gutter-resize-handler{background-color:transparent;border-width:0}.gutter-resize-handler:before{border-left-width:1px;border-right-width:1px;bottom:0;left:.25rem;position:absolute;right:.25rem;top:0;--tw-content:"";content:var(--tw-content)}:root{--avatar-radius:12.5%;--avatar-bg:var(--color-surface)}.avatar{align-items:center;aspect-ratio:1/1;background:var(--avatar-bg);border-radius:var(--avatar-radius);display:inline-flex;justify-content:center;overflow:hidden;width:2rem}.avatar>img{height:100%;margin:0;-o-object-fit:cover;object-fit:cover;width:100%}.avatar.size-xs{width:1.25rem}.avatar.size-sm,.avatar.size-xs{font-size:.75rem;line-height:1rem}.avatar.size-sm{width:1.5rem}.avatar.size-lg{font-size:1.5rem;line-height:2rem;width:3rem}.avatar.size-xl{font-size:2.25rem;line-height:2.5rem;width:5rem}.avatar-group{display:flex;gap:.625rem}.avatar-group>.avatar{box-shadow:0 0 0 1px var(--color-canvas)}.avatar-group>*+*{margin-left:-1rem}.avatar-group.size-xs>*+*{margin-left:-.75rem}.avatar-group.size-sm>*+*{margin-left:-.875rem}.avatar-group.size-lg>*+*{margin-left:-1.25rem}.avatar-group.size-xl>*+*{margin-left:-1.5rem}.btn-group{display:flex;gap:1px}.btn-group>.btn.active{z-index:1}.btn-group>.btn:focus-within,.btn-group>.btn:hover{z-index:2}.btn-group>.btn.disabled,.btn-group>.btn:disabled{z-index:0}.btn-group>.btn:not(:first-child){border-bottom-left-radius:var(--radius-none);border-left-color:rgba(var(--color-canvas-rgb),.2);border-left-width:1px;border-top-left-radius:var(--radius-none)}.btn-group>.btn:not(:first-child):before{left:-1px}.btn-group>.btn:not(:last-child){border-bottom-right-radius:var(--radius-none);border-top-right-radius:var(--radius-none)}.color-picker-heading{align-items:center;font-weight:700;justify-content:space-between;margin-bottom:-.25rem;padding:.5rem}.color-picker-heading,.color-picker-row{display:flex;flex-direction:row}.color-picker-row{flex-wrap:wrap;gap:.5rem;padding:.75rem}.color-picker-item{align-items:center;border-radius:var(--radius-full);display:flex;height:1.25rem;justify-content:center;padding-left:.125rem;padding-right:.125rem;width:1.25rem;--tw-text-opacity:1;color:rgba(var(--color-canvas-rgb),var(--tw-text-opacity,1));--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.pick-container{left:0;pointer-events:none;position:absolute;top:0;z-index:1600}.pick-pop{display:flex;flex-direction:column;opacity:0;pointer-events:auto;position:absolute;transition-duration:.15s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);z-index:1200}.pick-pop.in{opacity:1}.date-picker-menu{--menu-bg:none}.date-picker-menu .mini-calendar{margin-top:-.75rem}.date-pick-menu-month,.date-pick-menu-years{display:flex;flex-direction:row;flex-wrap:wrap;gap:1px;max-height:237px;padding-bottom:.5rem;padding-left:.5rem;padding-right:.5rem}.date-pick-menu-years>.btn{width:2.5rem}.date-pick-menu-years>.btn.is-current{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-100-rgb),var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgba(var(--color-primary-500-rgb),var(--tw-text-opacity,1))}.date-pick-menu-month>.btn.active,.date-pick-menu-years>.btn.active{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-500-rgb),var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgba(var(--color-canvas-rgb),var(--tw-text-opacity,1))}.date-pick-menu-month>.btn{width:3rem}.date-picker-menu-footer{border-top-width:1px;display:flex;flex-direction:row;padding:.25rem}.date-picker-menu-footer>.toolbar{flex:1 1 auto;justify-content:center}.date-picker-menu>.menu{border-right-width:1px}.date-picker-menu .menu-item{--tw-text-opacity:1;color:rgba(var(--color-primary-500-rgb),var(--tw-text-opacity,1))}.time-picker-menu{max-height:inherit}.time-picker-menu .menu-item>a{justify-content:center;padding-left:0;padding-right:0;text-align:center}.datetime-picker-menu{max-height:inherit}.mini-calendar{padding:.5rem}.mini-calendar>.row>.col{align-items:center;justify-content:center;width:14.2857%}.mini-calendar-day{height:2rem}.mini-calendar-day.disabled{pointer-events:none;--tw-bg-opacity:1;background-color:rgba(var(--color-gray-200-rgb),var(--tw-bg-opacity,1));opacity:.5}.mini-calendar-day>.btn{width:2rem}.mini-calendar-day.is-weekend>.btn{--tw-text-opacity:1;color:rgba(var(--color-gray-500-rgb),var(--tw-text-opacity,1))}.mini-calendar-day.active>.btn,.mini-calendar-day.is-today>.btn{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-100-rgb),var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgba(var(--color-primary-500-rgb),var(--tw-text-opacity,1))}.mini-calendar-day.selected>.btn{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-500-rgb),var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgba(var(--color-canvas-rgb),var(--tw-text-opacity,1))}.mini-calendar-day.is-out-month{opacity:.5}.i-time{border-color:currentColor;border-radius:50%;border-width:.08em;display:inline-block;height:1em;position:relative;width:1em}.i-time:after{border-color:currentColor;border-width:0 0 .08em .08em;height:.385em;left:.3846em;position:absolute;top:.08em;width:.385em;--tw-content:"";content:var(--tw-content)}.i-calendar{border-radius:2px;display:inline-block;height:.79em;margin-top:.16em;position:relative;width:1em}.i-calendar,.i-calendar:after,.i-calendar:before{border-color:currentColor;border-width:.08em}.i-calendar:after,.i-calendar:before{position:absolute;--tw-content:"";content:var(--tw-content)}.i-calendar:before{border-bottom-width:0;left:.15em;top:.307em;width:.6em}.i-calendar:after{border-bottom-width:0;border-top-width:0;height:.3077em;left:.17em;top:-.154em;width:.538em}:root{--modal-radius:var(--radius-lg);--modal-bg:rgba(var(--color-inverse-rgb),.4);--modal-sm:37.5rem;--modal-base:50rem;--modal-lg:75rem;--modal-xl:90rem}.modal{align-items:center;background-color:var(--modal-bg);bottom:0;display:none;justify-content:center;left:0;overflow:hidden;position:fixed;right:0;top:0;z-index:1500}.modal.load-indicator:before{background-color:transparent;transition-property:none}.modal.loading:after{--tw-text-opacity:1;color:rgba(var(--color-canvas-rgb),var(--tw-text-opacity,1))}.modal.loading .modal-dialog{opacity:0!important}.modal.show{display:flex}.modal-no-backdrop{background-color:transparent;pointer-events:none}.modal-hide{opacity:0!important}.modal-dialog{background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1));pointer-events:auto;position:relative;--tw-bg-opacity:0.9;--tw-shadow:0 10px 50px -10px rgba(0,0,0,.4),0 8px 20px -10px rgba(0,0,0,.3);--tw-shadow-colored:0 10px 50px -10px var(--tw-shadow-color),0 8px 20px -10px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:rgba(var(--color-inverse-rgb),var(--tw-ring-opacity,1));--tw-ring-opacity:0.05;--tw-backdrop-blur:blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);border-radius:var(--modal-radius);width:var(--modal-base)}.modal-content,.modal-dialog{max-height:100vh}.modal-content{display:flex;flex-direction:column;height:100%}.loading>.modal-dialog>.modal-content{opacity:0;visibility:hidden}.modal-dialog.loading{background-color:transparent}.modal-dialog.loading>.modal-content{display:none}.close{aspect-ratio:1/1;display:block;position:relative;width:1em}.close:after,.close:before{content:"";display:block;height:1px;left:0;position:absolute;width:100%;--tw-rotate:45deg;background-color:currentColor;border-radius:var(--radius-full);top:calc(50% - .5px)}.close:after,.close:before{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.close:after{--tw-rotate:-45deg}.modal-header{align-items:center;display:flex;flex:none;flex-wrap:nowrap;gap:1rem;padding:1rem 1.25rem;position:relative}.modal-title{flex:1 1 auto;font-size:1rem;font-weight:700;line-height:1.5rem}.modal-actions{position:absolute;right:.75rem;top:.75rem;z-index:15}.modal-body{flex:1 1 auto;overflow:auto;padding:1rem 1.25rem}.modal-footer{align-items:center;display:flex;flex:none;gap:.75rem;padding:1.25rem}.modal-dialog.size-full,.modal-dialog[data-size=full]{border-radius:var(--radius-none);height:100vh;width:100vw}.modal-dialog.size-sm,.modal-dialog[data-size=sm]{width:var(--modal-sm)}.modal-dialog.size-lg,.modal-dialog[data-size=lg]{width:var(--modal-lg)}.modal-dialog.size-xl,.modal-dialog[data-size=xl]{width:var(--modal-xl)}.modal-iframe{flex:1 1 auto;width:100%}.modal-trans{opacity:0;transition-duration:.2s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1)}.modal-trans.in{opacity:1}.modal-trans>.modal-dialog{transition-property:transform,opacity;--tw-scale-x:.95;--tw-scale-y:.95;opacity:0;transition-duration:.3s}.modal-trans.in>.modal-dialog,.modal-trans>.modal-dialog{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.modal-trans.in>.modal-dialog{--tw-scale-x:1;--tw-scale-y:1;opacity:1}.modal-alert .modal-footer{justify-content:flex-end}.modal-alert .modal-header{margin-bottom:-1rem}.modal-alert .modal-body{overflow-wrap:break-word;white-space:pre-line}.modal-alert .modal-actions+.modal-body{padding-right:3rem}.modal-alert .modal-header+.modal-actions+.modal-body{padding-right:1.25rem}.file-selector{gap:.5rem;width:100%}.file-selector,.file-selector-box{display:flex;flex-direction:column}.file-selector-box{border-style:dashed;border-width:1px;gap:0;height:auto;justify-content:center;position:relative;--tw-border-opacity:1;background-color:rgba(var(--color-primary-50-rgb),.3);border-color:rgba(var(--color-primary-400-rgb),var(--tw-border-opacity,1));padding:.5rem .75rem;--tw-ring-color:transparent;--state-color:rgba(var(--color-primary-500-rgb),.05)}.file-selector-box .text{--tw-text-opacity:1;color:rgba(var(--color-primary-500-rgb),var(--tw-text-opacity,1))}.is-dragging .file-selector-box{border-style:solid}.file-selector-btn{align-items:center;display:flex;gap:.5rem;position:relative}.is-dragging .file-selector-btn{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-50-rgb),var(--tw-bg-opacity,1))}.file-selector-input{-webkit-appearance:none;-moz-appearance:none;appearance:none;bottom:0;cursor:pointer;left:0;opacity:.1;position:absolute;right:0;top:0}.file-selector-tip{--tw-text-opacity:1;color:rgba(var(--color-gray-400-rgb),var(--tw-text-opacity,1))}.file-selector.is-mode-button{flex-direction:column-reverse}.file-selector-list.is-empty{display:none}.file-selector-item .item-avatar{--tw-bg-opacity:1;background-color:rgba(var(--color-gray-50-rgb),var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgba(var(--color-gray-500-rgb),var(--tw-text-opacity,1))}.file-selector-item .item-subtitle{--tw-text-opacity:1;color:rgba(var(--color-gray-400-rgb),var(--tw-text-opacity,1))}.file-selector-item .item-content{flex:none;margin-right:.25rem;max-width:100%}.file-selector-item>.listitem:hover{background-color:rgba(var(--color-gray-500-rgb),.05)}.file-selector-item.is-renaming .item-avatar+.item-content{max-width:calc(100% - 32px)}.file-selector-rename-text{max-width:100%;min-width:100px;position:relative}.file-selector-rename-text>div{overflow:hidden;pointer-events:none;visibility:hidden;white-space:nowrap}.file-selector-rename-input{bottom:0;left:0;position:absolute;right:0;top:0}.file-selector-grid{align-items:flex-start;border-color:transparent;border-radius:var(--radius);border-width:1px;display:flex;flex-direction:row;flex-wrap:wrap;gap:var(--file-selector-grid-gap);--tw-bg-opacity:1;background-color:rgba(var(--color-surface-light-rgb),var(--tw-bg-opacity,1));padding:.5rem}.file-selector-grid-item{height:var(--file-selector-grid-height)}.file-selector-grid-btn,.file-selector-grid-item{width:var(--file-selector-grid-width)}.file-selector-grid-btn{aspect-ratio:1/1;border-style:dashed;border-width:1px;display:flex;flex-direction:column;gap:0;height:auto;justify-content:center;--tw-border-opacity:1;background-color:rgba(var(--color-primary-50-rgb),.3);border-color:rgba(var(--color-primary-400-rgb),var(--tw-border-opacity,1));padding:.5rem;--tw-ring-color:transparent;--state-color:rgba(var(--color-primary-500-rgb),.05)}.file-selector-grid-btn .text{--tw-text-opacity:1;color:rgba(var(--color-primary-500-rgb),var(--tw-text-opacity,1))}.file-selector-grid-item .listitem{flex-direction:column;height:100%;padding:0;position:relative;width:100%}.file-selector-grid-item .item-avatar{border-radius:var(--radius);border-width:1px;width:100%;--tw-text-opacity:1;color:rgba(var(--color-gray-500-rgb),var(--tw-text-opacity,1))}.file-selector-grid-item .item-avatar.has-icon>.icon{font-size:calc(var(--file-selector-grid-width)/2)}.file-selector-grid-item .item-content,.file-selector-grid-item .toolbar{aspect-ratio:1/1;left:0;position:absolute;right:0;top:0;width:100%}.file-selector-grid-item .item-title{bottom:-1.25rem;font-size:.75rem;left:0;line-height:1rem;overflow:hidden;position:absolute;right:1.5rem;white-space:nowrap}.file-selector-grid-item .item-subtitle{border-radius:var(--radius-full);bottom:.25rem;left:.25rem;position:absolute;--tw-bg-opacity:1;background-color:rgba(var(--color-fore-rgb),var(--tw-bg-opacity,1));font-size:.75rem;line-height:1rem;padding-left:.25rem;padding-right:.25rem;--tw-text-opacity:1;color:rgba(var(--color-canvas-rgb),var(--tw-text-opacity,1));opacity:0;transition-duration:.15s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1)}.file-selector-grid-item:hover .item-subtitle{opacity:1}.file-selector-grid-item .toolbar .btn[data-remove-file]{background-color:rgba(var(--color-inverse-rgb),.5);padding:.375rem;position:absolute;right:1px;top:1px;--tw-text-opacity:1;color:rgba(var(--color-canvas-rgb),var(--tw-text-opacity,1))}.file-selector-grid-item .toolbar .btn[data-rename-file]{bottom:-1.5rem;padding:0;position:absolute;right:0}.file-selector-grid .file-selector-rename{bottom:0;height:1.5rem;position:absolute;top:auto}.file-selector-grid .file-selector-rename-text{width:100%}.is-dragging .file-selector-grid{border-width:1px;--tw-border-opacity:1;border-color:rgba(var(--color-primary-400-rgb),var(--tw-border-opacity,1));--tw-bg-opacity:1;background-color:rgba(var(--color-primary-50-rgb),var(--tw-bg-opacity,1))}:root{--nav-radius:var(--radius);--nav-active-color:var(--color-primary-500);--nav-active-bg:var(--color-inherit);--nav-heading-color:var(--color-gray-500);--nav-gap:0.25rem;--nav-item-color:inherit;--nav-item-bg:transparent;--nav-item-padding:1rem;--nav-item-height:2rem;--nav-item-gap:0.75rem;--nav-divider-height:calc(var(--nav-item-height)/2);--nav-divider-margin:0.5rem}.nav{list-style-type:none;padding-left:0}.nav,.nav-item{align-items:center;display:flex;position:relative}.nav-item{gap:var(--nav-item-gap)}.nav-item>a{align-items:center;background-color:var(--nav-item-bg);color:var(--nav-item-color);cursor:pointer;display:flex;gap:var(--nav-gap);height:var(--nav-item-height);justify-content:center;padding-left:var(--nav-item-padding);padding-right:var(--nav-item-padding)}.nav-item>a>.text{white-space:nowrap}.nav-item>.active{font-weight:700;--nav-item-color:var(--nav-active-color);--nav-item-bg:var(--nav-active-bg)}.nav-item>.selected{--nav-item-color:var(--nav-selected-color);--nav-item-bg:var(--nav-selected-bg)}.nav-item>.disabled{--nav-item-color:var(--nav-disabled-color);--nav-item-bg:var(--nav-disabled-bg)}.nav-item>.disabled>*{opacity:var(--opacity-disabled)}.nav-divider,.nav>.divider{align-self:center;height:var(--nav-divider-height);margin-left:var(--nav-divider-margin);margin-right:var(--nav-divider-margin)}.nav-heading{align-items:center;color:var(--nav-heading-color);display:flex;font-weight:700;gap:.25rem;height:2rem;justify-content:center;padding-left:1rem;padding-right:1rem}.nav-space{flex:1 1 auto;width:1rem}.nav-compact{--nav-gap:0.25rem;--nav-item-gap:0.5rem;--nav-item-height:1.75rem;--nav-item-padding:0.5rem;--nav-divider-margin:0.25rem}.nav-primary>.nav-item{position:relative}.nav-primary>.nav-item:hover{z-index:10}.nav-primary>.nav-item+.nav-item{margin-left:-1px}.nav-primary>.nav-item>a{border-radius:var(--radius-none);border-width:1px}.nav-primary>.nav-item:first-child>a,.nav-primary>.nav-item:has(.nav-heading)+.nav-item>a{border-bottom-left-radius:var(--nav-radius);border-top-left-radius:var(--nav-radius)}.nav-primary>.nav-item:last-child>a{border-bottom-right-radius:var(--nav-radius);border-top-right-radius:var(--nav-radius)}.nav-primary>.nav-item>.active{--tw-text-opacity:1;background:var(--nav-active-color);border-color:var(--nav-active-color);color:rgba(var(--color-canvas-rgb),var(--tw-text-opacity,1))}.nav-primary>.nav-divider{display:none}.nav-secondary>.nav-item>a{border-radius:var(--radius-none);position:relative}.nav-secondary>.nav-item>a:after{bottom:-2px;display:block;height:2px;left:0;position:absolute;right:0;--tw-bg-opacity:1;background-color:rgba(var(--color-border-rgb),var(--tw-bg-opacity,1));--tw-content:"";content:var(--tw-content)}.nav-secondary>.nav-item>.active:after{background-color:currentColor}.nav-secondary>.nav-divider{margin:0 0 0 -1px}.nav-tabs>.nav-item>a{border-bottom-left-radius:var(--radius-none);border-bottom-right-radius:var(--radius-none);position:relative}.nav-tabs>.nav-item>a:after{border-color:transparent;border-width:1px;bottom:-1px;display:block;left:-1px;pointer-events:none;position:absolute;right:-1px;top:-1px;--tw-border-opacity:1;border-bottom-color:rgba(var(--color-border-rgb),var(--tw-border-opacity,1));--tw-content:"";border-top-left-radius:inherit;border-top-right-radius:inherit;content:var(--tw-content)}.nav-tabs>.nav-item>.active:after{--tw-border-opacity:1;border-color:rgba(var(--color-border-rgb),var(--tw-border-opacity,1));border-bottom-color:transparent}.nav-tabs>.nav-divider{margin:0 0 0 -1px}.nav-pills>.nav-item>a{border-radius:var(--radius-full)}.nav-pills>.nav-item>.active{--tw-text-opacity:1;background:var(--nav-active-color);border-color:var(--nav-active-color);color:rgba(var(--color-canvas-rgb),var(--tw-text-opacity,1))}.nav-steps{--nav-item-bg:var(--color-canvas);--nav-active-bg:var(--color-primary-500);--nav-active-color:var(--color-canvas);--nav-selected-bg:var(--color-secondary-500);--nav-selected-color:var(--color-canvas)}.nav-steps>.nav-item+.nav-item>a{padding-left:calc(var(--nav-item-padding) + var(--nav-item-height)/3)}.nav-steps>.nav-item>a:after,.nav-steps>.nav-item>a:before{border-style:solid;height:0;left:100%;position:absolute;width:0;z-index:2;--tw-content:"";border-color:transparent;border-left-color:var(--nav-item-bg,var(--color-canvas));border-width:calc(var(--nav-item-height)/2);border-left-width:calc(var(--nav-item-height)/3);border-right-width:0;content:var(--tw-content)}.nav-steps>.nav-item>a:before{background-color:transparent!important;border-left-color:var(--color-border);bottom:auto;left:calc(100% + 5.5px);opacity:1!important;right:auto;top:.4rem;transform:none;z-index:1;--nav-item-height:1.2rem}.nav-steps>.nav-item:has(+.nav-item>.active)>.selected:before,.nav-steps>.nav-item:has(+.nav-item>.active,+.nav-item>.selected)>a:not(.active,.selected):before,.nav-steps>.nav-item:has(+.nav-item>.selected)>.active:before,.nav-steps>.nav-item:last-child>a:after,.nav-steps>.nav-item:last-child>a:before{display:none}.nav-steps>.nav-item>a:hover{--nav-item-bg:var(--color-gray-100)}.nav-steps>.nav-item>.active:hover{--nav-item-bg:var(--color-primary-600)}.nav-steps>.nav-item>.selected:hover{--nav-item-bg:var(--color-secondary-600)}.nav-stacked{flex-direction:column}.nav-stacked>.nav-item{width:100%}.nav-stacked>.nav-heading,.nav-stacked>.nav-item>a{justify-content:flex-start;width:100%}.nav-stacked>.nav-divider{height:1px;margin:.5rem 0;width:100%}.nav-primary.nav-stacked>.nav-item>a{height:2.5rem}.nav-primary.nav-stacked>.nav-item+.nav-item{margin-left:0;margin-top:-1px}.nav-primary.nav-stacked>.nav-item:first-child>a{border-bottom-left-radius:0;border-top-left-radius:var(--nav-radius);border-top-right-radius:var(--nav-radius)}.nav-primary.nav-stacked>.nav-item:last-child>a{border-bottom-left-radius:var(--nav-radius);border-bottom-right-radius:var(--nav-radius);border-top-right-radius:0}.nav-secondary.nav-stacked>.nav-item>a:after{bottom:0;height:100%;left:auto;right:0;top:0;width:2px;--tw-bg-opacity:1;background-color:rgba(var(--color-border-rgb),var(--tw-bg-opacity,1))}.nav-secondary.nav-stacked>.nav-item>.active:after{background-color:currentColor}.nav-secondary.nav-stacked>.nav-divider{margin:0}.nav-tabs.nav-stacked>.nav-item>a{border-bottom-left-radius:var(--nav-radius);border-bottom-right-radius:var(--radius-none);border-top-right-radius:var(--radius-none);position:relative}.nav-tabs.nav-stacked>.nav-item>a:after{--tw-border-opacity:1;border-bottom-color:transparent;border-bottom-left-radius:inherit;border-right-color:rgba(var(--color-border-rgb),var(--tw-border-opacity,1));border-top-left-radius:inherit}.nav-tabs.nav-stacked>.nav-item>a.active:after{--tw-border-opacity:1;border-color:rgba(var(--color-border-rgb),var(--tw-border-opacity,1));border-right-color:transparent}.nav-tabs.nav-stacked>.nav-divider{margin:0}.nav-pills.nav-stacked>.nav-item+.nav-item{margin-top:.25rem}.nav-justified>.nav-item:not(.flex-none,.nav-divider){flex:1 1 auto}.nav-justified>.nav-item>a{width:100%}.arrow,.arrow:before{background:inherit;height:calc(var(--arrow-size)*1.4142);position:absolute;width:calc(var(--arrow-size)*1.4142)}.arrow{visibility:hidden;--arrow-size:5px}.arrow:before{border:inherit;content:"";visibility:visible;--tw-rotate:45deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.arrow-top,.arrow-up{border-bottom:inherit;border-right:inherit;border-width:1px 0 0 1px;top:calc(1px - var(--arrow-size))}.white>.arrow-top,.white>.arrow-up{top:calc(0px - var(--arrow-size))}.arrow-bottom,.arrow-down{border-left:inherit;border-top:inherit;border-width:0 1px 1px 0;bottom:calc(1px - var(--arrow-size))}.white>.arrow-bottom,.white>.arrow-down{bottom:calc(0px - var(--arrow-size))}.arrow-left{border-right:inherit;border-top:inherit;border-width:0 0 1px 1px;left:calc(1px - var(--arrow-size))}.white>.arrow-left{left:calc(0px - var(--arrow-size))}.arrow-right{border-bottom:inherit;border-left:inherit;border-width:1px 1px 0 0;right:calc(1px - var(--arrow-size))}.white>.arrow-right{right:calc(0px - var(--arrow-size))}.popover{display:none;left:0;position:absolute;top:0;width:-moz-max-content;width:max-content}.popover.show{display:block}.popover-heading{align-items:center;border-top-left-radius:inherit;border-top-right-radius:inherit;display:flex;gap:1rem;height:2.5rem;justify-content:space-between;position:relative;z-index:1;--tw-bg-opacity:1;background-color:rgba(var(--color-surface-rgb),var(--tw-bg-opacity,1));padding-left:.75rem;padding-right:.5rem}.popover-title{flex:1 1 auto;font-weight:700}.popover-content{padding:.75rem;position:relative;z-index:1}.popover-arrow{z-index:0}.has-heading>.popover-arrow.arrow-top,.has-heading>.popover-arrow.arrow-up{--tw-bg-opacity:1;background-color:rgba(var(--color-surface-rgb),var(--tw-bg-opacity,1))}.popover>.btn-close{position:absolute;right:.5rem;top:.625rem;z-index:2}.btn-close+.popover-content{padding-right:3rem}.btn.with-popover-show{--tw-shadow:inset 0 2px 4px 0 rgba(0,0,0,.05);--tw-shadow-colored:inset 0 2px 4px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.with-popover-show[data-pop-placement=top]>.caret{--tw-rotate:180deg}.with-popover-show[data-pop-placement=left]>.caret,.with-popover-show[data-pop-placement=top]>.caret{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.with-popover-show[data-pop-placement=left]>.caret{--tw-rotate:90deg}.with-popover-show[data-pop-placement=right]>.caret{--tw-rotate:-90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.pager{align-items:center;display:flex;gap:.25rem;white-space:nowrap}.menu.pager-size-menu{display:grid!important;grid-template-columns:repeat(3,minmax(0,1fr));text-align:center}.menu.pager-size-menu>.menu-item>a{margin:.125rem}.pager .pager-goto-group>.form-control{width:3rem}.pager .pager-goto-group>.input-group-addon{border-width:1px;--tw-border-opacity:1;border-color:rgba(var(--color-gray-300-rgb),var(--tw-border-opacity,1));--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1))}.pager>.pager-nav.active{--tw-text-opacity:1;box-shadow:0 0 0 1px var(--color-primary-500);color:rgba(var(--color-primary-500-rgb),var(--tw-text-opacity,1))}.panel{border-radius:var(--radius);overflow:hidden;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:rgba(var(--color-inverse-rgb),var(--tw-ring-opacity,1));--tw-ring-opacity:0.05}.panel-heading{background-color:var(--panel-heading-bg);flex-wrap:nowrap;gap:1rem;justify-content:space-between;padding:.5rem 1rem}.panel-heading,.panel-title{align-items:center;display:flex}.panel-title{font-weight:700;gap:.5rem;margin:0}.panel-actions{align-items:center;display:flex;margin-right:-.5rem}.panel-body{padding:.75rem 1rem}.panel-footer{align-items:center;background-color:var(--panel-footer-bg);display:flex;gap:.5rem;padding:.5rem 1rem}.size-sm .panel-body,.size-sm .panel-footer,.size-sm .panel-heading{padding:.375rem .75rem}.size-lg .panel-body,.size-lg .panel-footer,.size-lg .panel-heading{padding:1rem 1.25rem}.picker{position:relative}.picker-select{align-items:center;gap:.25rem;justify-content:space-between}.picker-select,.picker-select.form-control{display:flex}.picker-select-placeholder{flex:1 1 auto;--tw-text-opacity:1;color:rgba(var(--color-placeholder-rgb),var(--tw-text-opacity,1))}.picker-select-multi .picker-select-placeholder{padding-left:.25rem;padding-right:.25rem}.picker-single-selection{flex:1 1 auto;min-width:0;overflow:hidden;white-space:nowrap}.picker-deselect-btn{border-radius:var(--radius-full);padding:.25rem}.picker-deselect-btn:not(:hover){opacity:.7}.picker-select-multi.form-control{height:auto;min-height:32px;padding-left:.25rem}.picker-multi-selections{display:flex;flex:1 1 auto;flex-wrap:wrap;gap:.25rem;min-width:0}.picker-multi-selection{align-items:center;border-radius:var(--radius-full);border-width:1px;display:flex;max-width:100%;--tw-bg-opacity:1;background-color:rgba(var(--color-surface-rgb),var(--tw-bg-opacity,1));padding-left:.5rem}.readonly .picker-multi-selection{padding-right:.5rem}.picker-multi-selection>.text{max-width:180px;min-width:0;overflow:clip;white-space:nowrap}.picker-no-search{cursor:default}.picker-menu-list{border-style:none;flex:1 1 auto;min-height:0;overflow-y:auto;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.picker-menu-search+.picker-menu-list.menu{margin-top:-.125rem;padding-top:0}.picker-menu-list.tree{padding:.5rem}.picker-menu-list .tree-item>.selected .item-content{font-weight:400}.picker-menu .search-menu-footer{border-top-width:1px;padding-bottom:.25rem;padding-top:.25rem}.picker-search-input{border-color:transparent;height:1.75rem;outline-width:0!important;padding-left:0;padding-right:2rem;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)!important;--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color)!important;box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)!important}.picker-search{flex:none;position:relative;width:100%}.picker-search>.magnifier{opacity:.5;position:absolute;right:0;top:.5rem}.picker-search-clear.btn{cursor:pointer;height:1.25rem;position:absolute;right:0;top:.25rem;width:1.25rem}.picker-search.is-inline{min-width:64px;width:4rem}.is-inline>.picker-search-input{height:1.25rem;min-width:64px;padding-left:.25rem;padding-right:.25rem}.picker-search-measure{height:0;left:0;overflow:hidden;position:absolute;top:0;white-space:nowrap}.sidebar{flex:none!important;position:relative;--gutter-width:1px;--sidebar-duration:200ms}.has-sidebar-animation .sidebar{transition-duration:.15s;transition-duration:var(--sidebar-duration);transition-property:width,margin;transition-timing-function:cubic-bezier(.4,0,.2,1)}.sidebar-left.is-collapsed{margin-left:calc(var(--gutter-width)*-1)}.sidebar-right.is-collapsed{margin-right:calc(var(--gutter-width)*-1)}.sidebar.is-collapsed>*,.sidebar.is-expanded.is-animating>*{display:none}.sidebar.is-collapsed>.sidebar-gutter{display:flex!important}.sidebar-gutter{bottom:0;left:100%;position:absolute;top:0;width:var(--gutter-width);z-index:10}.sidebar-right>.sidebar-gutter{left:auto;right:100%}.is-collapsed>.gutter>.gutter-toggle>span{--tw-rotate:-180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.sidebar-gutter:before{border-radius:var(--radius-full);opacity:0}.sidebar-gutter:hover:before{opacity:1;width:.5rem}.is-expanded .sidebar-gutter.gutter-border:before{opacity:1}.is-sidebar-resizing{cursor:col-resize}.table{--table-head-bg:var(--color-surface);--table-striped-color:var(--color-gray-50);--table-hover-color:rgba(var(--color-primary-500-rgb),.05);--table-border-color:var(--color-border)}.table{border-color:var(--table-border-color);width:100%}.table>thead{background-color:var(--table-head-bg)}.table>*>tr{border-bottom-width:1px}.table>*>tr>*{padding:.5rem 1rem}.table-striped>tbody>tr:nth-child(2n){background:var(--table-striped-color)}.table-hover>tbody>tr:hover>*{background:var(--table-hover-color)}.table.bordered>*>tr>*{border-width:1px}.table.borderless>*>tr,.table.borderless>*>tr>*{border-style:none}.condensed>*>tr>*{padding:.375rem .75rem}.table-fixed{table-layout:fixed}.table-fixed>*>tr>*{overflow:hidden;white-space:nowrap}.toolbar{align-items:center;display:flex;position:relative}.toolbar>.divider{margin:.5rem;width:1px;--tw-bg-opacity:1;background-color:rgba(var(--color-border-rgb),var(--tw-bg-opacity,1))}.toolbar-space{flex:1 1 auto;height:1px;width:1px}.toolbar>.dropdown.show{align-items:center;display:flex;position:relative}:root{--tooltip-bg:var(--skin-color,var(--color-inverse));--tooltip-text:var(--skin-text,var(--color-canvas));--tooltip-arrow:6px;--tooltip-delay:0.5s}.hint,[class*=" hint-"],[class^=hint-]{position:relative}.hint:before,[class*=" hint-"]:before,[class^=hint-]:before{border-style:solid;height:0;position:absolute;width:0;--tw-content:"";border-color:var(--tooltip-bg) transparent transparent transparent;border-width:var(--tooltip-arrow) var(--tooltip-arrow) 0 var(--tooltip-arrow);content:var(--tw-content);margin-bottom:calc(0px - var(--tooltip-arrow))}.hint:after,[class*=" hint-"]:after,[class^=hint-]:after{background-color:var(--tooltip-bg);border-color:var(--tooltip-color);border-radius:var(--radius);color:var(--tooltip-text);font-size:.75rem;line-height:1rem;max-width:28rem;overflow:hidden;padding:.25rem .5rem;position:absolute;white-space:nowrap;--tw-shadow:0 3px 8px 0 rgba(0,0,0,.04),0 1px 2px -1px rgba(0,0,0,.01);--tw-shadow-colored:0 3px 8px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-content:attr(data-hint);content:var(--tw-content);text-shadow:0 1px 0 var(--tooltip-bg)}.hint:after,.hint:before,[class*=" hint-"]:after,[class*=" hint-"]:before,[class^=hint-]:after,[class^=hint-]:before{bottom:100%;left:50%;opacity:0;pointer-events:none;transition-delay:0s;transition-duration:.15s;transition-property:opacity,visibility;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-timing-function:cubic-bezier(.4,0,1,1);visibility:hidden;z-index:1800;--tw-translate-x:-50%;--tw-translate-y:calc(var(--tooltip-arrow)*-1);transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hint:hover:after,.hint:hover:before,[class*=" hint-"]:hover:after,[class*=" hint-"]:hover:before,[class^=hint-]:hover:after,[class^=hint-]:hover:before{opacity:1;transition-delay:var(--tooltip-delay);visibility:visible}.hint-bottom:before{border-color:transparent transparent var(--tooltip-bg) transparent;border-width:0 var(--tooltip-arrow) var(--tooltip-arrow) var(--tooltip-arrow);margin-bottom:auto;margin-top:calc(0px - var(--tooltip-arrow))}.hint-bottom:after,.hint-bottom:before{bottom:auto;top:100%;--tw-translate-y:var(--tooltip-arrow);transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hint-left:before{border-color:transparent transparent transparent var(--tooltip-bg);border-width:var(--tooltip-arrow) 0 var(--tooltip-arrow) var(--tooltip-arrow);margin-bottom:auto;margin-right:calc(0px - var(--tooltip-arrow))}.hint-left:after,.hint-left:before{bottom:50%;left:auto;right:100%;--tw-translate-x:calc(var(--tooltip-arrow)*-1);--tw-translate-y:50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hint-right:before{border-color:transparent var(--tooltip-bg) transparent;border-width:var(--tooltip-arrow) var(--tooltip-arrow) var(--tooltip-arrow) 0;margin-bottom:auto;margin-left:calc(0px - var(--tooltip-arrow))}.hint-right:after,.hint-right:before{bottom:50%;left:100%;--tw-translate-x:var(--tooltip-arrow);--tw-translate-y:50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hint-lg:after,.hint-sm -.hint-md:after:after,.hint-xl:after{white-space:normal;word-break:break-all}.hint-sm:after{width:4rem}.hint-md:after{width:8rem}.hint-lg:after{width:16rem}.hint-xl:after{width:24rem}.hint-primary{--tooltip-bg:var(--color-primary-500)}.hint-success{--tooltip-bg:var(--color-success-500)}.hint-danger{--tooltip-bg:var(--color-danger-500)}.hint-warning{--tooltip-bg:var(--color-warning-500)}.hint-important{--tooltip-bg:var(--color-important-500)}.hint-special{--tooltip-bg:var(--color-special-500)}.tooltip{background-color:var(--tooltip-bg);border-color:var(--tooltip-color);border-radius:var(--radius);color:var(--tooltip-text);font-size:.75rem;line-height:1rem;max-width:28rem;padding:.25rem .5rem;white-space:pre-wrap;z-index:1800}.tooltip:not(.white)>.arrow{border-width:0}.tooltip.white>.arrow{border-color:inherit}.tooltip-has-title{--tw-bg-opacity:0.8;padding:.5rem .75rem .75rem;--tw-shadow:0 10px 25px -5px rgba(0,0,0,.2),0 4px 10px -6px rgba(0,0,0,.15);--tw-shadow-colored:0 10px 25px -5px var(--tw-shadow-color),0 4px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-backdrop-blur:blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.tooltip-has-title>.arrow{opacity:.75}.tooltip-heading{align-items:center;display:flex;font-size:.8125rem;font-weight:700;gap:1rem;justify-content:space-between;line-height:1.25rem;padding:.25rem}.tooltip-heading>.btn-close{margin-right:-.25rem}.tooltip-content{padding:.25rem}.tree-item-inner{flex-direction:row;min-height:24px;padding-left:var(--list-nested-indent)}.tree-item-inner,.tree-toggle{align-items:center;display:flex}.tree-toggle{border-radius:var(--radius);flex:none;height:1rem;justify-content:center;margin-right:-.375rem;width:1rem;--caret-size:5px;--caret-opacity:.3}.tree-item-inner>.item-icon{opacity:.5;width:1rem}.tree-item-inner:hover>.item-icon{opacity:.8}.tree-item-inner.has-hover{border-radius:var(--radius)}.tree-item-inner .item-title:not(:hover),.tree-item-inner>a.item-title:not(:hover){color:inherit}.tree-item-inner>.toolbar{margin-left:1rem;opacity:.6}.tree-item-inner:hover>.toolbar{opacity:1}.tree-item>.active{background:var(--menu-active-bg);color:var(--menu-active-color)}.tree-item>.selected{background:var(--menu-selected-bg)}.tree-item>.selected .item-content{color:var(--menu-selected-color);font-weight:700}.tree.search-menu-on-top>.search-box{left:0;right:0}.tree-lines .tree{position:relative}.tree-lines .tree-item{--tree-line-indent:calc(var(--list-nested-indent) + 8px)}.tree-lines .tree:before{border-left-width:1px;bottom:.5rem;display:block;left:var(--tree-line-indent);position:absolute;top:-.5rem;--tw-content:"";content:var(--tw-content)}.upload .upload-tip{--tw-text-opacity:1;color:rgba(var(--color-gray-400-rgb),var(--tw-text-opacity,1))}.upload .draggable-area{background-color:rgba(var(--color-primary-50-rgb),.2);border:1px dashed var(--color-primary-300)}.upload .draggable-area.dragover{background-color:rgba(var(--color-primary-500-rgb),.1);border-style:solid}.upload .upload-tip{color:var(--color-slate-500)}.file-item>.img{height:120px;width:120px}.upload .file-item:hover .file-size{display:flex!important}.form-batch-container{overflow-y:auto}.form-batch-table{min-width:100%;table-layout:fixed;--table-head-bg:var(--color-canvas)}.form-batch-table>*>tr{--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1))}.form-batch-table>*>tr>*{padding-left:.375rem;padding-right:.375rem;vertical-align:top}.form-batch-table>*>tr>th{text-align:left;vertical-align:middle}.form-batch-head[data-name=ACTIONS]{width:5rem}.form-batch-head[data-name=ACTIONS][data-action-count="3"]{width:6rem}.form-batch-label{display:inline}.form-batch-control>textarea.form-control{height:2rem}.form-batch-btn+.btn{margin-left:.25rem}.form-batch-table>tbody[data-count="1"] .form-batch-btn[data-type=delete]{display:none}.form-batch-ditto{position:relative}.form-batch-ditto-btn{bottom:0;height:auto;opacity:.5;padding-left:.5rem;padding-right:.5rem;position:absolute!important;right:0;top:0}.form-batch-ditto-btn:after{bottom:.5rem;left:-1px;position:absolute;top:.5rem;width:1px;--tw-bg-opacity:1;background-color:rgba(var(--color-border-rgb),var(--tw-bg-opacity,1));--tw-content:"";content:var(--tw-content)}[data-ditto=on] .form-batch-ditto-btn{--tw-text-opacity:1;color:rgba(var(--color-primary-500-rgb),var(--tw-text-opacity,1));opacity:1}td.form-batch-row-actions{padding-bottom:.75rem!important;padding-top:.75rem!important}.form-batch-ditto-wrapper{position:relative}.form-batch-ditto-control .form-control,.form-batch-ditto-control .pick-pri{padding-right:calc(var(--form-batch-ditto-width) + 8px)}.form-batch-ditto-control .input-control>.input-control-suffix{right:var(--form-batch-ditto-width)}.form-batch-ditto-control .input-control>.form-control{padding-right:calc(var(--form-batch-ditto-width) + var(--input-control-suffix))}.has-fixed-actions .form-batch-col-actions{position:sticky;right:0;z-index:1;--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1))}.form-batch-col-actions.is-pinned:before{background-image:linear-gradient(-90deg,transparent,transparent),linear-gradient(-90deg,transparent,transparent 50%);border-right-width:1px;bottom:0;content:" ";display:block;left:-1rem;position:absolute;top:0;transition-duration:.15s;transition-property:background;transition-timing-function:cubic-bezier(.4,0,.2,1);width:1rem;z-index:1}.form-batch:hover .form-batch-col-actions.is-pinned:before{background-image:linear-gradient(-90deg,rgba(0,0,0,.03),transparent),linear-gradient(-90deg,rgba(0,0,0,.03),transparent 50%)}.panel-form-batch .form-batch-container .form-batch-col-actions.is-pinned:after{bottom:0;display:block;position:absolute;right:-1rem;top:0;width:1rem;z-index:1;--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1));content:" "}.datalist{--datalist-label-width:68px}.datalist-item{display:flex;gap:.5rem;padding-bottom:.375rem;padding-top:.375rem}.datalist-item-label{align-items:center;display:flex;flex:none;justify-content:flex-end;overflow:hidden;white-space:nowrap;width:var(--datalist-label-width);--tw-text-opacity:1;color:rgba(var(--color-gray-500-rgb),var(--tw-text-opacity,1))}.datalist-item-content{align-items:center;display:flex;flex:1 1 0%;gap:.5rem}.deliverable-items{border-radius:var(--radius);border-width:1px}.deliverable-category{align-items:stretch;-moz-column-gap:1rem;column-gap:1rem;display:flex;min-height:3rem}.deliverable-category+.deliverable-category{border-top-width:1px}.deliverable-category-name{align-items:center;border-right-width:1px;display:flex;flex:none;justify-content:center;padding:.25rem .5rem;width:var(--deliverable-category-width,100px)}.required .deliverable-category-name>.text{display:block;position:relative;text-align:center}.required .deliverable-category-name>.text:after{font-size:1rem;line-height:1.5rem;position:absolute;right:-.75rem;top:0;--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity,1));--tw-content:"*";content:var(--tw-content)}.deliverable-item-row{align-items:center;-moz-column-gap:1rem;column-gap:1rem;display:flex;min-height:3rem;padding:.25rem .5rem}.deliverable-item-doc,.deliverable-item-file{align-items:center;display:flex;gap:.25rem;min-width:200px}.deliverable-item-actions{flex:1 1 auto}.deliverable-item-avatar{align-items:center;display:flex;gap:.25rem;white-space:nowrap}.deliverable-item-info{flex:1 1 auto;overflow:hidden;white-space:nowrap;--tw-text-opacity:1;color:rgba(var(--color-gray-500-rgb),var(--tw-text-opacity,1))}.deliverable-item-avatar+.deliverable-item-info{margin-left:-.75rem}.deliverable-item-doc-picker{width:14rem}.deliverable-item-rename{align-items:center;display:flex;gap:.5rem}.deliverable-item-rename .form-control{flex:1 1 auto;width:18rem}.deliverable-item .form-tip{line-height:28px;margin:0;padding-left:7rem;position:relative;top:-.5rem;width:100%}.scrollbar,:root{--scrollbar-size:10px;--scrollbar-opacity:.6;--scrollbar-bg:rgba(var(--color-inverse-rgb),.15);--scrollbar-inset:inset 0 0 0 1px rgba(var(--color-inverse-rgb),.05);--scrollbar-bar-bg:rgba(var(--color-inverse-rgb),.3);--scrollbar-hover-bg:rgba(var(--color-inverse-rgb),.4);--scrollbar-drag-bg:rgba(var(--color-inverse-rgb),.5);--scrollbar-radius:var(--radius-sm);--scrollbar-duration:.7s}.scrollbar{background:var(--scrollbar-bg);box-shadow:var(--scrollbar-shadow);opacity:var(--scrollbar-opacity);position:absolute;transition-duration:.15s;transition-duration:var(--scrollbar-duration);transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1)}.scrollbar-hover .scrollbar{opacity:0}.scrollbar-hover:hover .scrollbar{opacity:var(--scrollbar-opacity)}.scrollbar.is-dragging,.scrollbar:hover{opacity:1!important}.scrollbar-bar{background:var(--scrollbar-bar-bg);border-radius:var(--scrollbar-radius);position:absolute}.scrollbar-bar:hover{background:var(--scrollbar-hover-bg)}.is-dragging>.scrollbar-bar{background:var(--scrollbar-drag-bg)}.is-horz>.scrollbar-bar{height:100%;z-index:20}.is-vert>.scrollbar-bar{width:100%;z-index:20}.htmldiff{--htmldiff-color-insert-rgb:var(--color-success-600-rgb);--htmldiff-color-delete-rgb:var(--color-danger-500-rgb)}.htmldiff ins[data-operation-index]{background:rgba(var(--htmldiff-color-insert-rgb),.1);border-left:2px solid rgba(var(--htmldiff-color-insert-rgb),.2);border-right:2px solid rgba(var(--htmldiff-color-insert-rgb),.2);color:rgba(var(--htmldiff-color-insert-rgb,1));text-decoration:none}.htmldiff del[data-operation-index]{color:rgba(var(--htmldiff-color-delete-rgb,1));text-decoration:line-through}.affine-theme,.affine-theme [data-theme=dark],.affine-theme [data-theme=light]{--affine-brand-color:var(--color-primary-500);--affine-primary-color:var(--color-primary-500);--affine-text-primary-color:var(--color-fore);--affine-font-family:var(--font-family-sans);--affine-font-serif-family:var(--font-family-serif);--affine-font-mono-family:var(--font-family-mono)}.blocksuite-portal{position:absolute!important}.embed-card-modal-mask{z-index:12!important}.embed-card-modal-wrapper{z-index:13!important}.affine-code-block-container .line-number{opacity:.5}@-moz-document url-prefix(){.affine-code-block-container v-line{width:100%}}.affine-list-block__prefix{color:inherit!important}.embed-zui-iframe{border-radius:var(--radius-lg);border-width:1px}affine-bookmark .affine-block-component{border-width:0}.is-editor-empty.is-editing .affine-block-children-container>affine-paragraph:first-child .affine-paragraph-placeholder:not(.visible){display:block!important}database-datasource-note-renderer{display:none!important}.editor{--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1))}.editor-is-exporting audio,.editor-is-exporting canvas,.editor-is-exporting embed,.editor-is-exporting iframe,.editor-is-exporting img,.editor-is-exporting object,.editor-is-exporting svg,.editor-is-exporting video{display:initial!important}body>.affine-modal{align-items:center;background-color:var(--modal-bg);bottom:0!important;display:flex;justify-content:center;left:0!important;position:fixed!important;right:0!important;top:0!important}body>.affine-modal>center-peek{left:auto;max-width:1200px;position:relative;top:auto;--tw-shadow:0 0 #0000!important;--tw-shadow-colored:0 0 #0000!important;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)!important}body>.affine-modal affine-data-view-record-detail{border-radius:var(--radius);overflow:auto;--tw-shadow:0 10px 25px -5px rgba(0,0,0,.2),0 4px 10px -6px rgba(0,0,0,.15);--tw-shadow-colored:0 10px 25px -5px var(--tw-shadow-color),0 4px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);max-height:calc(100vh - 40px)}body>.affine-modal>center-peek>.close-modal{height:2rem;right:.75rem;top:.75rem;width:2rem;z-index:10}body>.affine-modal>center-peek>.close-modal>svg{height:1rem;width:1rem}.affine-database-column-stats{margin-left:0!important}.editor.is-readonly .database-header-bar+uni-lit,.editor.is-readonly .unsupported-content{display:none}.form-control .editor,.form-group .editor{border-radius:var(--form-control-radius);--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1));outline-color:transparent;outline-style:solid;outline-width:1px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:var(--form-control-border);transition-duration:.15s;transition-property:outline,box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1);--affine-editor-width:initial;--affine-editor-bottom-padding:24px!important;--affine-editor-side-padding:16px!important;min-height:200px}.detail-section .editor,.section .editor{--affine-editor-width:initial;--affine-editor-bottom-padding:0!important;--affine-editor-side-padding:0px!important}.form-control .has-pick-checks .affine-page-root-block-container,.form-group .has-pick-checks .affine-page-root-block-container{padding-left:40px!important;padding-right:calc(var(--affine-block-selection-side-width) + 12px)!important;--affine-block-selection-side-width:100px}.form-control .affine-page-viewport,.form-group .affine-page-viewport{overflow:visible}.editor page-editor{display:flex;flex-direction:column}.editor .affine-page-viewport,.editor .affine-page-viewport>editor-host{display:flex;flex:1 1 auto;flex-direction:column}.editor .affine-page-viewport>editor-host>affine-page-root{flex:1 1 auto;padding:1px}.form-control .editor page-editor,.form-group .editor page-editor{height:100%}.dtable .toggle-icon{margin-top:0;opacity:.5;position:static!important;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.editor-block-pick-options{display:none}affine-block-selection.is-last-picked .editor-block-pick-options{display:flex}.editor .toggle-icon{align-items:center}.affine-layout-block-container>affine-zui-layout-cell .affine-block-selection-side{left:0;top:32px}.affine-layout-block-container>affine-zui-layout-cell:last-child .affine-block-selection-side{left:calc(100% + 12px);top:0}.history-panel>.panel-heading+.panel-body{margin-top:-.75rem}.history-panel-action{position:relative}.history-panel-action:before{border-left-width:1px;bottom:-.375rem;left:.5rem;position:absolute;top:22px;--tw-border-opacity:1;border-color:rgba(var(--color-border-rgb),var(--tw-border-opacity,1));--tw-content:"";content:var(--tw-content)}.col-reverse>.history-panel-action:first-child:before,.col>.history-panel-action:last-child:before{display:none}.history-panel-action>.item-inner{padding-left:1.5rem}.history-panel-action>.item-inner>.avatar{left:0;position:absolute;top:.375rem}.history-panel-action .file-list-item .item-content{flex:none}.history-panel-action blockquote{margin-top:.25rem;--tw-bg-opacity:1;background-color:rgba(var(--color-surface-rgb),var(--tw-bg-opacity,1));padding:.25rem .25rem .25rem .5rem}.history-panel-action blockquote.original{display:none}.doc-app{--doc-view-max-width:unset;--doc-view-padding:24px 40px;--doc-view-side-width:240px;--affine-editor-side-padding:0}.doc-app{align-items:stretch;display:flex;flex-direction:column;min-height:120px}.doc-space-picker-menu .menu-item>.item-inner{padding-right:.25rem}.doc-app-search .form-control{border-radius:var(--radius-full)}.doc-app-search .input-control-prefix{cursor:pointer;opacity:.75}.doc-app-search.empty:not(.focus){transition-duration:.15s;transition-property:width;transition-timing-function:cubic-bezier(.4,0,.2,1);width:2rem}.doc-app-search.empty:not(.focus) .form-control{padding-left:.5rem;padding-right:.5rem;--tw-ring-color:transparent}.doc-app-search.empty:not(.focus) .form-control::-moz-placeholder{opacity:0}.doc-app-search.empty:not(.focus) .form-control::placeholder{opacity:0}.doc-app-search.empty:not(.focus) .form-control:hover{--tw-bg-opacity:1;background-color:rgba(var(--color-gray-100-rgb),var(--tw-bg-opacity,1))}.doc-app-search:not(.empty) .form-control{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-50-rgb),var(--tw-bg-opacity,1));--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-primary-300-rgb),var(--tw-ring-opacity,1))}.doc-app-header .divider{height:1rem!important;margin-left:.25rem!important;margin-right:.25rem!important}.doc-app .is-match-keys{--tw-bg-opacity:1;background-color:rgba(var(--color-warning-100-rgb),var(--tw-bg-opacity,1));font-weight:700;text-decoration-line:underline;text-underline-offset:2px}.doc-main .dtable-footer{border-bottom-width:1px;--tw-border-opacity:1;border-bottom-color:rgba(var(--color-border-rgb),var(--tw-border-opacity,1))}.doc-main.show-view>.doc-list{pointer-events:none;visibility:hidden;z-index:-10}.has-doc-app-fullscreen #mainNavbar,.has-doc-app-fullscreen .doc-app-header,.has-doc-app-fullscreen .doc-sidebar,.has-doc-app-fullscreen>#header{display:none!important}.has-doc-app-fullscreen #mainContainer{max-width:none!important;padding:0!important;width:100%!important}.has-doc-app-fullscreen #docApp{height:calc(100vh - 12px)!important}.doc-app doc-title,.editor-is-exporting .doc-editor-title{display:none}.editor-is-exporting doc-title{display:block}.doc-app .affine-page-root-block-container{margin:0;max-width:100%}.doc-app-nav .pick-diff .btn{--skin-hover-bg:var(--color-primary-100);--skin-hover-text:var(--color-primary-500)}.doc-app-nav .pick-diff .btn.gray-pale{border-radius:9px;gap:3px;height:18px;padding-left:5px;padding-right:3px}.doc-app-nav .pick-diff .btn.ghost{border-radius:2px;height:18px;min-width:auto;padding:0;width:18px}.doc-tree .item-inner{cursor:pointer;padding-right:0;position:relative}.doc-tree .item-inner>.item-icon{flex:none;opacity:1}.doc-tree .item-inner .item-title{overflow:hidden;text-overflow:clip;white-space:nowrap}.doc-tree .item-inner.selected .item-title{font-weight:700}.doc-tree .item-inner>.toolbar{top:.25rem!important}.doc-tree .item-inner>.toolbar>.btn.with-popover-show,.doc-tree .list-heading-inner>.toolbar{opacity:1!important}.doc-tree .item-inner:hover>.toolbar{margin-top:0!important}.doc-tree .with-hover-actions>.item>.item-inner .item-actions{right:0}.doc-sidebar .sortable-ghost{border-radius:var(--radius-sm);z-index:10;--tw-bg-opacity:1;background-color:rgba(var(--color-warning-100-rgb),var(--tw-bg-opacity,1));opacity:.3;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-warning-600-rgb),var(--tw-ring-opacity,1))}.doc-tree [z-key=project-files]{border-top:1px solid rgba(var(--color-border-rgb),var(--tw-border-opacity));margin-top:.25rem;padding-top:.25rem}.doc-list-item-title{overflow:hidden;text-overflow:clip}.doc-view{scroll-padding-top:16px;scrollbar-gutter:stable both-edges}.doc-view-content{max-width:var(--doc-view-max-width);padding:var(--doc-view-padding)}.doc-files .item-title{overflow:hidden;white-space:nowrap}.doc-files .file-list-item{border-radius:var(--radius-lg);transition-duration:.15s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1)}.doc-files .file-list-item:hover{background-color:rgba(var(--color-inverse-rgb),.05)}.doc-files .file-list-item .item-actions,.doc-files .file-list-item:hover .item-actions{margin-left:1rem;margin-top:0;position:relative}.doc-files .file-list-item .item-actions .btn{--tw-text-opacity:1;color:rgba(var(--color-link-rgb),var(--tw-text-opacity,1))}.doc-editor .affine-page-viewport{overflow:visible!important}.doc-editor .affine-page-root-block-container{max-width:100%;padding:0 0 2rem!important}.doc-editor-keywords,.doc-editor-title{flex:none;max-width:100%;min-width:0}.doc-editor-keywords:hover .form-control{--tw-bg-opacity:1;background-color:rgba(var(--color-gray-100-rgb),var(--tw-bg-opacity,1))}.doc-editor-keywords .form-control:focus{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-50-rgb),var(--tw-bg-opacity,1));--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);outline:2px solid transparent;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.doc-editor-control{z-index:2}.doc-view-sidebar{display:flex;flex-direction:column;max-height:calc(100% - 24px);overflow:visible;width:var(--doc-view-side-width)}.doc-view-sidebar-nav{--nav-item-padding:6px;--nav-item-color:var(--color-gray-500);--nav-active-bg:var(--color-primary-100);--nav-active-color:var(--color-fore);--nav-item-height:26px;--nav-divider-margin:8px;background-color:rgba(var(--color-surface-rgb),.2)}.doc-view-sidebar .datalist{--datalist-label-width:56px}.is-closed.doc-view-sidebar .doc-view-sidebar-content,.is-sidebar-closed .doc-view-sidebar-content{display:none}.is-closed.doc-view-sidebar,.is-sidebar-closed .doc-view-sidebar{--doc-view-side-width:0;opacity:0;transition-delay:1s;transition-duration:1s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1)}.is-outline.doc-view-sidebar{--doc-view-side-width:260px}.doc-view:hover .doc-view-sidebar{opacity:1;transition-delay:0s}.is-closed>.doc-view-sidebar-container,.is-sidebar-closed .doc-view-sidebar-container{position:absolute;right:0;top:0}.doc-view-sidebar-container{background-color:rgba(var(--color-canvas-rgb),.8);min-height:0;--tw-backdrop-blur:blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.doc-outline .listitem{position:relative}.doc-outline .tree-toggle.is-empty:before{border-radius:var(--radius-full);height:.25rem;position:absolute;width:.25rem;--tw-bg-opacity:1;background-color:rgba(var(--color-gray-300-rgb),var(--tw-bg-opacity,1));--tw-content:"";content:var(--tw-content)}.doc-outline .is-nested-root.no-nested-items{padding-left:.375rem}.doc-view input{font-family:inherit}.doc-diff ins[data-operation-index]{background:rgba(208,246,232,.4);border-left:2px solid #dfd;border-right:2px solid #dfd;color:#0ca76f;text-decoration:none}.doc-diff del[data-operation-index]{color:#d91b1b;text-decoration:line-through}.doc-path-picker .picker-deselect-btn{display:none}.doc-path-picker-angle{margin-left:-.125rem;margin-right:-.125rem}.doc-path-picker,.doc-space-picker{outline:2px solid transparent!important;outline-offset:2px!important;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)!important;--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color)!important;box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)!important}.doc-path-picker-toggle.btn{flex:none;--btn-height:18px;--skin-hover-bg:var(--color-primary-100);--skin-hover-text:var(--color-primary-500)}.doc-path-picker-toggle>.icon{--tw-scale-x:1.25;--tw-scale-y:1.25;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.doc-toolbar-align-menu{align-items:center;display:flex!important;flex-direction:row;flex-wrap:nowrap}.doc-toolbar-align-menu>.menu-item>a>.item-icon{opacity:1}.doc-toolbar-align-menu>.menu-item>a>.item-content{display:none}.dropmenu-btn{gap:.25rem;padding-left:.5rem;padding-right:.5rem}.dropmenu-btn>.text{max-width:180px;overflow:hidden}.dropmenu-btn>.is-leading{left:-.625rem;opacity:.6;position:absolute}.dropmenu-btn>.is-caret{align-items:center;background-color:rgba(var(--color-canvas-rgb),.2);border-radius:var(--radius);display:flex;height:1rem;justify-content:center;width:1rem}.dropmenu-nav{border-bottom-width:1px;margin-left:.75rem;margin-right:.75rem;margin-top:.25rem}.has-search .dropmenu-nav{margin-top:-.5rem}.dropmenu-nav>.nav-secondary{gap:.5rem}.dropmenu-nav>.nav-secondary>.nav-item>a{border-radius:var(--radius);padding-left:.5rem;padding-right:.5rem}.dropmenu-nav>.nav-secondary>.nav-item>a:after{bottom:-1px;left:1rem;opacity:0;right:1rem}.dropmenu-nav>.nav-secondary>.nav-item>.active:after{left:.5rem;opacity:1;right:.5rem;transition-duration:.15s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1)}.dropmenu-title{font-size:.75rem;font-weight:700;line-height:1rem;margin-bottom:-.5rem;padding:.75rem;--tw-text-opacity:1;color:rgba(var(--color-gray-500-rgb),var(--tw-text-opacity,1))}.dropmenu-list{min-height:0;overflow-x:hidden;overflow-y:auto;padding:.5rem .75rem}.dropmenu.loading>*{opacity:0}.dropmenu-item .tree-item-inner{border-radius:var(--radius);cursor:pointer;transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1)}.dropmenu-item.is-item.active>.tree-item-inner{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-50-rgb),var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgba(var(--color-primary-500-rgb),var(--tw-text-opacity,1))}.tree-item-inner.is-link:hover{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-500-rgb),var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgba(var(--color-canvas-rgb),var(--tw-text-opacity,1))}.tree-item-inner.is-link:hover .item-content,.tree-item-inner.is-link:hover .item-trailing-icon,.tree-item-inner.is-link:hover .label{color:inherit}.tree-item-inner.is-toggle:hover{--tw-bg-opacity:1;background-color:rgba(var(--color-gray-100-rgb),var(--tw-bg-opacity,1))}.dropmenu-item+.tree-item{margin-top:.125rem}.dropmenu-item .is-match{font-weight:700;text-decoration-line:underline}.dropmenu-item .item-title,.dropmenu-item .label{overflow:hidden;white-space:nowrap}.dropmenu-item .item-content{padding-left:.375rem;padding-right:.375rem}.dropmenu-item *+.item-content{padding-left:0}.tree-item-inner.is-toggle .item-title{opacity:.6}.tree-item-inner.is-toggle:hover .item-title{opacity:1}.dropmenu-item-check{align-items:center;display:flex;flex:1 1 auto;justify-content:flex-end;padding-right:.5rem}.dropmenu-item .nested-toggle-icon.is-empty{width:.25rem}.dropmenu-item .item-icon{margin-right:-.25rem}.card-list{--list-gap:.625rem;--list-count-per-row:1}.card-list,.card-list-item{padding:calc(var(--list-gap)/2)}.card-list-item{width:calc(100%/var(--list-count-per-row))}.card-grid{display:flex;flex-wrap:wrap}.card-grid .card{height:100%}:root{--form-control-border:var(--color-border-strong)}.checkbox-primary.disabled,.checkbox-primary.disabled>label,.checkbox-primary>input[type=checkbox]:disabled,.checkbox-primary>input[type=checkbox]:disabled+label,.radio-primary.disabled,.radio-primary.disabled>label,.radio-primary>input[type=radio],.radio-primary>input[type=radio]:disabled+label{filter:none!important}.checkbox-primary.disabled>label,.radio-primary.disabled>label{opacity:1}.checkbox-primary.disabled>label:before,.radio-primary.disabled>label:before{background-color:rgba(var(--color-inverse-rgb),.05);opacity:.5}.form-actions{gap:1rem;justify-content:center}.form-actions .btn{min-width:96px}.form-control-static{min-height:32px;padding-bottom:.375rem;padding-top:.375rem}:root{--zt-panel-form-max-width:1000px}.size-sm{--zt-panel-form-max-width:800px}.size-lg{--zt-panel-form-max-width:1200px}.panel-body>.container,.panel-heading>.container{max-width:var(--panel-container-width);min-width:0;padding-left:var(--panel-container-padding);padding-right:var(--panel-container-padding)}.panel-heading>.container{align-items:center;display:flex;flex-direction:row;flex-wrap:nowrap;gap:1rem;justify-content:space-between;min-height:48px}.panel-form{border-radius:var(--radius-md);margin-bottom:1rem;margin-left:auto;margin-right:auto;max-width:var(--zt-panel-form-max-width);min-width:var(--zt-panel-form-min-width);overflow:visible;--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1));padding-bottom:1rem;padding-left:1rem;padding-right:1rem;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.panel-form .form-actions{background-color:rgba(var(--color-canvas-rgb),.8);bottom:0;padding-bottom:1rem;padding-top:1rem;position:sticky;z-index:3;--tw-backdrop-blur:blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.panel-form .form-grid{margin-left:calc(0px - var(--form-grid-gap-y-half));margin-right:calc(0px - var(--form-grid-gap-y-half));padding-bottom:0}.panel-form-toolbar{padding-left:var(--form-grid-gap-x-half);padding-right:var(--form-grid-gap-x-half);width:100%}.panel-form-toolbar>.toolbar{gap:1rem;padding-bottom:.75rem;padding-top:.75rem}.panel-form-divider{margin-bottom:.75rem;margin-top:1rem;padding-left:var(--form-grid-gap-x-half);padding-right:var(--form-grid-gap-x-half);width:100%}.panel-form-divider:before{background-color:rgba(var(--color-border-rgb),.7);display:block;height:1px;--tw-content:"";content:var(--tw-content)}.is-full .btn-full-form,.is-lite .btn-lite-form{z-index:1;--tw-bg-opacity:1;background-color:rgba(var(--color-primary-50-rgb),var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgba(var(--color-primary-500-rgb),var(--tw-text-opacity,1));--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-primary-300-rgb),var(--tw-ring-opacity,1))}.btn-toggle-fold:after{content:attr(data-expand-text)}.show-fold-items .btn-toggle-fold:after{content:attr(data-collapse-text)}.is-foldable,.is-full .full\:hidden,.is-full .lite\:visible,.is-full .panel-form-divider,.is-full .panel-form-toolbar,.is-lite .full\:visible,.is-lite .lite\:hidden,.no-foldable-items .btn-toggle-fold{display:none}.is-foldable.is-pinned,.is-full .full\:visible,.is-full .is-foldable,.is-full .lite\:hidden,.is-lite .full\:hidden,.is-lite .lite\:visible,.show-fold-items .is-foldable{display:block}.is-full .full\:w-1\/2,.is-lite .lite\:w-1\/2{width:50%}.is-full .full\:w-1\/3,.is-lite .lite\:w-1\/3{width:33.333333%}.is-full .full\:w-2\/3,.is-lite .lite\:w-2\/3{width:66.666667%}.is-full .full\:w-1\/4,.is-lite .lite\:w-1\/4{width:25%}.is-full .full\:w-2\/4,.is-lite .lite\:w-2\/4{width:50%}.is-full .full\:w-3\/4,.is-lite .lite\:w-3\/4{width:75%}.is-full .full\:w-1\/5,.is-lite .lite\:w-1\/5{width:20%}.is-full .full\:w-2\/5,.is-lite .lite\:w-2\/5{width:40%}.is-full .full\:w-3\/5,.is-lite .lite\:w-3\/5{width:60%}.is-full .full\:w-4\/5,.is-lite .lite\:w-4\/5{width:80%}.is-full .full\:w-1\/6,.is-lite .lite\:w-1\/6{width:16.666667%}.is-full .full\:w-2\/6,.is-lite .lite\:w-2\/6{width:33.333333%}.is-full .full\:w-3\/6,.is-lite .lite\:w-3\/6{width:50%}.is-full .full\:w-4\/6,.is-lite .lite\:w-4\/6{width:66.666667%}.is-full .full\:w-5\/6,.is-lite .lite\:w-5\/6{width:83.333333%}.is-full .full\:w-full,.is-lite .lite\:w-full{width:100%}.page-form{--panel-container-width:960px;--panel-container-padding:20px;--zt-panel-form-max-width:1200px;--zt-panel-form-min-width:1040px;padding-left:0;padding-right:0;--tw-shadow:0 1px 2px 0 rgba(0,0,0,.04),0 0 2px -1px rgba(0,0,0,.01);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color),0 0 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.page-form .panel-heading{border-bottom-width:1px;--tw-border-opacity:0.7;padding:0}.page-form .panel-title{font-size:1rem;line-height:1.5rem}@media (max-width:1240px){.page-form{--zt-panel-form-max-width:1100px}}@media (max-width:1110px){.page-form{--zt-panel-form-max-width:1040px}}.modal-body>.page-form{margin:-1.5rem -2rem!important;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.modal-body>.page-form>.panel-heading{border-top-left-radius:var(--radius);border-top-right-radius:var(--radius);position:sticky;top:-1.25rem;z-index:2;--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1));padding-bottom:.375rem;padding-top:.375rem}.modal-body>.panel-form .form-actions{bottom:-1.5rem!important;padding-bottom:1.5rem;padding-top:1.5rem}.gantt-container .gantt_message_area{display:none}.gantt-container .gantt_grid_head_owner_id{text-align:left}.gantt-container .gantt_grid_head_cell.gantt_grid_head_text{overflow:visible}.gantt-container .gantt_grid_head_cell,.gantt_scale_cell{color:#000!important}.gantt-container .gantt_grid_scale,.gantt_task_scale,.gantt_task_vscroll{background-color:#f2f7ff}.gantt-container .gantt_row{cursor:pointer}.gantt-container .gantt_row>div:first-child .gantt_tree_content{color:#3c4353}.gantt-container .gantt_row_task:hover .submitBtn{display:inline-block}.gantt-container .gantt_link_arrow_right{border-left-color:#2196f3}.gantt-container .gantt_link_arrow_left{border-right-color:#2196f3}.gantt-container .gantt_tree_content table{width:100%}.gantt-container .gantt_tree_content table td{padding:0!important}.gantt-container .gantt_tree_content{color:#838a9d}.gantt-container .gantt_task_content .icon-seal,.gantt-container .gantt_task_content span.task-label,.gantt_task_content span.label-pri{display:none}.gantt-container .gantt_task_line{overflow:visible}.gantt-container .gantt_task_line.gantt_selected{box-shadow:0 1px 1px rgba(0,0,0,.05),0 2px 6px 0 rgba(0,0,0,.045)}.gantt-container .gantt_task_line.gantt_task_inline_color{border:0}.gantt-container .gantt_task_link .gantt_line_wrapper div{background-color:#2196f3}.gantt-container .gantt_task_link.start_to_start .gantt_line_wrapper div{background-color:#dd55ea}.gantt-container .gantt_task_link.start_to_start:hover .gantt_line_wrapper div{box-shadow:0 0 5px 0 #dd55ea}.gantt-container .gantt_task_link.start_to_start .gantt_link_arrow_right{border-left-color:#dd55ea}.gantt-container .gantt_task_link.finish_to_start .gantt_line_wrapper div{background-color:#7576ba}.gantt-container .gantt_task_link.finish_to_start:hover .gantt_line_wrapper div{box-shadow:0 0 5px 0 #7576ba}.gantt-container .gantt_task_link.finish_to_start .gantt_link_arrow_right{border-left-color:#7576ba}.gantt-container .gantt_task_link.finish_to_finish .gantt_line_wrapper div{background-color:#55d822}.gantt-container .gantt_task_link.finish_to_finish:hover .gantt_line_wrapper div{box-shadow:0 0 5px 0 #55d822}.gantt-container .gantt_task_link.finish_to_finish .gantt_link_arrow_left{border-right-color:#55d822}.gantt-container .gantt_task_link.start_to_finish .gantt_line_wrapper div{background-color:#975000}.gantt-container .gantt_task_link.start_to_finish:hover .gantt_line_wrapper div{box-shadow:0 0 5px 0 #975000}.gantt-container .gantt_task_link.start_to_finish .gantt_link_arrow_left{border-right-color:#975000}.gantt-container .gantt_critical_link .gantt_line_wrapper>div{background-color:#e63030!important}.gantt-container .gantt_critical_link.finish_to_start .gantt_link_arrow_right,.gantt-container .gantt_critical_link.start_to_start .gantt_link_arrow_right{border-left-color:#e63030!important}.gantt-container .gantt_critical_link.finish_to_finish .gantt_link_arrow_left,.gantt-container .gantt_critical_link.start_to_finish .gantt_link_arrow_left{border-right-color:#e63030!important}.gantt-container .gantt_critical_task{background:#e63030!important;border-color:#9d3a3a!important}.gantt-container .gantt_marker .gantt_marker_content{background-color:#f51e1e;left:-15px}.gantt-container .submitBtn{display:none}.gantt-container .editDeadline{color:#fff!important;display:none;line-height:normal!important;padding:2px 6px}.gantt-container td:hover>.editDeadline{display:inline-block!important}.gantt-container .icon-confirm{color:#18a6fd;font-size:18px}.gantt-container .icon-seal{font-size:18px}.gantt-container div.delayed{background:#ffebeb;color:#fb2b2b}.gantt-container [class*=" pri-"]{max-width:unset}.dropdown.popover{display:flex;flex-direction:column;position:absolute;z-index:1200}.dropdown.show{display:flex}.dropdown-menu{display:none;--menu-min-width:7rem;--menu-max-width:20rem}.dropdown-menu.show,.menu-wrapper>.dropdown-menu,.show>.dropdown-menu{display:block}.dropdown>.dropdown-menu,.menu-wrapper .dropdown-menu{position:relative}.popup .popup.search-menu{background-color:var(--menu-bg)}.show>.menu-wrapper{display:flex}.dropdown>.menu-wrapper{height:100%}.dropdown>.menu-wrapper .menu-wrapper{position:absolute}.dropdown>.menu-wrapper.is-tree .menu-wrapper{position:relative}.is-contextmenu .is-nested-show>a:not(:hover){--tw-bg-opacity:1;background-color:rgba(var(--color-primary-100-rgb),var(--tw-bg-opacity,1))}.is-contextmenu .menu-item.is-nested>.item-inner>.nested-toggle-icon{position:absolute;right:.25rem;top:.375rem}.is-contextmenu .menu-nested .menu-item>.item-inner{padding-left:.5rem;padding-right:1.25rem}.is-contextmenu .menu-nested .menu-item>.item-inner>.item-content{overflow:hidden}.dropdown>.arrow{--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1))}.global-search-panel li:not(.order-first):hover{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-500-rgb),var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgba(var(--color-canvas-rgb),var(--tw-text-opacity,1))}.global-search-panel li a{width:100%}.global-search-panel li{cursor:pointer}.img-cutter{background:var(--color-gray-100);border:1px solid #ddd;margin-bottom:20px;padding:10px}.img-cutter .canvas{margin:0 auto;max-width:100%;min-width:50px;position:relative}.img-cutter .cover{bottom:0;left:0;position:absolute;right:0;top:0;z-index:1}.img-cutter .controller{background:none;border:1px dashed hsla(0,0%,100%,.7);cursor:move;position:absolute;z-index:5}.img-cutter .control{background:#000;background:rgba(0,0,0,.6);border:1px solid hsla(0,0%,100%,.6);height:6px;position:absolute;width:6px}.img-cutter .control[data-type=left]{cursor:w-resize;left:-4px;margin-top:-3px;top:50%}.img-cutter .control[data-type=top]{cursor:n-resize;left:50%;margin-left:-3px;top:-4px}.img-cutter .control[data-type=right]{cursor:e-resize;margin-top:-3px;right:-4px;top:50%}.img-cutter .control[data-type=bottom]{bottom:-4px;cursor:s-resize;left:50%;margin-left:-3px}.img-cutter .control[data-type=top-left]{cursor:nw-resize;left:-4px;top:-4px}.img-cutter .control[data-type=top-right]{cursor:ne-resize;right:-4px;top:-4px}.img-cutter .control[data-type=bottom-left]{bottom:-4px;cursor:sw-resize;left:-4px}.img-cutter .control[data-type=bottom-right]{bottom:-4px;cursor:se-resize;right:-4px}.img-cutter .cliper{bottom:0;left:0;position:absolute;right:0;top:0;z-index:2}.messager-lite{border-radius:var(--radius-lg);min-width:160px;--tw-bg-opacity:1!important;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1))!important;padding:1rem 1.5rem;--tw-text-opacity:1!important;color:rgba(var(--color-fore-rgb),var(--tw-text-opacity,1))!important;--skin-ring:transparent!important;--skin-text:inherit!important;--skin-color:var(--color-gray-500)}.messager-lite .alert-icon{color:var(--skin-color);font-size:1.5rem;line-height:2rem}.messager-lite .alert-text{font-size:.875rem;font-weight:700;line-height:1.3rem}.messager-lite .toolbar{gap:.5rem;margin-left:2rem}.messager-lite .alert-content+.alert-close{margin-left:1.5rem}.messager-lite .toolbar .btn.ghost{--tw-text-opacity:1;color:rgba(var(--color-primary-500-rgb),var(--tw-text-opacity,1))}.modal-reconfirm .modal-body{font-size:14px;font-weight:700;padding:24px 32px}.modal-reconfirm .modal-footer{justify-content:center;padding:24px}.pick{align-items:center;display:flex;flex-direction:row;justify-content:flex-start;position:relative}.color-picker{justify-content:center}.pick>.text{align-items:center;display:flex;flex:1 1 auto;min-width:0;overflow:hidden;white-space:nowrap}.pick>.text>.placeholder{--tw-text-opacity:1;color:rgba(var(--color-placeholder-rgb),var(--tw-text-opacity,1))}.picker-deselect-btn{opacity:.6;transition-duration:.15s;transition-property:opacity,transform;transition-timing-function:cubic-bezier(.4,0,.2,1)}.picker-multi-selection{cursor:pointer;padding-right:.5rem;position:relative}.picker-multi-selection .picker-deselect-btn{bottom:0;left:0;position:absolute;right:0;top:0;--tw-scale-x:0;--tw-scale-y:0;background-color:rgba(var(--color-surface-rgb),.8);opacity:0}.picker-deselect-btn:hover,.picker-multi-selection .picker-deselect-btn,.picker-multi-selection:hover .picker-deselect-btn{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.picker-deselect-btn:hover,.picker-multi-selection:hover .picker-deselect-btn{--tw-scale-x:1;--tw-scale-y:1;opacity:1;--state-color:rgba(var(--color-surface-rgb),.9)}.pick-pri{flex-direction:row;justify-content:flex-start;position:relative}.pick-pri,.pick-pri>.text{align-items:center;display:flex}.pick-pri>.text{flex:1 1 auto;min-width:0;overflow:hidden;white-space:nowrap}.pick-pri .placeholder{--tw-text-opacity:1;color:rgba(var(--color-placeholder-rgb),var(--tw-text-opacity,1))}.pick-pri-list>.btn{justify-content:flex-start}.disabled.pick-pri,.disabled.pick-pri>*{filter:none}.pick-diff{border:none!important;box-shadow:none!important;outline:none!important;padding:0!important}.pick-diff .diff-picker-trigger{align-items:center;display:flex;gap:4px}.pick-diff .btn{gap:.25rem;min-width:32px;padding-left:.5rem;padding-right:.5rem}.pick-diff .switch-diff{padding:0}.pick-diff .switch-diff .icon{font-size:18px}.pick-diff-pop .diff-pop{display:flex;flex-direction:column;max-height:300px;min-width:136px;-webkit-user-select:none;-moz-user-select:none;user-select:none}.pick-diff-pop .diff-pop>menu{flex:1;overflow-y:auto}.pick-diff-pop .diff-pop-header{align-items:center;display:flex;justify-content:space-between;padding:8px 8px 2px}.pick-diff-pop .diff-pop-header>span{flex-shrink:0}.pick-diff-pop .diff-pop-footer{align-items:center;display:flex;justify-content:space-between;padding:2px 8px 8px}.pick-diff-pop .menu-item>a{justify-content:start}.pick-range-list{max-height:100%;overflow:auto;padding:.25rem .5rem}.pick-range-list-item,.pick-range-list-row{align-items:center;display:flex}.pick-range-list-item{height:1.75rem;justify-content:center;margin-bottom:.125rem;margin-top:.125rem;position:relative;width:1.75rem}.pick-range-list-item:hover{border-radius:var(--radius);outline-color:rgb(var(--color-border-strong-rgb));outline-style:solid;z-index:10}.pick-range-list-item.is-from,.pick-range-list-item.is-to{border-radius:var(--radius);--tw-bg-opacity:1;background-color:rgba(var(--color-primary-400-rgb),var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgba(var(--color-canvas-rgb),var(--tw-text-opacity,1))}.pick-range-list-item.is-in{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-100-rgb),var(--tw-bg-opacity,1))}.pick-range-list-item.has-small-text>.text{--tw-scale-x:.75;--tw-scale-y:.75}.pick-range-list-item.has-small-text:hover,.pick-range-list-item.has-small-text>.text{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.pick-range-list-item.has-small-text:hover{position:relative;z-index:10;--tw-scale-x:1.25;--tw-scale-y:1.25}.pick-range-list-item.is-col-end{margin-right:1rem}.pick-range-list-item.is-col-end:after{border-right-width:1px;bottom:-.125rem;display:block;position:absolute;right:-.5rem;top:-.125rem;--tw-content:"";content:var(--tw-content)}.search-form{--gutter-width:12px;padding-bottom:.5rem}.search-form-container{border-radius:var(--radius);min-height:116px;position:relative;--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1));--tw-shadow:0 3px 8px 0 rgba(0,0,0,.04),0 1px 2px -1px rgba(0,0,0,.01);--tw-shadow-colored:0 3px 8px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-border-rgb),var(--tw-ring-opacity,1))}.is-simple .search-form-container{min-height:56px}.search-form-field td{padding:.375rem}.search-form-field td.is-andOr,.search-form-field td.is-operator{width:5rem}.search-form-field td.is-condition{width:7rem}.search-form-field td.is-operator{width:5rem}[lang=en] .search-form-field td.is-operator{width:6rem}.search-form .sidebar-right.is-collapsed{margin-right:-.375rem}.is-simple .search-form-wrapper{display:flex}.is-simple .search-form-wrapper>.row{flex:1 1 auto}.is-simple .search-form-wrapper>.toolbar{flex:none;margin-top:0}zen-editor-menu-item,zen-editor-menu-item>.menu-item{align-items:center;color:#64758b!important;display:flex;height:26px;justify-content:center;margin:0!important;min-width:24px;padding-left:2px;padding-right:2px}zen-editor-menu-item>.menu-item:hover{background-color:var(--color-gray-200)!important;color:var(--color-primary-400)!important}zen-editor-menu-item>.menu-item.is-active{background-color:transparent!important;box-shadow:inset 0 0 0 1px var(--color-primary-300);color:var(--color-primary-400)!important}zen-editor-menu-item>.menu-item.is-active:hover{background-color:var(--color-gray-200)!important}zen-editor-menu-item>.menu-item.is-active:not(:hover){background-color:transparent!important}zen-editor-menu-item>.menu-item:has(.color).is-active,zen-editor-menu-item>.menu-item:has(.color):hover{background-color:transparent!important;box-shadow:inset 0 0 0 1px var(--color-primary-300)!important}.zen-editor-menu-submenu{background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1))!important;border-radius:var(--radius);border-style:none!important;--tw-bg-opacity:0.85;--tw-shadow:0 10px 25px -5px rgba(0,0,0,.2),0 4px 10px -6px rgba(0,0,0,.15);--tw-shadow-colored:0 10px 25px -5px var(--tw-shadow-color),0 4px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:rgba(var(--color-inverse-rgb),var(--tw-ring-opacity,1));--tw-ring-opacity:0.05;--tw-backdrop-blur:blur(16px);align-items:center;-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);display:flex;justify-content:center}.ci-bar_top,.ci-bold,.ci-code,.ci-combine_cells,.ci-font,.ci-heading,.ci-heading_h1,.ci-heading_h2,.ci-heading_h3,.ci-heading_h4,.ci-image_02,.ci-italic,.ci-link,.ci-list_ordered,.ci-list_unordered,.ci-paragraph,.ci-strikethrough,.ci-swatches_palette,.ci-table,.ci-text,.ci-underline,.ci-unlink,.ci-window_code_block{font-size:1em!important}.ci-swatches_palette:before{content:"\ea23";font-family:ZentaoIcon}.ci-font:before{content:"\ea20";font-family:ZentaoIcon}.ci-text:before{content:"\e929";font-family:ZentaoIcon}.ci-bold:before{content:"\e953";font-family:ZentaoIcon}.ci-italic:before{content:"\e955";font-family:ZentaoIcon}.ci-underline:before{content:"\ea2b";font-family:ZentaoIcon}.ci-strikethrough:before{content:"\ea2c";font-family:ZentaoIcon}.ci-link:before{content:"\e94d";font-family:ZentaoIcon}.ci-unlink:before{content:"\ea51";font-family:ZentaoIcon}.ci-heading:before{content:"\e954";font-family:ZentaoIcon}.ci-heading_h1:before{content:"\ea25";font-family:ZentaoIcon}.ci-heading_h2:before{content:"\ea26";font-family:ZentaoIcon}.ci-heading_h3:before{content:"\ea27";font-family:ZentaoIcon}.ci-heading_h4:before{content:"\ea28";font-family:ZentaoIcon}.ci-code:before{content:"\e990";font-family:ZentaoIcon}.ci-window_code_block:before{content:"\ea39";font-family:ZentaoIcon}.ci-list_unordered:before{content:"\e9a8";font-family:ZentaoIcon}.ci-list_ordered:before{content:"\e969";font-family:ZentaoIcon}.ci-image_02:before{content:"\e96c";font-family:ZentaoIcon}.ci-table:before{content:"\e96d";font-family:ZentaoIcon}.ci-combine_cells:before{content:"\ea48";font-family:ZentaoIcon}.is-active>.ci-combine_cells:before{content:"\ea47";font-family:ZentaoIcon}.ci-paragraph:before{content:"\ea50";font-family:ZentaoIcon}.ci-bar_top:before{content:"\e96b";font-family:ZentaoIcon}.is-active>.ci-bar_top:before{content:"\e972";font-family:ZentaoIcon}.zinbar [data-hint]{position:relative}.zinbar [data-hint]:after{background-color:rgba(var(--color-inverse-rgb),var(--tw-bg-opacity,1));border-top-left-radius:var(--radius-lg);border-top-right-radius:var(--radius-lg);bottom:100%;display:block;pointer-events:none;position:absolute;right:0;white-space:nowrap;z-index:50;--tw-bg-opacity:0.9;font-size:.75rem;line-height:1rem;padding:.125rem .25rem;--tw-text-opacity:1;color:rgba(var(--color-canvas-rgb),var(--tw-text-opacity,1));opacity:0;transition-duration:.15s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);--tw-content:attr(data-hint);content:var(--tw-content)}.zinbar [data-hint]:hover:after{opacity:1}.zin-perf-btn-list .text-danger{color:var(--color-danger-400)}.zinbar .state{transition-duration:.15s;transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1)}.zinbar .state:active{--tw-scale-x:1.05;--tw-scale-y:1.05}.zinbar .state:active,.zinbar.collapse{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.zinbar.collapse{--tw-translate-x:100%}.zinbar.collapse>div{pointer-events:none}.zinbar{--tw-translate-x:0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));transition-duration:.7s;transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1)}body[z-perf=danger]:before,body[z-perf=warning]:before{bottom:0;left:0;pointer-events:none;position:fixed;right:0;top:0;z-index:9990;--tw-border-opacity:1;border-color:rgba(var(--color-warning-600-rgb),var(--tw-border-opacity,1));font-size:.75rem;line-height:1rem;--tw-content:"";border-style:inset;border-width:12px 8px 8px;content:var(--tw-content)}body[z-perf=danger]:before{--tw-border-opacity:1;border-color:rgba(var(--color-danger-600-rgb),var(--tw-border-opacity,1))}body[z-perf=danger]:after,body[z-perf=warning]:after{font-size:.75rem;font-weight:700;left:0;line-height:1rem;line-height:1;pointer-events:none;position:fixed;right:0;text-align:center;top:0;z-index:9991;--tw-text-opacity:1;color:rgba(var(--color-white-rgb),var(--tw-text-opacity,1));--tw-content:attr(z-perf-message);content:var(--tw-content)}.card{border-radius:var(--radius);min-height:28px;position:relative;--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1));--tw-shadow:0 1px 2px 0 rgba(0,0,0,.04),0 0 2px -1px rgba(0,0,0,.01);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color),0 0 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:rgba(var(--color-border-rgb),var(--tw-ring-opacity,1));--tw-ring-opacity:0.05;transition-duration:.15s;transition-property:box-shadow,border,color,background-color;transition-timing-function:cubic-bezier(.4,0,.2,1)}.card:hover{--tw-shadow:0 2px 6px -1px rgba(0,0,0,.2),0 1px 4px -2px rgba(0,0,0,.15);--tw-shadow-colored:0 2px 6px -1px var(--tw-shadow-color),0 1px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.card-content,.card-footer,.card-header,.card-heading{padding:.25rem .5rem}.card-heading{align-items:center;display:flex;gap:.5rem}.card-icon{opacity:.5}.card-header{--tw-bg-opacity:1;background-color:rgba(var(--color-surface-rgb),var(--tw-bg-opacity,1))}.card-content{display:flex;flex-direction:column;gap:.25rem}.card-actions{position:absolute;right:.125rem;top:.125rem}.card-actions+.card-heading{padding-right:1.75rem}.card-subtitle{font-size:.75rem;line-height:1rem;--tw-text-opacity:1;color:rgba(var(--color-gray-500-rgb),var(--tw-text-opacity,1))}.card.selected{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-50-rgb),var(--tw-bg-opacity,1));--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-primary-400-rgb),var(--tw-ring-opacity,1))}.card-list{--list-gap:.625rem;--list-count-per-row:1}.card-list,.card-list-item{padding:calc(var(--list-gap)/2)}.card-list-item{width:calc(100%/var(--list-count-per-row))}.card-grid{display:flex;flex-wrap:wrap}.card-grid .card{height:100%}.contextmenu{display:none}.contextmenu.show{display:block}.contextmenu .popup .popup,.contextmenu.popup{position:absolute}.more,.more-vert{margin:.5rem;position:relative}.more,.more-vert,.more-vert:after,.more-vert:before,.more:after,.more:before{background-color:currentColor;border-radius:var(--radius-full);height:.125rem;width:.125rem}.more-vert:after,.more-vert:before,.more:after,.more:before{display:block;left:-5px;position:absolute;top:0;--tw-content:"";content:var(--tw-content)}.more-vert:after,.more:after{left:5px}.more-vert{--tw-rotate:90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.dashboard-blocks{position:relative}.dashboard-block-cell{position:absolute;transition-duration:.15s;transition-property:left,top;transition-timing-function:cubic-bezier(.4,0,.2,1)}.dashboard-block{border-radius:var(--radius);bottom:.5rem;left:.5rem;position:absolute;right:.5rem;top:.5rem;--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1));transition-duration:.15s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1)}.dashboard-block.is-dragging{opacity:0;z-index:1600}.dashboard-block-header{align-items:center;border-top-left-radius:var(--radius);border-top-right-radius:var(--radius);display:flex;flex-direction:row;justify-content:space-between;left:0;padding:.75rem;pointer-events:none;position:absolute;right:0;top:0;z-index:10}.dashboard-block-header>*{pointer-events:auto}.dashboard-block-title{font-size:.875rem;font-weight:700;line-height:1.3rem}.dashboard-block-body{bottom:0;left:0;position:absolute;right:0;top:0}.dashboard-block-body>.panel{display:flex;flex-direction:column;height:100%;width:100%;--tw-shadow:0px 6px 16px rgba(202,215,235,.25)}.dashboard-block-body .panel-heading{cursor:move;flex:none}.dashboard-block-body .panel-body{flex:1 1 auto;overflow-y:auto}.has-more-menu>.dashboard-block-body .panel-heading{padding-right:3rem}.dashboard-block-body .panel-title{font-size:.875rem;height:2rem;line-height:1.3rem}.dashboard-block-actions .btn{opacity:.6}.dashboard-block-actions .btn:hover{opacity:1}.dashboard-drop-shadow{position:absolute;transition-duration:.15s;transition-property:left,top;transition-timing-function:cubic-bezier(.4,0,.2,1)}.dashboard-drop-shadow:before{background-color:rgba(var(--color-inverse-rgb),.05);border-radius:var(--radius);bottom:.5rem;left:.5rem;position:absolute;right:.5rem;top:.5rem;--tw-shadow:inset 0 2px 4px 0 rgba(0,0,0,.05);--tw-shadow-colored:inset 0 2px 4px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-content:"";content:var(--tw-content)}:root{--dtable-checked-bg:var(--color-warning-50);--dtable-checked-bg-hover:var(--color-warning-100);--dtable-checked-border:var(--color-border-strong)}.dtable-cell.is-checked,.dtable-striped .dtable-cell.is-odd-row.is-checked{background-color:var(--dtable-checked-bg)}.checkbox-primary.dtable-checkbox{margin-right:-.375rem}.dtable-checkbox{order:-5}.dtable-hover-col .dtable-cell.is-hover-col.is-checked,.dtable-hover-row .dtable-cell.is-hover-row.is-checked{background-color:var(--dtable-checked-bg-hover)}.dtable-cell.is-checked{--dtable-border-color:var(--dtable-checked-border)}.dtable-check-info{flex-shrink:1;margin-right:.5rem;overflow:hidden;white-space:nowrap}:root{--toggle-icon-size:calc(var(--font-size-root)*3/4 + 1px)}.toggle-icon,.toggle-icon-collapse,.toggle-icon-expand{border-color:currentColor;border-width:1px;display:block;opacity:.5;position:relative}.toggle-icon-collapse:hover,.toggle-icon-expand:hover,.toggle-icon:hover{opacity:.9}.toggle-icon,.toggle-icon-collapse,.toggle-icon-expand{border-radius:inherit;height:var(--toggle-icon-size);width:var(--toggle-icon-size)}.is-collapsed .toggle-icon:after,.is-collapsed .toggle-icon:before,.is-expanded .toggle-icon:before,.toggle-icon-collapse:after,.toggle-icon-collapse:before,.toggle-icon-expand:before{background-color:currentColor;content:" ";display:block;height:1px;left:2px;position:absolute;right:2px;top:calc((var(--toggle-icon-size) - 3px)/2)}.is-collapsed .toggle-icon:after,.toggle-icon-collapse:after{--tw-rotate:90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}:root{--dtable-nt-size:calc(var(--font-size-root)*3/4 + 1px)}.dtable-nested-indent{flex:none;margin-right:-.25rem;order:-100}.dtable-nested-toggle{align-items:center;border-radius:var(--radius-sm);display:flex;flex:none;height:1.25rem;justify-content:center;margin-left:-.25rem;order:-6;width:1.25rem}.dtable-nested-toggle.is-no-child{margin-right:-.25rem;opacity:0;pointer-events:none}.dtable-child-label{order:-5}.dtable-header-group{align-items:center;background:var(--dtable-header-bg);cursor:default;display:flex;justify-content:center;left:0;position:absolute;top:1px;z-index:30}.dtable-bordered .dtable-header-group{border-bottom:1px solid var(--dtable-border-color);border-left:1px solid var(--dtable-border-color)}.dtable-header-as-group{contain:style;content-visibility:visible;overflow:visible!important}.dtable-sorting{cursor:move}.dtable-cell.is-sorting-from{background-color:var(--dtable-bg);z-index:20}.dtable-cell.is-sorting-from:before{border-top-width:1px}.dtable-sorting .dtable-cell.is-sorting-after{--tw-translate-y:-100%}.dtable-sorting .dtable-cell.is-sorting-after,.dtable-sorting .dtable-cell.is-sorting-before{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.dtable-sorting .dtable-cell.is-sorting-before{--tw-translate-y:100%}.dtable-cell.is-sorting-before:before,.dtable-cell.is-sorting-from:before{border-bottom-width:1px;border-top-width:1px}.dtable{--dtable-bg:var(--color-canvas);--dtable-striped-bg:var(--color-gray-50);--dtable-hover-bg:rgba(var(--color-primary-500-rgb),.05);--dtable-header-bg:var(--color-surface);--dtable-footer-bg:var(--color-surface);--dtable-border-color:var(--color-border);--dtable-sorter-size:0.3125rem}.dtable{position:relative;--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1))}.dtable.no-animation *{transition-property:none!important}.dtable-block{overflow:hidden;position:absolute;width:100%}.dtable-header{background-color:var(--dtable-header-bg);border-top-left-radius:inherit;border-top-right-radius:inherit}.dtable-body{overflow:hidden}.dtable-cells{background-color:var(--dtable-bg);height:100%;position:absolute;z-index:0}.dtable-cells-container{height:100%;position:absolute;width:100%}.dtable-header .dtable-cells{background-color:var(--dtable-header-bg)}.dtable-cells.dtable-fixed-left,.dtable-cells.dtable-fixed-right{z-index:10}.dtable-cell{position:absolute;transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,transform;transition-timing-function:cubic-bezier(.4,0,.2,1)}.dtable-cell:after,.dtable-cell:before{bottom:0;content:"";left:0;opacity:0;pointer-events:none;position:absolute;right:0;top:-1px;z-index:2}.dtable-cell:before{border-bottom-width:1px;border-color:var(--dtable-border-color);opacity:1}.dtable-header-cell{align-items:center;display:flex;font-weight:700}.dtable-header-cell:after,.dtable-header-cell:before{top:0}.dtable-cell-content{align-items:center;display:flex;gap:.25rem;height:100%;overflow:hidden;padding-left:.75rem;padding-right:.75rem;position:relative;white-space:nowrap;width:100%;z-index:5}.dtable-body .dtable-cell.is-last-row:before{border-bottom-width:0}.dtable-footer{align-items:center;background-color:var(--dtable-footer-bg);border-bottom-left-radius:inherit;border-bottom-right-radius:inherit;border-color:var(--dtable-border-color);border-top-width:1px;display:flex;padding-left:.75rem;padding-right:.75rem;position:absolute;width:100%;z-index:10}.dtable-empty-tip{align-items:center;display:flex;height:100%;justify-content:center}.dtable .scrollbar{z-index:20}.dtable-header{transition-duration:1s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1)}.dtable-scrolled-down .dtable-header{border-bottom-color:rgba(var(--color-inverse-rgb),.15);border-bottom-width:1px}.dtable-has-scroll-y:not(.dtable-scrolled-bottom) .dtable-footer{border-top-color:rgba(var(--color-inverse-rgb),.15);border-top-width:1px}.dtable-scroll-shadow{background-image:linear-gradient(90deg,rgba(0,0,0,.03),transparent),linear-gradient(90deg,rgba(0,0,0,.03),transparent 50%);opacity:0;pointer-events:none;position:absolute;top:0;transition-duration:1s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);width:8px;z-index:20}.dtable:hover .dtable-scroll-shadow{opacity:1}.dtable-scroll-shadow.is-right{margin-left:-7px;--tw-rotate:180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.dtable-scroll-shadow.is-left,.dtable-scrolled-end .dtable-scroll-shadow.is-right{visibility:hidden}.dtable-scroll-shadow.is-right,.dtable-scrolled-right .dtable-scroll-shadow.is-left{visibility:visible}.scrollbar-hover:hover .scrollbar{opacity:0}.scrollbar-hover .dtable-body:hover~.scrollbar{opacity:var(--scrollbar-opacity)}.dtable-sort{display:inline-flex;height:calc(var(--dtable-sorter-size)*12/5);margin-left:.25rem;opacity:.8;position:relative}.dtable-cell:hover .dtable-sort{opacity:1}.dtable-sort:after,.dtable-sort:before{border-color:transparent;border-style:solid;height:0;left:0;opacity:.4;position:absolute;width:0;--tw-content:"";border-width:var(--dtable-sorter-size);content:var(--tw-content)}.dtable-sort:before{border-bottom-color:currentColor;border-top-width:0;top:0}.dtable-sort:after{border-bottom-width:0;border-top-color:currentColor;bottom:0}.dtable-sort.dtable-sort-asc:before,.dtable-sort.dtable-sort-desc:after{opacity:.9}.dtable-sort-link{align-items:center;cursor:pointer;display:inline-flex}.dtable-cells.dtable-fixed-left:before,.dtable-cells.dtable-fixed-right:before{border-color:var(--dtable-border-color);content:"";height:100%;pointer-events:none;position:absolute;width:100%;z-index:5}.dtable-cells.dtable-fixed-left:before{border-right-width:1px;right:-1px}.dtable-cells.dtable-fixed-right:before{border-left-width:1px;left:0}.dtable-bordered:before{border-color:var(--dtable-border-color);border-radius:inherit;border-width:1px;bottom:0;content:"";display:block;left:0;pointer-events:none;position:absolute;right:0;top:0;z-index:15}.dtable-bordered .dtable-cell:before{border-width:1px;right:-1px}.dtable-cell.has-border-left:before{border-left-width:1px}.dtable-cell.has-border-right:before{border-right-width:1px;right:-1px}.dtable-striped .dtable-cell.is-odd-row{background-color:var(--dtable-striped-bg)}.dtable-hover-cell .dtable-cell:hover:after,.dtable-hover-col .dtable-cell.is-hover-col:before,.dtable-hover-row .dtable-body .dtable-cell.is-hover-row:before{background-color:var(--dtable-hover-bg)}.kanban,.kanban-list{--kanban-lane-name-width:20px;--kanban-col-width:280px;--kanban-cols-gap:8px;--kanban-lanes-gap:8px;--kanban-header-height:32px;--kanban-lane-height:auto;--kanban-lane-color:var(--color-primary-500);--kanban-link-color:var(--color-secondary-600)}.kanban{align-items:flex-start;display:flex;flex-direction:column;min-width:-moz-fit-content;min-width:fit-content;position:relative}.kanban-header{display:flex;flex-direction:row;height:var(--kanban-header-height)}.kanban.has-sub-cols .kanban-header{height:calc(var(--kanban-header-height)*2)}.kanban-header-lane-name{background-color:rgba(var(--color-fore-rgb),.05);flex:none;width:var(--kanban-lane-name-width)}.kanban-header-cols,.kanban-header-sub-cols{display:flex;flex:1 1 0%;flex-direction:row;gap:var(--kanban-cols-gap)}.kanban-header-sub-cols{border-top-width:2px;--tw-border-opacity:1;border-color:rgba(var(--color-canvas-rgb),var(--tw-border-opacity,1))}.kanban-header-col{align-items:center;border-bottom-width:1px;display:flex;flex:1 1 0%;flex-direction:column;height:100%;width:var(--kanban-col-width)}.kanban-header-col.has-subs{width:auto}.kanban-header-col-wrapper{align-items:center;display:flex;flex:1 1 0%;flex-direction:row;position:relative;width:100%;--tw-bg-opacity:1;background-color:rgba(var(--color-surface-rgb),var(--tw-bg-opacity,1));padding-left:3.5rem;padding-right:3.5rem}.kanban-header-col-wrapper.is-align-left{justify-content:flex-start;padding-left:.5rem}.kanban-header-col-wrapper.is-align-left>.kanban-header-title{justify-content:flex-start}.kanban-header-title{align-items:center;display:flex;flex:1 1 auto;flex-direction:row;justify-content:center;overflow:hidden}.kanban-header-title>.as-title{color:var(--kanban-col-color);font-weight:700;overflow:hidden;white-space:nowrap}.kanban-header-col-actions{bottom:.25rem;position:absolute;right:.25rem;top:.25rem}.kanban-header-col-actions>.btn{opacity:.6}.kanban-header-col-actions>.btn:hover{opacity:1}.kanban-body{display:flex;flex-direction:column;gap:var(--kanban-lanes-gap)}.kanban-lane{display:flex;flex-direction:row;height:var(--kanban-lane-height);min-height:96px}.kanban-lane-name{align-items:center;background-color:var(--kanban-lane-color);display:flex;justify-content:center;width:var(--kanban-lane-name-width);--tw-text-opacity:1;color:rgba(var(--color-white-rgb),var(--tw-text-opacity,1));writing-mode:vertical-rl}.kanban-lane-actions,.kanban-lane-name{flex:none;position:relative}.kanban-lane.is-first .kanban-lane-actions{margin-top:calc(4px - var(--kanban-header-height))}.has-sub-cols .kanban-lane.is-first .kanban-lane-actions{margin-top:calc(4px - var(--kanban-header-height)*2)}.kanban-lane-actions>.btn.square{width:var(--kanban-lane-name-width)}.kanban-lane-title{align-items:center;display:flex;flex:1 1 auto;justify-content:center;overflow:hidden;white-space:nowrap}.kanban-lane-cols{display:flex;flex-direction:row;gap:var(--kanban-cols-gap)}.kanban-lane-col{background-color:rgba(var(--color-inverse-rgb),.05);display:flex;flex-direction:column;height:100%;width:var(--kanban-col-width)}.kanban-header-col,.kanban-lane-col{margin-left:calc(var(--kanban-col-gap-left) - var(--kanban-cols-gap));margin-right:calc(var(--kanban-col-gap-right) - var(--kanban-cols-gap))}.kanban-col-content{position:relative;z-index:5}.kanban-lane.is-first>.kanban-lane-name:before{background-color:var(--kanban-lane-color);bottom:100%;display:block;height:var(--kanban-header-height);left:0;position:absolute;right:0;--tw-content:"";content:var(--tw-content)}.kanban.has-sub-cols .kanban-lane.is-first>.kanban-lane-name:before{height:calc(var(--kanban-header-height)*2)}.kanban-lane{margin-bottom:calc(var(--kanban-col-gap-bottom) - var(--kanban-lanes-gap));margin-top:calc(var(--kanban-col-gap-top) - var(--kanban-lanes-gap))}.kanban-items{flex:1 1 auto;overflow:auto;scrollbar-gutter:both-edges stable}.kanban-lane.is-auto-height .kanban-items{scrollbar-gutter:auto}.kanban-item{cursor:default}.kanban-item .card-actions{z-index:5}.kanban-heading{width:100%}.kanban-heading .listitem{height:2.25rem}.kanban-heading .item-title{font-weight:700}.kanban.has-dragging{cursor:move}.kanban-item.is-dragging{cursor:move;opacity:.1}.kanban-sticky .kanban-header{position:sticky;top:0;z-index:10;--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1))}.kanban-sticky .kanban-header.is-pinned{border-bottom-color:rgba(var(--color-inverse-rgb),.15);border-bottom-width:1px;z-index:20;--tw-shadow:0 1px 2px 0 rgba(0,0,0,.04),0 0 2px -1px rgba(0,0,0,.01);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color),0 0 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.kanban-sticky .kanban-lane-name{left:0;position:sticky;z-index:21}.kanban-region{border-radius:var(--radius);min-width:-moz-fit-content;min-width:fit-content;--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1));padding:.75rem;--tw-shadow:0 3px 8px 0 rgba(0,0,0,.04),0 1px 2px -1px rgba(0,0,0,.01);--tw-shadow-colored:0 3px 8px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.kanban-region>.kanban+.kanban{margin-top:.75rem}.kanban-region.has-heading{padding-top:0}.kanban-heading>.listitem{left:.75rem;position:sticky;width:calc(var(--kanban-list-width) - 24px)}.kanban-list{display:flex;flex-direction:column;gap:.75rem;height:100vh;overflow:auto;position:relative;scrollbar-gutter:stable}.kanban-list.is-moving{cursor:grabbing}.kanban-items.is-dropping{position:relative}.kanban-item.is-dropping{position:relative;transition-duration:.15s;transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1)}.kanban-item.is-dropping:after,.kanban-items.is-dropping>.card-list:after{background-color:rgba(var(--color-warning-500-rgb),.5);border-radius:var(--radius-full);display:block;height:.25rem;--tw-content:"";content:var(--tw-content)}.kanban-item.is-dropping:after{left:.25rem;position:absolute;right:.25rem;top:-.25rem}.kanban-item.is-dropping[z-drop-side=before]{--tw-translate-y:0.25rem}.kanban-item.is-dropping[z-drop-side=after],.kanban-item.is-dropping[z-drop-side=before]{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.kanban-item.is-dropping[z-drop-side=after]{--tw-translate-y:-0.25rem}.kanban-item.is-dropping[z-drop-side=after]:after{bottom:-.25rem;top:auto}.kanban-links{bottom:0;left:0;pointer-events:none;position:absolute;right:0;top:0;z-index:5}.kanban-list>.kanban-links{overflow:visible;z-index:11}.kanban-link{align-items:center;color:var(--kanban-link-color);display:flex;justify-content:center;position:absolute}.kanban-link>svg{position:absolute}.kanban-link-text{border-radius:var(--radius);height:1em;line-height:1;padding-left:.125rem;padding-right:.125rem;pointer-events:auto;position:relative;text-align:center;white-space:nowrap}.kanban-link-start-point{height:.5rem;width:.5rem;--tw-translate-x:-0.25rem;--tw-translate-y:-0.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.kanban-link-start-point,.kanban-link-start-point:before{background-color:currentColor;border-radius:var(--radius-full);position:absolute}.kanban-link-start-point:before{bottom:-.25rem;display:block;left:-.25rem;opacity:.2;right:-.25rem;top:-.25rem;--tw-content:"";content:var(--tw-content)}.kanban-link path{pointer-events:auto}.kanban-link path+path{opacity:.6}.kanban-link.is-hover path+path{opacity:1;stroke-width:calc(var(--kanban-link-weight)*1.5)}.kanban-link-delete-btn{pointer-events:auto;--tw-scale-x:.75;--tw-scale-y:.75;opacity:0;transition-duration:.15s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1)}.is-hover .kanban-link-delete-btn,.kanban-link-delete-btn{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.is-hover .kanban-link-delete-btn{--tw-scale-x:1;--tw-scale-y:1;opacity:1}.is-adding-link{cursor:crosshair;-webkit-user-select:none;-moz-user-select:none;user-select:none}.kanban-link-editor{bottom:0;left:0;pointer-events:none;position:absolute;right:0;top:0;z-index:20}.kanban-link-editor-from,.kanban-link-editor-to{border-radius:var(--radius);--tw-shadow-color:rgb(var(--color-primary-500-rgb));--tw-shadow:var(--tw-shadow-colored);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-primary-500-rgb),var(--tw-ring-opacity,1))}.kanban-link-editor-from,.kanban-link-editor-point,.kanban-link-editor-to{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);position:absolute}.kanban-link-editor-point{height:.5rem;pointer-events:auto;width:.5rem;--tw-translate-x:-0.25rem;--tw-translate-y:-0.25rem;border-radius:var(--radius-full);cursor:move;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-bg-opacity:1;background-color:rgba(var(--color-primary-500-rgb),var(--tw-bg-opacity,1));opacity:.5;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-color:rgba(var(--color-primary-500-rgb),0.1);transition-duration:.15s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1)}.kanban-link-editor-point.is-left{left:0;top:50%}.kanban-link-editor-point.is-right{right:0;top:50%;--tw-translate-x:0.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.kanban-link-editor-point.is-top{left:50%;top:0}.kanban-link-editor-point.is-bottom{bottom:0;left:50%;--tw-translate-y:0.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.kanban-link-editor-point:hover{opacity:1;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(8px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:rgba(var(--color-primary-500-rgb),0.5)}.tab-pane{display:none}.tab-pane.active{display:block}.has-sorting-col{cursor:move;--dtable-sorting-col-color:var(--color-primary-300);--dtable-hover-bg:transparent}.has-sorting-col .dtable-col-splitter{display:none}.dtable-cell.is-sorting-col-move{transition-duration:.15s;transition-property:left;transition-timing-function:cubic-bezier(.4,0,.2,1)}.dtable-cell.is-sorting-from-col{transition-duration:.1s}.dtable-cell.is-sorting-from-col:after{background-color:var(--dtable-sorting-col-color)!important;opacity:.1!important}.dtable-cell.is-sorting-from-col:before{border-left:1px solid var(--dtable-sorting-col-color);border-right:1px solid var(--dtable-sorting-col-color)}.dtable-header-cell.is-sortable-col{cursor:move}.has-sorting-col .scrollbar.is-horz{opacity:var(--scrollbar-opacity)!important}.has-sorting-col .dtable-scroll-shadow{visibility:visible}:root{--dtable-col-splitter-width:7px;--dtable-col-splitter-color:var(--color-primary-500)}.dtable-cell.has-col-resizing:after,.dtable-cell.has-col-splitter:hover:after{background:var(--dtable-col-splitter-color);opacity:.05}.dtable-col-splitter{background:var(--dtable-col-splitter-color);border-radius:var(--radius-full);bottom:0;cursor:ew-resize;opacity:0;position:absolute;right:calc(var(--dtable-col-splitter-width)/-2);top:0;transition-duration:.15s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);width:var(--dtable-col-splitter-width);z-index:20}.dtable-cell.has-col-splitter:hover .dtable-col-splitter{opacity:.3}.dtable-cell.has-col-resizing .dtable-col-splitter,.dtable-cell.has-col-splitter .dtable-col-splitter:hover{opacity:.5}.dtable.has-col-resizing .dtable-cell.has-col-splitter:not(.has-col-resizing) .dtable-col-splitter,.dtable.has-col-resizing .dtable-cell.has-col-splitter:not(.has-col-resizing):after{opacity:0}.dtable-col-splitter:after,.dtable-col-splitter:before{content:" ";display:block;height:.5rem;left:50%;margin-top:-.25rem;position:absolute;top:50%;width:1px;--tw-bg-opacity:1;background-color:rgba(var(--color-white-rgb),var(--tw-bg-opacity,1))}.dtable-col-splitter:before{margin-left:-1px}.dtable-col-splitter:after{margin-left:1px}.dtable.has-col-resizing{--dtable-hover-bg:transparent}.dtable.has-col-resizing,.has-col-resizing .dtable-header-cell{cursor:ew-resize!important}.dtable-cell.is-col-resizing:before{border-right:1px solid var(--dtable-col-splitter-color)}.dtable-cell.is-col-resizing:after{background:var(--dtable-col-splitter-color);opacity:.05}.has-col-resizing .scrollbar.is-horz{opacity:var(--scrollbar-opacity)!important}.dtable-cell.has-contextmenu-show:after{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-500-rgb),var(--tw-bg-opacity,1));opacity:.1}.dtable{--dtable-header-bg:var(--color-surface-light);--dtable-footer-bg:var(--color-surface-light);--dtable-border-color:var(--color-border-light);--dtable-checked-border:var(--color-border);--dtable-checked-bg:var(--color-primary-50);--dtable-checked-bg-hover:var(--color-primary-100);--dtable-hover-bg:rgba(var(--color-gray-500-rgb),.05);--dtable-link-color:var(--color-link);--dtable-link-hover-color:var(--color-link-hover);--dtable-link-visited-color:var(--color-link-visited)}.dtable-cell-content[style*="--color-link"]{--dtable-link-hover-color:var(--color-link);--dtable-link-visited-color:var(--color-link)}.dtable-body .dtable-cell a{--dtable-link-color:var(--color-link)}.dtable-body .dtable-cell a:not(.btn){color:var(--dtable-link-color)}.dtable-body .dtable-cell a:not(.btn):visited{color:var(--dtable-link-visited-color)}.dtable-body .dtable-cell a:not(.btn):hover{color:var(--dtable-link-hover-color)}.dtable .btn-avatar{border-radius:var(--radius-full);gap:.25rem;height:1.25rem;--tw-bg-opacity:1;background-color:rgba(var(--color-gray-100-rgb),var(--tw-bg-opacity,1));padding-left:0;padding-right:.5rem;--tw-ring-color:transparent}.dtable .btn-avatar:hover{--tw-shadow:0 3px 8px 0 rgba(0,0,0,.04),0 1px 2px -1px rgba(0,0,0,.01);--tw-shadow-colored:0 3px 8px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.dtable-nested-toggle{width:1rem}.dtable .toggle-icon{--toggle-icon-size:11px;border-radius:var(--radius);--tw-border-opacity:1;border-color:rgba(var(--color-gray-400-rgb),var(--tw-border-opacity,1))}.dtable .toggle-icon:after,.dtable .toggle-icon:before{--tw-bg-opacity:1;background-color:rgba(var(--color-gray-700-rgb),var(--tw-bg-opacity,1))}.dtable-footer>.toolbar{margin-right:.5rem}.dtable-header .dtable-cell[data-sort]>.dtable-cell-content>a:not(:hover){color:inherit}.dtable-assign-btn{align-items:center;border-radius:var(--radius-full);display:flex;flex-direction:row;height:1.25rem;padding-left:.375rem;padding-right:.375rem;--dtable-link-color:var(--color-fore)}.dtable-assign-btn:not(:hover){color:inherit}.dtable-assign-btn.is-me{--dtable-link-color:var(--color-warning-500)!important}.dtable-assign-btn:hover{--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1));--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-border-strong-rgb),var(--tw-ring-opacity,1))}.dtable-assign-btn>span{border-radius:var(--radius-full);line-height:20px;padding-left:.375rem;padding-right:.375rem}.dtable-assign-btn.is-unassigned>span{--tw-text-opacity:1;color:rgba(var(--color-gray-500-rgb),var(--tw-text-opacity,1));--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-border-strong-rgb),var(--tw-ring-opacity,1))}.dtable-assign-btn.is-unassigned:hover>span{background-color:inherit;color:inherit;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.dtable-assign-btn>.icon{opacity:0;transition-duration:.15s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1)}.dtable-assign-btn:not(.disabled):hover>.icon{opacity:1}.dtable-header .dtable-cell[data-type=assign]{padding-left:1.5rem}.dtable-cell-icon{order:-5}.dtable-custom-cell[data-type=control]{align-items:center;display:flex;justify-content:center;padding-left:.125rem;padding-right:.125rem;z-index:1}:root{--dtable-editing-color:var(--color-success-600)}.dtable-cell.is-editing:after{border-color:var(--dtable-editing-color);border-width:2px!important;opacity:1;z-index:20}.dtable-editing-input{height:100%;outline:2px solid transparent;outline-offset:2px;padding-left:.75rem;padding-right:.75rem;width:100%}:root{--dtable-selected-color:var(--color-success-500);--dtable-selected-bg:var(--color-success-50);--dtable-selecting-bg:var(--color-success-100);--dtable-highlight-color:var(--color-success-700)}.dtable-selectable{-webkit-user-select:none;-moz-user-select:none;user-select:none}.dtable-cell.is-select:after{border-color:var(--dtable-selected-color);border-width:1px;opacity:1;z-index:10}.dtable-cell.is-selecting{background:var(--dtable-selecting-bg)}.dtable-cell.is-selected{background:var(--dtable-selected-bg)}.dtable-cell.is-col-selected:after,.dtable-cell.is-row-selected[data-col=INDEX]:after{background-color:rgba(var(--color-inverse-rgb),.05);opacity:1}.dtable-cell.has-cell-selected{color:var(--dtable-highlight-color)}.dtable-cell.is-first-row.is-select:after{top:0}.dtable-cell.is-last-row.is-select:after{bottom:1px}.dtable-cell.is-first-in-row.is-select:after{left:1px}.dtable-cell.is-last-in-row.is-select:after{right:1px}.dtable-datagrid .dtable-cell[data-col=INDEX]{background:var(--dtable-header-bg)}.dtable-empty-tip{min-height:212px}.dtable-cell[data-type=actions] .btn>.icon{font-size:1rem;line-height:1.5rem}.menu.menu-dtable-actions.has-icons{align-items:center;display:flex;gap:.25rem;min-width:auto;--menu-icon-opacity:1}.menu.menu-dtable-actions.has-icons>.menu-item>a{padding-left:.25rem;padding-right:.25rem}.menu.menu-dtable-actions.has-icons>.menu-item>a>.icon-EMPTY,.menu.menu-dtable-actions.has-icons>.menu-item>a>.item-content{display:none}.menu.menu-dtable-actions.has-icons>.menu-item>a>.icon-EMPTY+.item-content,.menu.menu-dtable-actions.has-icons>.menu-item>a>.item-content:first-child{display:block}:root{--state-color:rgba(0,0,0,.03);--zt-page-bg:#f8f9fa;--zt-header-height:3rem;--zt-header-bg:var(--color-canvas);--zt-header-color:var(--color-fore);--zt-sidebar-width:160px;--zt-navbar-active-color:var(--color-primary-500)}body{background-color:var(--zt-page-bg)}.page-app{overflow:overlay}.container{min-width:1200px}#header{height:var(--zt-header-height);--tw-shadow:0 3px 8px 0 rgba(0,0,0,.04),0 1px 2px -1px rgba(0,0,0,.01);--tw-shadow-colored:0 3px 8px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color);background:var(--zt-header-bg);border-bottom:1px solid var(--zt-header-border,rgba(var(--color-inverse-rgb),.05));box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);color:var(--zt-header-color)}#header>.container{height:100%;position:relative}#heading{align-items:center;bottom:0;display:flex;gap:.25rem;left:1rem;position:absolute;top:0}#heading>.toolbar{margin-left:-.75rem}#heading .dropmenu-btn>.text{max-width:142px}#heading>[data-zui-dropmenu]+div .dropmenu-btn>.text,#heading>[data-zui-dropmenu]+div+div .dropmenu-btn>.text{max-width:78px}#navbar{align-items:center;display:flex;font-size:.875rem;height:100%;justify-content:center;line-height:1.3rem;--state-color:rgba(var(--color-primary-500-rgb),.05);--state-active-opacity:1;--state-active-color:rgba(var(--color-primary-500-rgb),.08)}#navbar>.nav{--nav-active-color:var(--zt-navbar-active-color,var(--color-current));--nav-item-padding:12px;--nav-divider-margin:8px;margin-left:var(--nav-offset-left)}#navbar>.nav>.nav-item>a{height:3rem;padding-left:var(--nav-item-padding);padding-right:var(--nav-item-padding)}#navbar>.nav>.nav-item>a:before{--tw-scale-x:1!important;--tw-scale-y:1!important;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)!important;--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color)!important;box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)!important}#navbar>.nav>.nav-item>a.active:before{background:var(--state-active-color)!important;opacity:1!important}#navbar>.nav>.divider{align-self:center;height:1.25rem;margin-left:var(--nav-divider-margin);margin-right:var(--nav-divider-margin);opacity:.2}#navbar>.nav.compact{font-size:.8125rem;line-height:1.25rem}#navbar>.nav.compact-extra{font-size:.75rem;line-height:1rem}#toolbar{align-items:center;bottom:0;display:flex;gap:.25rem;position:absolute;right:1rem;top:0}#main{min-height:100vh}#header+#main{min-height:calc(100vh - 3rem)}#main>.container{padding-left:1rem;padding-right:1rem;position:relative}@media (min-width:1400px){#header>.container,#main>.container,#mainNavbar>.container{padding-left:2.5rem;padding-right:2.5rem}#heading{left:2.5rem}#toolbar{right:2.5rem}}#mainNavbar{height:2.75rem;--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1))}#mainNavbar>.container{position:relative}#mainNavbar .nav{bottom:0;height:2.75rem;justify-content:center;left:0;position:absolute;right:0;top:0}#mainNavbar .nav-item{font-size:.875rem;line-height:1.3rem}#mainNavbar .nav-item>a{border-radius:var(--radius)}#mainMenu{gap:1rem;justify-content:space-between;padding-bottom:.75rem;padding-top:.75rem}#featureBar,#mainMenu{align-items:center;display:flex}#featureBar{flex:1 1 auto;gap:.5rem}#actionBar{gap:.5rem}#actionBar>.nav-divider{margin-left:-.25rem;margin-right:-.25rem}#mainContent{padding-top:.75rem}#mainMenu+#mainContent{padding-top:0}#mainContent.row{align-items:stretch;display:flex;gap:1rem;justify-content:space-between}#mainContent.row>*{flex:1 1 auto;min-width:0}#mainContainer.has-sidebar-left{--gutter-left-size:16px}#mainContainer.is-sidebar-left-collapsed{--gutter-left-size:0}.has-sidebar-animation.has-sidebar-left #mainMenu{transition-duration:.15s;transition-property:padding-left;transition-timing-function:cubic-bezier(.4,0,.2,1)}:root{--modal-radius:var(--radius);--avatar-bg:var(--color-gray-200)}.modal-alert .modal-footer{justify-content:center}.modal-dialog{--tw-bg-opacity:1}.modal-content,.modal-dialog{max-height:calc(100vh - 4rem)}.modal-body,.modal-footer,.modal-header{padding:1.5rem 2rem}.modal-header{padding-right:3rem}.modal-body+.modal-footer,.modal-header+.modal-actions+.modal-body,.modal-header+.modal-body{padding-top:1px}.modal-condensed .modal-body,.modal-condensed .modal-header{padding:1rem 1.25rem}.modal-condensed .modal-actions{top:.75rem}:root{--label-bg:var(--color-gray-100);--label-color:var(--color-gray-800)}.label[class$=-pale],.label[class*="-pale "]{--tw-bg-opacity:0.4;--tw-ring-opacity:0.4}.body-modal .panel-form,.modal-body>.panel-form{margin:0;padding:0}.modal-body>.panel-form>.panel-heading{padding-left:1px;padding-right:1px;padding-top:1px}.modal-body>.panel-form>.panel-body{padding:1px}.modal-body>.form{padding-top:1px}.modal .history,.modal .panel-body>.form{padding:0}:root{--article-p-space:0}.lane-col-join-with-above{position:relative}.lane-col-join-with-above:before{background-color:inherit;left:0;position:absolute;right:0;--tw-content:"";content:var(--tw-content);height:var(--kanban-col-gap-top,var(--kanban-lanes-gap));top:calc(0px - var(--kanban-col-gap-top, var(--kanban-lanes-gap)))}:root{--state-color:rgba(0,0,0,.05);--state-scale:.9;--opacity-disabled:.7;--opacity-muted:.5;--load-indicator-duration:300ms;--load-indicator-delay:.5s}.btn,.item>a,.state{cursor:pointer;position:relative}.btn:before,.item>a:before,.state:before{background:var(--state-color);border-radius:inherit;bottom:0;content:" ";display:block;left:0;opacity:0;pointer-events:none;position:absolute;right:0;top:0;transform:scale(var(--state-scale));transition-duration:.2s;transition-property:opacity,transform,box-shadow,background-color;transition-timing-function:cubic-bezier(.4,0,.2,1)}.btn.active:not(:hover,:focus-visible,:focus-within,:active):before,.item>a.active:not(:hover,:focus-visible,:focus-within,:active):before,.state.active:not(:hover,:focus-visible,:focus-within,:active):before{background:var(--state-active-color,var(--state-color));opacity:var(--state-active-opacity,0);--tw-scale-x:1;--tw-scale-y:1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-shadow:inset 0 2px 4px 0 rgba(0,0,0,.05);--tw-shadow-colored:inset 0 2px 4px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);transition-duration:.7s}.btn.selected:not(:hover,:focus-visible,:focus-within,:active):before,.item>a.selected:not(:hover,:focus-visible,:focus-within,:active):before,.state.selected:not(:hover,:focus-visible,:focus-within,:active):before{background:var(--state-selected-color,var(--state-scale));opacity:var(--state-selected-opacity,.1);--tw-scale-x:1;--tw-scale-y:1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.btn:focus-visible,.item>a:focus-visible,.state:focus-visible{outline:2px solid transparent;outline-offset:2px}.btn:active:before,.btn:focus-visible:before,.btn:hover:before,.item>a:active:before,.item>a:focus-visible:before,.item>a:hover:before,.state:active:before,.state:focus-visible:before,.state:hover:before{--tw-scale-x:1;--tw-scale-y:1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.btn:hover:before,.item>a:hover:before,.state:hover:before{opacity:var(--state-hover-opacity,1)}.btn:active:before,.item>a:active:before,.state:active:before{background:var(--state-pressed-color,var(--state-color));opacity:var(--state-pressed-opacity,.6);--tw-ring-color:var(--state-ring-color,currentColor);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);transition-duration:.7s}.btn:focus-visible:before,.item>a:focus-visible:before,.state:focus-visible:before{background:var(--state-focus-color,var(--state-color));opacity:var(--state-focus-opacity,1);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-focus-rgb),var(--tw-ring-opacity,1))}.btn.disabled:before,.btn[disabled]:before,.item>a.disabled:before,.item>a[disabled]:before,.state.disabled:before,.state[disabled]:before{display:none}.btn{--state-active-opacity:1}@-moz-document url-prefix(){.btn,:root{--state-active-opacity:0;--state-focus-opacity:0}}.disabled,.disabled *,[disabled],[disabled] *{cursor:not-allowed!important;opacity:var(--opacity-disabled);--tw-grayscale:grayscale(100%);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.load-indicator:after,.load-indicator:before{display:block;opacity:0;position:absolute;transition-delay:0s;transition-duration:.15s;transition-duration:var(--load-indicator-duration);transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);visibility:hidden}.load-indicator:before{align-items:center;background-color:rgba(var(--color-canvas-rgb),.7);border-radius:inherit;bottom:0;display:flex;font-size:.75rem;justify-content:center;left:0;line-height:1rem;right:0;top:0;z-index:99;--tw-content:attr(data-loading);content:var(--tw-content)}.load-indicator[data-loading]:before{padding-top:3.5rem}.load-indicator:after{border-color:transparent currentcolor currentcolor;border-radius:var(--radius-full);border-style:dotted;border-width:4px 3px 4px 4px;height:2rem;left:50%;margin-left:-1rem;margin-top:-1rem;top:50%;width:2rem;z-index:100;--tw-content:"";content:var(--tw-content)}.load-indicator.loading:after,.load-indicator.loading:before{opacity:1;transition-delay:var(--load-indicator-delay);visibility:visible}@keyframes -spin{to{transform:rotate(1turn)}}.load-indicator.loading:after{animation:-spin 1s linear infinite;opacity:.5}.events-none,.pointer-events-none{pointer-events:none}.events-auto,.pointer-events-auto{pointer-events:auto}.scroll-auto{scroll-behavior:auto}.scroll-smooth{scroll-behavior:smooth}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.select-text{-webkit-user-select:text;-moz-user-select:text;user-select:text}.select-all{-webkit-user-select:all;-moz-user-select:all;user-select:all}.select-auto{-webkit-user-select:auto;-moz-user-select:auto;user-select:auto}.cursor-auto{cursor:auto}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.cursor-wait{cursor:wait}.cursor-text{cursor:text}.cursor-move{cursor:move}.cursor-help{cursor:help}.cursor-not-allowed{cursor:not-allowed}.active\:opacity-100.active,.active\:opacity-100:active,.group.active .group-active\:opacity-100,.group:active .group-active\:opacity-100,.group:hover .group-hover\:opacity-100,.hover\:opacity-100:hover{opacity:1}.active\:opacity-0.active,.active\:opacity-0:active,.group.active .group-active\:opacity-0,.group:active .group-active\:opacity-0,.group:hover .group-hover\:opacity-0,.hover\:opacity-0:hover{opacity:0}.active\:text-primary.active,.active\:text-primary:active,.group.active .group-active\:text-primary,.group:active .group-active\:text-primary,.group:hover .group-hover\:text-primary,.hover\:text-primary:hover{--tw-text-opacity:1;color:rgba(var(--color-primary-500-rgb),var(--tw-text-opacity,1))}.active\:border-primary.active,.active\:border-primary:active,.group.active .group-active\:border-primary,.group:active .group-active\:border-primary,.group:hover .group-hover\:border-primary,.hover\:border-primary:hover{--tw-border-opacity:1;border-color:rgba(var(--color-primary-500-rgb),var(--tw-border-opacity,1))}.active\:primary-pale.active,.active\:primary-pale:active,.group.active .group-active\:primary-pale,.group:active .group-active\:primary-pale,.group:hover .group-hover\:primary-pale,.hover\:primary-pale:hover{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-50-rgb),var(--tw-bg-opacity,1))}.active\:primary.active,.active\:primary:active,.group.active .group-active\:primary,.group:active .group-active\:primary,.group:hover .group-hover\:primary,.hover\:primary:hover{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-500-rgb),var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgba(var(--color-canvas-rgb),var(--tw-text-opacity,1))}.active\:canvas.active,.active\:canvas:active,.group.active .group-active\:canvas,.group:active .group-active\:canvas,.group:hover .group-hover\:canvas,.hover\:canvas:hover{--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1))}.active\:font-bold.active,.active\:font-bold:active,.group.active .group-active\:font-bold,.group:active .group-active\:font-bold,.group:hover .group-hover\:font-bold,.hover\:font-bold:hover{font-weight:700}.active\:shadow.active,.active\:shadow:active,.group.active .group-active\:shadow,.group:active .group-active\:shadow,.group:hover .group-hover\:shadow,.hover\:shadow:hover{--tw-shadow:0 3px 8px 0 rgba(0,0,0,.04),0 1px 2px -1px rgba(0,0,0,.01);--tw-shadow-colored:0 3px 8px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.active\:shadow-lg.active,.active\:shadow-lg:active,.group.active .group-active\:shadow-lg,.group:active .group-active\:shadow-lg,.group:hover .group-hover\:shadow-lg,.hover\:shadow-lg:hover{--tw-shadow:0 5px 15px -3px rgba(0,0,0,.2),0 2px 6px -4px rgba(0,0,0,.15);--tw-shadow-colored:0 5px 15px -3px var(--tw-shadow-color),0 2px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.group:hover .group-hover\:block,.hover\:block:hover{display:block!important}.group:hover .group-hover\:flex,.hover\:flex:hover{display:flex!important}.group:hover .group-hover\:inline-flex,.hover\:inline-flex:hover{display:inline-flex!important}.group:hover .group-hover\:scale-110,.hover\:scale-110:hover{--tw-scale-x:1.1!important;--tw-scale-y:1.1!important}.group:hover .group-hover\:scale-110,.group:hover .group-hover\:scale-125,.hover\:scale-110:hover,.hover\:scale-125:hover{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.group:hover .group-hover\:scale-125,.hover\:scale-125:hover{--tw-scale-x:1.25!important;--tw-scale-y:1.25!important}.aspect-auto{aspect-ratio:auto}.aspect-square{aspect-ratio:1/1}.aspect-video{aspect-ratio:16/9}.container{width:100%}@media (min-width:1720px){.container{max-width:1720px}}.container{margin-left:auto;margin-right:auto}.popup{background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1));border-radius:var(--radius);--tw-bg-opacity:0.85;--tw-shadow:0 10px 25px -5px rgba(0,0,0,.2),0 4px 10px -6px rgba(0,0,0,.15);--tw-shadow-colored:0 10px 25px -5px var(--tw-shadow-color),0 4px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:rgba(var(--color-inverse-rgb),var(--tw-ring-opacity,1));--tw-ring-opacity:0.05;--tw-backdrop-blur:blur(16px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.table-cell{display:table-cell}.table-row{display:table-row}.hidden{display:none!important}.pull-right{float:right}.pull-left{float:left}.clearfix:after{clear:both;content:"";display:block}.object-contain{-o-object-fit:contain;object-fit:contain}.object-cover{-o-object-fit:cover;object-fit:cover}.object-fill{-o-object-fit:fill;object-fit:fill}.object-none{-o-object-fit:none;object-fit:none}.object-scale-down{-o-object-fit:scale-down;object-fit:scale-down}.object-bottom{-o-object-position:bottom;object-position:bottom}.object-center{-o-object-position:center;object-position:center}.object-left{-o-object-position:left;object-position:left}.object-left-bottom{-o-object-position:left bottom;object-position:left bottom}.object-left-top{-o-object-position:left top;object-position:left top}.object-right{-o-object-position:right;object-position:right}.object-right-bottom{-o-object-position:right bottom;object-position:right bottom}.object-right-top{-o-object-position:right top;object-position:right top}.object-top{-o-object-position:top;object-position:top}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-clip{overflow:clip}.overflow-visible{overflow:visible}.overflow-scroll{overflow:scroll}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-hidden{overflow-y:hidden}.overflow-x-clip{overflow-x:clip}.overflow-y-clip{overflow-y:clip}.overflow-x-visible{overflow-x:visible}.overflow-y-visible{overflow-y:visible}.overflow-x-scroll{overflow-x:scroll}.overflow-y-scroll{overflow-y:scroll}.overflow-overlay{overflow:overlay}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{bottom:0;left:0;right:0;top:0}.inset-auto{bottom:auto;left:auto;right:auto;top:auto}.inset-x-0{left:0;right:0}.inset-y-0{bottom:0;top:0}.top-0{top:0}.right-0{right:0}.bottom-0{bottom:0}.left-0{left:0}.top-full{top:100%}.right-full{right:100%}.bottom-full{bottom:100%}.left-full{left:100%}.top-auto{top:auto}.right-auto{right:auto}.bottom-auto{bottom:auto}.left-auto{left:auto}.top-px{top:1px}.right-px{right:1px}.bottom-px{bottom:1px}.left-px{left:1px}.top-0\.5{top:.125rem}.right-0\.5{right:.125rem}.bottom-0\.5{bottom:.125rem}.left-0\.5{left:.125rem}.top-1{top:.25rem}.right-1{right:.25rem}.bottom-1{bottom:.25rem}.left-1{left:.25rem}.top-1\.5{top:.375rem}.right-1\.5{right:.375rem}.bottom-1\.5{bottom:.375rem}.left-1\.5{left:.375rem}.top-2{top:.5rem}.right-2{right:.5rem}.bottom-2{bottom:.5rem}.left-2{left:.5rem}.top-2\.5{top:.625rem}.right-2\.5{right:.625rem}.bottom-2\.5{bottom:.625rem}.left-2\.5{left:.625rem}.top-3{top:.75rem}.right-3{right:.75rem}.bottom-3{bottom:.75rem}.left-3{left:.75rem}.top-3\.5{top:.875rem}.right-3\.5{right:.875rem}.bottom-3\.5{bottom:.875rem}.left-3\.5{left:.875rem}.top-4{top:1rem}.right-4{right:1rem}.bottom-4{bottom:1rem}.left-4{left:1rem}.top-5{top:1.25rem}.right-5{right:1.25rem}.bottom-5{bottom:1.25rem}.left-5{left:1.25rem}.top-6{top:1.5rem}.right-6{right:1.5rem}.bottom-6{bottom:1.5rem}.left-6{left:1.5rem}.top-7{top:1.75rem}.right-7{right:1.75rem}.bottom-7{bottom:1.75rem}.left-7{left:1.75rem}.top-8{top:2rem}.right-8{right:2rem}.bottom-8{bottom:2rem}.left-8{left:2rem}.visible{visibility:visible!important}.invisible{visibility:hidden!important}.z-0{z-index:0}.z-1{z-index:1}.z-5{z-index:5}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-40{z-index:40}.z-50{z-index:50}.z-auto{z-index:auto}.z-base{z-index:1100}.z-above{z-index:50}.z-below{z-index:-50}.z-dropdown{z-index:1200}.z-sticky{z-index:1300}.z-fixed{z-index:1400}.z-modal{z-index:1500}.z-overlay{z-index:1600}.z-popover{z-index:1700}.z-tooltip{z-index:1800}.z-messager{z-index:1900}.m-0{margin:0}.m-auto{margin:auto}.m-px{margin:1px}.m-0\.5{margin:.125rem}.m-1{margin:.25rem}.m-1\.5{margin:.375rem}.m-2{margin:.5rem}.m-2\.5{margin:.625rem}.m-3{margin:.75rem}.m-3\.5{margin:.875rem}.m-4{margin:1rem}.m-5{margin:1.25rem}.m-6{margin:1.5rem}.m-7{margin:1.75rem}.m-8{margin:2rem}.m-9{margin:2.25rem}.m-10{margin:2.5rem}.mx-0{margin-left:0;margin-right:0}.my-0{margin-bottom:0}.mt-0,.my-0{margin-top:0}.mr-0{margin-right:0}.mb-0{margin-bottom:0}.ml-0{margin-left:0}.mx-auto{margin-left:auto;margin-right:auto}.my-auto{margin-bottom:auto}.mt-auto,.my-auto{margin-top:auto}.mr-auto{margin-right:auto}.mb-auto{margin-bottom:auto}.ml-auto{margin-left:auto}.mx-px{margin-left:1px;margin-right:1px}.my-px{margin-bottom:1px}.mt-px,.my-px{margin-top:1px}.mr-px{margin-right:1px}.mb-px{margin-bottom:1px}.ml-px{margin-left:1px}.mx-0\.5{margin-left:.125rem;margin-right:.125rem}.my-0\.5{margin-bottom:.125rem}.mt-0\.5,.my-0\.5{margin-top:.125rem}.mr-0\.5{margin-right:.125rem}.mb-0\.5{margin-bottom:.125rem}.ml-0\.5{margin-left:.125rem}.mx-1{margin-left:.25rem;margin-right:.25rem}.my-1{margin-bottom:.25rem}.mt-1,.my-1{margin-top:.25rem}.mr-1{margin-right:.25rem}.mb-1{margin-bottom:.25rem}.ml-1{margin-left:.25rem}.mx-1\.5{margin-left:.375rem;margin-right:.375rem}.my-1\.5{margin-bottom:.375rem}.mt-1\.5,.my-1\.5{margin-top:.375rem}.mr-1\.5{margin-right:.375rem}.mb-1\.5{margin-bottom:.375rem}.ml-1\.5{margin-left:.375rem}.mx-2{margin-left:.5rem;margin-right:.5rem}.my-2{margin-bottom:.5rem}.mt-2,.my-2{margin-top:.5rem}.mr-2{margin-right:.5rem}.mb-2{margin-bottom:.5rem}.ml-2{margin-left:.5rem}.mx-2\.5{margin-left:.625rem;margin-right:.625rem}.my-2\.5{margin-bottom:.625rem}.mt-2\.5,.my-2\.5{margin-top:.625rem}.mr-2\.5{margin-right:.625rem}.mb-2\.5{margin-bottom:.625rem}.ml-2\.5{margin-left:.625rem}.mx-3{margin-left:.75rem;margin-right:.75rem}.my-3{margin-bottom:.75rem}.mt-3,.my-3{margin-top:.75rem}.mr-3{margin-right:.75rem}.mb-3{margin-bottom:.75rem}.ml-3{margin-left:.75rem}.mx-3\.5{margin-left:.875rem;margin-right:.875rem}.my-3\.5{margin-bottom:.875rem}.mt-3\.5,.my-3\.5{margin-top:.875rem}.mr-3\.5{margin-right:.875rem}.mb-3\.5{margin-bottom:.875rem}.ml-3\.5{margin-left:.875rem}.mx-4{margin-left:1rem;margin-right:1rem}.my-4{margin-bottom:1rem}.mt-4,.my-4{margin-top:1rem}.mr-4{margin-right:1rem}.mb-4{margin-bottom:1rem}.ml-4{margin-left:1rem}.mx-5{margin-left:1.25rem;margin-right:1.25rem}.my-5{margin-bottom:1.25rem}.mt-5,.my-5{margin-top:1.25rem}.mr-5{margin-right:1.25rem}.mb-5{margin-bottom:1.25rem}.ml-5{margin-left:1.25rem}.mx-6{margin-left:1.5rem;margin-right:1.5rem}.my-6{margin-bottom:1.5rem}.mt-6,.my-6{margin-top:1.5rem}.mr-6{margin-right:1.5rem}.mb-6{margin-bottom:1.5rem}.ml-6{margin-left:1.5rem}.mx-7{margin-left:1.75rem;margin-right:1.75rem}.my-7{margin-bottom:1.75rem}.mt-7,.my-7{margin-top:1.75rem}.mr-7{margin-right:1.75rem}.mb-7{margin-bottom:1.75rem}.ml-7{margin-left:1.75rem}.mx-8{margin-left:2rem;margin-right:2rem}.my-8{margin-bottom:2rem}.mt-8,.my-8{margin-top:2rem}.mr-8{margin-right:2rem}.mb-8{margin-bottom:2rem}.ml-8{margin-left:2rem}.mx-9{margin-left:2.25rem;margin-right:2.25rem}.my-9{margin-bottom:2.25rem}.mt-9,.my-9{margin-top:2.25rem}.mr-9{margin-right:2.25rem}.mb-9{margin-bottom:2.25rem}.ml-9{margin-left:2.25rem}.mx-10{margin-left:2.5rem;margin-right:2.5rem}.my-10{margin-bottom:2.5rem}.mt-10,.my-10{margin-top:2.5rem}.mr-10{margin-right:2.5rem}.mb-10{margin-bottom:2.5rem}.ml-10{margin-left:2.5rem}.p-0{padding:0}.p-px{padding:1px}.p-0\.5{padding:.125rem}.p-1{padding:.25rem}.p-1\.5{padding:.375rem}.p-2{padding:.5rem}.p-2\.5{padding:.625rem}.p-3{padding:.75rem}.p-3\.5{padding:.875rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.p-7{padding:1.75rem}.p-8{padding:2rem}.p-9{padding:2.25rem}.p-10{padding:2.5rem}.px-0{padding-left:0;padding-right:0}.py-0{padding-bottom:0}.pt-0,.py-0{padding-top:0}.pr-0{padding-right:0}.pb-0{padding-bottom:0}.pl-0{padding-left:0}.px-px{padding-left:1px;padding-right:1px}.py-px{padding-bottom:1px}.pt-px,.py-px{padding-top:1px}.pr-px{padding-right:1px}.pb-px{padding-bottom:1px}.pl-px{padding-left:1px}.px-0\.5{padding-left:.125rem;padding-right:.125rem}.py-0\.5{padding-bottom:.125rem}.pt-0\.5,.py-0\.5{padding-top:.125rem}.pr-0\.5{padding-right:.125rem}.pb-0\.5{padding-bottom:.125rem}.pl-0\.5{padding-left:.125rem}.px-1{padding-left:.25rem;padding-right:.25rem}.py-1{padding-bottom:.25rem}.pt-1,.py-1{padding-top:.25rem}.pr-1{padding-right:.25rem}.pb-1{padding-bottom:.25rem}.pl-1{padding-left:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.py-1\.5{padding-bottom:.375rem}.pt-1\.5,.py-1\.5{padding-top:.375rem}.pr-1\.5{padding-right:.375rem}.pb-1\.5{padding-bottom:.375rem}.pl-1\.5{padding-left:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.py-2{padding-bottom:.5rem}.pt-2,.py-2{padding-top:.5rem}.pr-2{padding-right:.5rem}.pb-2{padding-bottom:.5rem}.pl-2{padding-left:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.py-2\.5{padding-bottom:.625rem}.pt-2\.5,.py-2\.5{padding-top:.625rem}.pr-2\.5{padding-right:.625rem}.pb-2\.5{padding-bottom:.625rem}.pl-2\.5{padding-left:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.py-3{padding-bottom:.75rem}.pt-3,.py-3{padding-top:.75rem}.pr-3{padding-right:.75rem}.pb-3{padding-bottom:.75rem}.pl-3{padding-left:.75rem}.px-3\.5{padding-left:.875rem;padding-right:.875rem}.py-3\.5{padding-bottom:.875rem}.pt-3\.5,.py-3\.5{padding-top:.875rem}.pr-3\.5{padding-right:.875rem}.pb-3\.5{padding-bottom:.875rem}.pl-3\.5{padding-left:.875rem}.px-4{padding-left:1rem;padding-right:1rem}.py-4{padding-bottom:1rem}.pt-4,.py-4{padding-top:1rem}.pr-4{padding-right:1rem}.pb-4{padding-bottom:1rem}.pl-4{padding-left:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.py-5{padding-bottom:1.25rem}.pt-5,.py-5{padding-top:1.25rem}.pr-5{padding-right:1.25rem}.pb-5{padding-bottom:1.25rem}.pl-5{padding-left:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-6{padding-bottom:1.5rem}.pt-6,.py-6{padding-top:1.5rem}.pr-6{padding-right:1.5rem}.pb-6{padding-bottom:1.5rem}.pl-6{padding-left:1.5rem}.px-7{padding-left:1.75rem;padding-right:1.75rem}.py-7{padding-bottom:1.75rem}.pt-7,.py-7{padding-top:1.75rem}.pr-7{padding-right:1.75rem}.pb-7{padding-bottom:1.75rem}.pl-7{padding-left:1.75rem}.px-8{padding-left:2rem;padding-right:2rem}.py-8{padding-bottom:2rem}.pt-8,.py-8{padding-top:2rem}.pr-8{padding-right:2rem}.pb-8{padding-bottom:2rem}.pl-8{padding-left:2rem}.px-9{padding-left:2.25rem;padding-right:2.25rem}.py-9{padding-bottom:2.25rem}.pt-9,.py-9{padding-top:2.25rem}.pr-9{padding-right:2.25rem}.pb-9{padding-bottom:2.25rem}.pl-9{padding-left:2.25rem}.px-10{padding-left:2.5rem;padding-right:2.5rem}.py-10{padding-bottom:2.5rem}.pt-10,.py-10{padding-top:2.5rem}.pr-10{padding-right:2.5rem}.pb-10{padding-bottom:2.5rem}.pl-10{padding-left:2.5rem}.space-x-0>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(0px*(1 - var(--tw-space-x-reverse)));margin-right:calc(0px*var(--tw-space-x-reverse))}.space-y-0>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(0px*var(--tw-space-y-reverse));margin-top:calc(0px*(1 - var(--tw-space-y-reverse)))}.space-x-0\.5>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.125rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.125rem*var(--tw-space-x-reverse))}.space-y-0\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.125rem*var(--tw-space-y-reverse));margin-top:calc(.125rem*(1 - var(--tw-space-y-reverse)))}.space-x-1>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.25rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.25rem*var(--tw-space-x-reverse))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.25rem*var(--tw-space-y-reverse));margin-top:calc(.25rem*(1 - var(--tw-space-y-reverse)))}.space-x-1\.5>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.375rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.375rem*var(--tw-space-x-reverse))}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.375rem*var(--tw-space-y-reverse));margin-top:calc(.375rem*(1 - var(--tw-space-y-reverse)))}.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.5rem*var(--tw-space-x-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.5rem*var(--tw-space-y-reverse));margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)))}.space-x-2\.5>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.625rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.625rem*var(--tw-space-x-reverse))}.space-y-2\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.625rem*var(--tw-space-y-reverse));margin-top:calc(.625rem*(1 - var(--tw-space-y-reverse)))}.space-x-3>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.75rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.75rem*var(--tw-space-x-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.75rem*var(--tw-space-y-reverse));margin-top:calc(.75rem*(1 - var(--tw-space-y-reverse)))}.space-x-3\.5>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.875rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.875rem*var(--tw-space-x-reverse))}.space-y-3\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.875rem*var(--tw-space-y-reverse));margin-top:calc(.875rem*(1 - var(--tw-space-y-reverse)))}.space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1rem*var(--tw-space-x-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1rem*var(--tw-space-y-reverse));margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)))}.space-x-5>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1.25rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1.25rem*var(--tw-space-x-reverse))}.space-y-5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1.25rem*var(--tw-space-y-reverse));margin-top:calc(1.25rem*(1 - var(--tw-space-y-reverse)))}.space-x-6>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1.5rem*var(--tw-space-x-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1.5rem*var(--tw-space-y-reverse));margin-top:calc(1.5rem*(1 - var(--tw-space-y-reverse)))}.space-x-7>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1.75rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1.75rem*var(--tw-space-x-reverse))}.space-y-7>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1.75rem*var(--tw-space-y-reverse));margin-top:calc(1.75rem*(1 - var(--tw-space-y-reverse)))}.space-x-8>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(2rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(2rem*var(--tw-space-x-reverse))}.space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(2rem*var(--tw-space-y-reverse));margin-top:calc(2rem*(1 - var(--tw-space-y-reverse)))}.space-x-9>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(2.25rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(2.25rem*var(--tw-space-x-reverse))}.space-y-9>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(2.25rem*var(--tw-space-y-reverse));margin-top:calc(2.25rem*(1 - var(--tw-space-y-reverse)))}.space-x-10>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(2.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(2.5rem*var(--tw-space-x-reverse))}.space-y-10>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(2.5rem*var(--tw-space-y-reverse));margin-top:calc(2.5rem*(1 - var(--tw-space-y-reverse)))}.space-x-px>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1px*(1 - var(--tw-space-x-reverse)));margin-right:calc(1px*var(--tw-space-x-reverse))}.space-y-px>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1px*var(--tw-space-y-reverse));margin-top:calc(1px*(1 - var(--tw-space-y-reverse)))}.w-0{width:0}.w-px{width:1px}.w-0\.5{width:.125rem}.w-1{width:.25rem}.w-1\.5{width:.375rem}.w-2{width:.5rem}.w-2\.5{width:.625rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-7{width:1.75rem}.w-8{width:2rem}.w-9{width:2.25rem}.w-10{width:2.5rem}.w-11{width:2.75rem}.w-12{width:3rem}.w-14{width:3.5rem}.w-16{width:4rem}.w-20{width:5rem}.w-24{width:6rem}.w-28{width:7rem}.w-32{width:8rem}.w-36{width:9rem}.w-40{width:10rem}.w-44{width:11rem}.w-48{width:12rem}.w-52{width:13rem}.w-56{width:14rem}.w-60{width:15rem}.w-64{width:16rem}.w-72{width:18rem}.w-80{width:20rem}.w-96{width:24rem}.w-1\/2{width:50%}.w-1\/3{width:33.333333%}.w-2\/3{width:66.666667%}.w-1\/4{width:25%}.w-2\/4{width:50%}.w-3\/4{width:75%}.w-1\/5{width:20%}.w-2\/5{width:40%}.w-3\/5{width:60%}.w-4\/5{width:80%}.w-1\/6{width:16.666667%}.w-2\/6{width:33.333333%}.w-3\/6{width:50%}.w-4\/6{width:66.666667%}.w-5\/6{width:83.333333%}.w-auto{width:auto}.w-full{width:100%}.w-screen{width:100vw}.w-min{width:-moz-min-content;width:min-content}.w-max{width:-moz-max-content;width:max-content}.w-fit{width:-moz-fit-content;width:fit-content}.min-w-0{min-width:0}.min-w-full{min-width:100%}.min-w-min{min-width:-moz-min-content;min-width:min-content}.min-w-max{min-width:-moz-max-content;min-width:max-content}.min-w-fit{min-width:-moz-fit-content;min-width:fit-content}.max-w-0{max-width:0}.max-w-none{max-width:none}.max-w-xs{max-width:20rem}.max-w-sm{max-width:24rem}.max-w-md{max-width:28rem}.max-w-lg{max-width:32rem}.max-w-xl{max-width:36rem}.max-w-2xl{max-width:42rem}.max-w-3xl{max-width:48rem}.max-w-4xl{max-width:56rem}.max-w-5xl{max-width:64rem}.max-w-6xl{max-width:72rem}.max-w-7xl{max-width:80rem}.max-w-full{max-width:100%}.max-w-min{max-width:-moz-min-content;max-width:min-content}.max-w-max{max-width:-moz-max-content;max-width:max-content}.max-w-fit{max-width:-moz-fit-content;max-width:fit-content}.h-0{height:0}.h-px{height:1px}.h-0\.5{height:.125rem}.h-1{height:.25rem}.h-1\.5{height:.375rem}.h-2{height:.5rem}.h-2\.5{height:.625rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-10{height:2.5rem}.h-11{height:2.75rem}.h-12{height:3rem}.h-14{height:3.5rem}.h-16{height:4rem}.h-20{height:5rem}.h-24{height:6rem}.h-28{height:7rem}.h-32{height:8rem}.h-36{height:9rem}.h-40{height:10rem}.h-44{height:11rem}.h-48{height:12rem}.h-52{height:13rem}.h-56{height:14rem}.h-60{height:15rem}.h-64{height:16rem}.h-72{height:18rem}.h-80{height:20rem}.h-96{height:24rem}.h-1\/2{height:50%}.h-1\/3{height:33.333333%}.h-2\/3{height:66.666667%}.h-1\/4{height:25%}.h-2\/4{height:50%}.h-3\/4{height:75%}.h-1\/5{height:20%}.h-2\/5{height:40%}.h-3\/5{height:60%}.h-4\/5{height:80%}.h-1\/6{height:16.666667%}.h-2\/6{height:33.333333%}.h-3\/6{height:50%}.h-4\/6{height:66.666667%}.h-5\/6{height:83.333333%}.h-auto{height:auto}.h-full{height:100%}.h-screen{height:100vh}.h-min{height:-moz-min-content;height:min-content}.h-max{height:-moz-max-content;height:max-content}.h-fit{height:-moz-fit-content;height:fit-content}.min-h-0{min-height:0}.min-h-full{min-height:100%}.min-h-min{min-height:-moz-min-content;min-height:min-content}.min-h-max{min-height:-moz-max-content;min-height:max-content}.min-h-fit{min-height:-moz-fit-content;min-height:fit-content}.max-h-0{max-height:0}.max-h-px{max-height:1px}.max-h-none{max-height:none}.max-h-full{max-height:100%}.max-h-min{max-height:-moz-min-content;max-height:min-content}.max-h-screen{max-height:100vh}.max-h-max{max-height:-moz-max-content;max-height:max-content}.max-h-fit{max-height:-moz-fit-content;max-height:fit-content}.canvas,.surface,.surface-light,.surface-strong{--tw-text-opacity:1;color:rgba(var(--color-fore-rgb),var(--tw-text-opacity,1))}.canvas{--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1))}.surface-light{--tw-bg-opacity:1;background-color:rgba(var(--color-surface-light-rgb),var(--tw-bg-opacity,1));--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-surface-light-rgb),var(--tw-ring-opacity,1))}.surface{--tw-bg-opacity:1;background-color:rgba(var(--color-surface-rgb),var(--tw-bg-opacity,1));--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-surface-rgb),var(--tw-ring-opacity,1))}.surface-strong{--tw-bg-opacity:1;background-color:rgba(var(--color-surface-strong-rgb),var(--tw-bg-opacity,1));--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-surface-strong-rgb),var(--tw-ring-opacity,1))}.inverse{background-color:rgba(var(--color-inverse-rgb),var(--tw-bg-opacity,1));color:rgba(var(--color-canvas-rgb),var(--tw-text-opacity,1))}.inverse,.white{--tw-bg-opacity:1;--tw-text-opacity:1}.white{background-color:rgba(var(--color-white-rgb),var(--tw-bg-opacity,1));color:rgba(var(--color-fore-in-light-rgb),var(--tw-text-opacity,1));--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-white-rgb),var(--tw-ring-opacity,1))}.black{--tw-bg-opacity:1;background-color:rgba(var(--color-black-rgb),var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgba(var(--color-fore-in-dark-rgb),var(--tw-text-opacity,1));--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-black-rgb),var(--tw-ring-opacity,1))}.transparent{background-color:transparent;--tw-ring-color:transparent}.skin{--skin-bg:var(--skin-color);--skin-ring:var(--skin-color);--skin-border:var(--skin-color);--skin-hover-text:var(--skin-text);--skin-hover-bg:var(--skin-bg);--tw-ring-color:var(--skin-ring);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);--color-link-hover:var(--skin-text);background-color:var(--skin-bg);border-color:var(--skin-border);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);color:var(--skin-text)}.skin:hover{background-color:var(--skin-hover-bg);color:var(--skin-hover-text)}.danger,.darken,.darker,.darkest,.gray,.gray-100,.gray-200,.gray-300,.gray-400,.gray-50,.gray-500,.gray-600,.gray-700,.gray-800,.gray-900,.gray-950,.important,.lighten,.lighter,.lightest,.primary,.secondary,.special,.success,.warning{--skin-bg:var(--skin-color);--skin-ring:var(--skin-color);--skin-border:var(--skin-color);--skin-hover-text:var(--skin-text);--skin-hover-bg:var(--skin-bg);--tw-ring-color:var(--skin-ring);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);--color-link-hover:var(--skin-text);background-color:var(--skin-bg);border-color:var(--skin-border);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);color:var(--skin-text)}.danger:hover,.darken:hover,.darker:hover,.darkest:hover,.gray-100:hover,.gray-200:hover,.gray-300:hover,.gray-400:hover,.gray-500:hover,.gray-50:hover,.gray-600:hover,.gray-700:hover,.gray-800:hover,.gray-900:hover,.gray-950:hover,.gray:hover,.important:hover,.lighten:hover,.lighter:hover,.lightest:hover,.primary:hover,.secondary:hover,.special:hover,.success:hover,.warning:hover{background-color:var(--skin-hover-bg);color:var(--skin-hover-text)}.danger,.darken,.darker,.darkest,.gray,.gray-100,.gray-200,.gray-300,.gray-400,.gray-50,.gray-500,.gray-600,.gray-700,.gray-800,.gray-900,.gray-950,.important,.lighten,.lighter,.lightest,.primary,.secondary,.special,.success,.warning{--skin-text:rgba(var(--color-fore-in-dark-rgb),var(--tw-text-opacity));--skin-color:rgba(var(--skin-solid-rgb),1);--state-ring-color:var(--skin-color);--state-active-color:rgba(0,0,0,.1);--state-pressed-color:rgba(0,0,0,.1);--state-color:hsla(0,0%,100%,.1);--state-focus-color:rgba(0,0,0,.1)}.primary{--skin-solid-rgb:var(--color-primary-500-rgb)}.secondary{--skin-solid-rgb:var(--color-secondary-500-rgb)}.success{--skin-solid-rgb:var(--color-success-500-rgb)}.warning{--skin-solid-rgb:var(--color-warning-500-rgb)}.danger{--skin-solid-rgb:var(--color-danger-500-rgb)}.important{--skin-solid-rgb:var(--color-important-500-rgb)}.special{--skin-solid-rgb:var(--color-special-500-rgb)}.gray-50{--skin-bg:rgba(var(--color-gray-50-rgb),var(--tw-bg-opacity));--skin-text:rgba(var(--color-fore),var(--tw-text-opacity))}.gray-100{--skin-solid-rgb:var(--color-gray-100-rgb);--skin-text:rgba(var(--color-fore),var(--tw-text-opacity))}.gray-200,.lightest{--skin-solid-rgb:var(--color-gray-200-rgb);--skin-text:rgba(var(--color-fore),var(--tw-text-opacity))}.gray-300,.lighter{--skin-solid-rgb:var(--color-gray-300-rgb);--skin-text:rgba(var(--color-fore),var(--tw-text-opacity))}.gray-400,.lighten{--skin-solid-rgb:var(--color-gray-400-rgb)}.gray,.gray-500{--skin-solid-rgb:var(--color-gray-500-rgb)}.darken,.gray-600{--skin-solid-rgb:var(--color-gray-600-rgb)}.darker,.gray-700{--skin-solid-rgb:var(--color-gray-700-rgb)}.darkest,.gray-800{--skin-solid-rgb:var(--color-gray-800-rgb)}.gray-900{--skin-solid-rgb:var(--color-gray-900-rgb)}.gray-950{--skin-solid-rgb:var(--color-gray-950-rgb)}.danger-pale,.gray-100-pale,.gray-200-pale,.gray-300-pale,.gray-400-pale,.gray-50-pale,.gray-500-pale,.gray-600-pale,.gray-700-pale,.gray-800-pale,.gray-900-pale,.gray-950-pale,.gray-pale,.important-pale,.pale,.primary-pale,.secondary-pale,.special-pale,.success-pale,.warning-pale{--skin-bg:var(--skin-color);--skin-ring:var(--skin-color);--skin-border:var(--skin-color);--skin-hover-text:var(--skin-text);--skin-hover-bg:var(--skin-bg);--tw-ring-color:var(--skin-ring);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);--color-link-hover:var(--skin-text);background-color:var(--skin-bg);border-color:var(--skin-border);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);color:var(--skin-text)}.danger-pale:hover,.gray-100-pale:hover,.gray-200-pale:hover,.gray-300-pale:hover,.gray-400-pale:hover,.gray-50-pale:hover,.gray-500-pale:hover,.gray-600-pale:hover,.gray-700-pale:hover,.gray-800-pale:hover,.gray-900-pale:hover,.gray-950-pale:hover,.gray-pale:hover,.important-pale:hover,.pale:hover,.primary-pale:hover,.secondary-pale:hover,.special-pale:hover,.success-pale:hover,.warning-pale:hover{background-color:var(--skin-hover-bg);color:var(--skin-hover-text)}.danger-pale,.gray-100-pale,.gray-200-pale,.gray-300-pale,.gray-400-pale,.gray-50-pale,.gray-500-pale,.gray-600-pale,.gray-700-pale,.gray-800-pale,.gray-900-pale,.gray-950-pale,.gray-pale,.important-pale,.pale,.primary-pale,.secondary-pale,.special-pale,.success-pale,.warning-pale{--skin-color:rgba(var(--skin-pale-rgb),.1);--skin-text:rgba(var(--skin-pale-rgb),1);--state-color:rgba(var(--skin-pale-rgb),.1)}.pale{--skin-pale-rgb:var(--color-gray-500-rgb)}.primary-pale{--skin-pale-rgb:var(--color-primary-500-rgb)}.secondary-pale{--skin-pale-rgb:var(--color-secondary-500-rgb)}.success-pale{--skin-pale-rgb:var(--color-success-500-rgb)}.warning-pale{--skin-pale-rgb:var(--color-warning-500-rgb)}.danger-pale{--skin-pale-rgb:var(--color-danger-500-rgb)}.important-pale{--skin-pale-rgb:var(--color-important-500-rgb)}.special-pale{--skin-pale-rgb:var(--color-special-500-rgb)}.gray-50-pale{--skin-pale-rgb:var(--color-gray-50-rgb);--skin-text:var(--color-gray-400)}.gray-100-pale{--skin-pale-rgb:var(--color-gray-100-rgb);--skin-text:var(--color-gray-400)}.gray-200-pale{--skin-pale-rgb:var(--color-gray-200-rgb);--skin-text:var(--color-gray-400)}.gray-300-pale{--skin-pale-rgb:var(--color-gray-300-rgb);--skin-text:var(--color-gray-500)}.gray-400-pale{--skin-pale-rgb:var(--color-gray-400-rgb);--skin-text:var(--color-gray-500)}.gray-500-pale,.gray-pale{--skin-pale-rgb:var(--color-gray-500-rgb)}.gray-600-pale{--skin-pale-rgb:var(--color-gray-600-rgb)}.gray-700-pale{--skin-pale-rgb:var(--color-gray-700-rgb)}.gray-800-pale{--skin-pale-rgb:var(--color-gray-800-rgb)}.gray-900-pale{--skin-pale-rgb:var(--color-gray-900-rgb)}.gray-950-pale{--skin-pale-rgb:var(--color-gray-950-rgb)}.danger-outline,.dark-outline,.gray-300-outline,.gray-400-outline,.gray-600-outline,.gray-outline,.important-outline,.light-outline,.outline,.primary-outline,.secondary-outline,.special-outline,.success-outline,.warning-outline{--skin-bg:var(--skin-color);--skin-ring:var(--skin-color);--skin-border:var(--skin-color);--skin-hover-text:var(--skin-text);--skin-hover-bg:var(--skin-bg);--tw-ring-color:var(--skin-ring);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);--color-link-hover:var(--skin-text);background-color:var(--skin-bg);border-color:var(--skin-border);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);color:var(--skin-text)}.danger-outline:hover,.dark-outline:hover,.gray-300-outline:hover,.gray-400-outline:hover,.gray-600-outline:hover,.gray-outline:hover,.important-outline:hover,.light-outline:hover,.outline:hover,.primary-outline:hover,.secondary-outline:hover,.special-outline:hover,.success-outline:hover,.warning-outline:hover{background-color:var(--skin-hover-bg);color:var(--skin-hover-text)}.danger-outline,.dark-outline,.gray-300-outline,.gray-400-outline,.gray-600-outline,.gray-outline,.important-outline,.light-outline,.outline,.primary-outline,.secondary-outline,.special-outline,.success-outline,.warning-outline{--skin-text:var(--skin-color,inherit);--skin-bg:transparent;--skin-color:rgba(var(--skin-outline-rgb),1);--state-color:rgba(var(--skin-outline-rgb),.1)}.outline{--skin-outline-rgb:var(--color-fore-rgb)}.primary-outline{--skin-outline-rgb:var(--color-primary-500-rgb)}.secondary-outline{--skin-outline-rgb:var(--color-secondary-500-rgb)}.success-outline{--skin-outline-rgb:var(--color-success-500-rgb)}.warning-outline{--skin-outline-rgb:var(--color-warning-500-rgb)}.danger-outline{--skin-outline-rgb:var(--color-danger-500-rgb)}.important-outline{--skin-outline-rgb:var(--color-important-500-rgb)}.special-outline{--skin-outline-rgb:var(--color-special-500-rgb)}.gray-300-outline{--skin-text:var(--color-gray-500);--skin-outline-rgb:var(--color-gray-300-rgb)}.gray-400-outline{--skin-text:var(--color-gray-500);--skin-outline-rgb:var(--color-gray-400-rgb)}.gray-outline{--skin-outline-rgb:var(--color-gray-500-rgb)}.gray-600-outline{--skin-outline-rgb:var(--color-gray-600-rgb)}.dark-outline{--skin-outline-rgb:var(--color-inverse-rgb)}.light-outline{--skin-outline-rgb:var(--color-canvas-rgb)}.danger-ghost,.ghost,.important-ghost,.primary-ghost,.secondary-ghost,.special-ghost,.success-ghost,.warning-ghost{--skin-bg:var(--skin-color);--skin-ring:var(--skin-color);--skin-border:var(--skin-color);--skin-hover-text:var(--skin-text);--skin-hover-bg:var(--skin-bg);--tw-ring-color:var(--skin-ring);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);--color-link-hover:var(--skin-text);background-color:var(--skin-bg);border-color:var(--skin-border);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);color:var(--skin-text)}.danger-ghost:hover,.ghost:hover,.important-ghost:hover,.primary-ghost:hover,.secondary-ghost:hover,.special-ghost:hover,.success-ghost:hover,.warning-ghost:hover{background-color:var(--skin-hover-bg);color:var(--skin-hover-text)}.danger-ghost,.ghost,.important-ghost,.primary-ghost,.secondary-ghost,.special-ghost,.success-ghost,.warning-ghost{--tw-ring-opacity:0;--tw-bg-opacity:0;--skin-text:var(--skin-color,inherit);--skin-bg:transparent;--skin-ring:transparent;--skin-color:rgba(var(--skin-ghost-rgb),1);--state-color:rgba(var(--skin-ghost-rgb),.1)}.ghost{--skin-ghost-rgb:var(--color-fore-rgb);--skin-text:inherit}.primary-ghost{--skin-ghost-rgb:var(--color-primary-500-rgb)}.secondary-ghost{--skin-ghost-rgb:var(--color-secondary-500-rgb)}.success-ghost{--skin-ghost-rgb:var(--color-success-500-rgb)}.warning-ghost{--skin-ghost-rgb:var(--color-warning-500-rgb)}.danger-ghost{--skin-ghost-rgb:var(--color-danger-500-rgb)}.important-ghost{--skin-ghost-rgb:var(--color-important-500-rgb)}.special-ghost{--skin-ghost-rgb:var(--color-special-500-rgb)}.font-sans{font-family:-apple-system,Noto Sans,Helvetica Neue,Helvetica,Nimbus Sans L,Arial,Liberation Sans,PingFang SC,Hiragino Sans GB,Noto Sans CJK SC,Source Han Sans SC,Source Han Sans CN,Microsoft YaHei,Wenquanyi Micro Hei,WenQuanYi Zen Hei,ST Heiti,SimHei,WenQuanYi Zen Hei Sharp,sans-serif}.font-serif{font-family:Nimbus Roman No9 L,Songti SC,Noto Serif CJK SC,Source Han Serif SC,Source Han Serif CN,STSong,AR PL New Sung,AR PL SungtiL GB,NSimSun,SimSun,TW-Sung,WenQuanYi Bitmap Song,AR PL UMing CN,AR PL UMing HK,AR PL UMing TW,AR PL UMing TW MBE,PMingLiU,MingLiU,serif}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-root{font-size:16px}.text-sm{font-size:.75rem;line-height:1rem}.text-base{font-size:.8125rem;line-height:1.25rem}.text-md{font-size:.875rem;line-height:1.3rem}.text-lg{font-size:1rem;line-height:1.5rem}.text-xl{font-size:1.125rem;line-height:1.75rem}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-4xl{font-size:2.25rem;line-height:2.5rem}.font-thin{font-weight:100}.font-light{font-weight:300}.font-normal{font-weight:400}.font-medium{font-weight:500}.font-semibold{font-weight:600}.font-bold{font-weight:700}.font-black{font-weight:900}.leading-3{line-height:.75rem}.leading-4{line-height:1rem}.leading-5{line-height:1.25rem}.leading-6{line-height:1.5rem}.leading-7{line-height:1.75rem}.leading-8{line-height:2rem}.leading-9{line-height:2.25rem}.leading-10{line-height:2.5rem}.leading-none{line-height:1}.leading-tight{line-height:1.25}.leading-snug{line-height:1.375}.leading-normal{line-height:1.5}.leading-relaxed{line-height:1.625}.leading-loose{line-height:2}.line-clamp-1{-webkit-line-clamp:1}.line-clamp-1,.line-clamp-2{display:-webkit-box;overflow:hidden;-webkit-box-orient:vertical}.line-clamp-2{-webkit-line-clamp:2}.line-clamp-3{-webkit-line-clamp:3}.line-clamp-3,.line-clamp-4{display:-webkit-box;overflow:hidden;-webkit-box-orient:vertical}.line-clamp-4{-webkit-line-clamp:4}.line-clamp-5{-webkit-line-clamp:5}.line-clamp-5,.line-clamp-6{display:-webkit-box;overflow:hidden;-webkit-box-orient:vertical}.line-clamp-6{-webkit-line-clamp:6}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.text-justify{text-align:justify}.align-middle{vertical-align:middle}.align-top{vertical-align:top}.align-bottom{vertical-align:bottom}.align-sub{vertical-align:sub}.align-super{vertical-align:super}.text-primary{--tw-text-opacity:1;color:rgba(var(--color-primary-500-rgb),var(--tw-text-opacity,1))}.text-secondary{--tw-text-opacity:1;color:rgba(var(--color-secondary-500-rgb),var(--tw-text-opacity,1))}.text-success{--tw-text-opacity:1;color:rgba(var(--color-success-500-rgb),var(--tw-text-opacity,1))}.text-warning{--tw-text-opacity:1;color:rgba(var(--color-warning-500-rgb),var(--tw-text-opacity,1))}.text-danger{--tw-text-opacity:1;color:rgba(var(--color-danger-500-rgb),var(--tw-text-opacity,1))}.text-important{--tw-text-opacity:1;color:rgba(var(--color-important-500-rgb),var(--tw-text-opacity,1))}.text-special{--tw-text-opacity:1;color:rgba(var(--color-special-500-rgb),var(--tw-text-opacity,1))}.text-primary-50{--tw-text-opacity:1;color:rgba(var(--color-primary-50-rgb),var(--tw-text-opacity,1))}.text-primary-100{--tw-text-opacity:1;color:rgba(var(--color-primary-100-rgb),var(--tw-text-opacity,1))}.text-primary-200{--tw-text-opacity:1;color:rgba(var(--color-primary-200-rgb),var(--tw-text-opacity,1))}.text-primary-300{--tw-text-opacity:1;color:rgba(var(--color-primary-300-rgb),var(--tw-text-opacity,1))}.text-primary-400{--tw-text-opacity:1;color:rgba(var(--color-primary-400-rgb),var(--tw-text-opacity,1))}.text-primary-500{--tw-text-opacity:1;color:rgba(var(--color-primary-500-rgb),var(--tw-text-opacity,1))}.text-primary-600{--tw-text-opacity:1;color:rgba(var(--color-primary-600-rgb),var(--tw-text-opacity,1))}.text-primary-700{--tw-text-opacity:1;color:rgba(var(--color-primary-700-rgb),var(--tw-text-opacity,1))}.text-primary-800{--tw-text-opacity:1;color:rgba(var(--color-primary-800-rgb),var(--tw-text-opacity,1))}.text-primary-900{--tw-text-opacity:1;color:rgba(var(--color-primary-900-rgb),var(--tw-text-opacity,1))}.text-primary-950{--tw-text-opacity:1;color:rgba(var(--color-primary-950-rgb),var(--tw-text-opacity,1))}.text-secondary-50{--tw-text-opacity:1;color:rgba(var(--color-secondary-50-rgb),var(--tw-text-opacity,1))}.text-secondary-100{--tw-text-opacity:1;color:rgba(var(--color-secondary-100-rgb),var(--tw-text-opacity,1))}.text-secondary-200{--tw-text-opacity:1;color:rgba(var(--color-secondary-200-rgb),var(--tw-text-opacity,1))}.text-secondary-300{--tw-text-opacity:1;color:rgba(var(--color-secondary-300-rgb),var(--tw-text-opacity,1))}.text-secondary-400{--tw-text-opacity:1;color:rgba(var(--color-secondary-400-rgb),var(--tw-text-opacity,1))}.text-secondary-500{--tw-text-opacity:1;color:rgba(var(--color-secondary-500-rgb),var(--tw-text-opacity,1))}.text-secondary-600{--tw-text-opacity:1;color:rgba(var(--color-secondary-600-rgb),var(--tw-text-opacity,1))}.text-secondary-700{--tw-text-opacity:1;color:rgba(var(--color-secondary-700-rgb),var(--tw-text-opacity,1))}.text-secondary-800{--tw-text-opacity:1;color:rgba(var(--color-secondary-800-rgb),var(--tw-text-opacity,1))}.text-secondary-900{--tw-text-opacity:1;color:rgba(var(--color-secondary-900-rgb),var(--tw-text-opacity,1))}.text-secondary-950{--tw-text-opacity:1;color:rgba(var(--color-secondary-950-rgb),var(--tw-text-opacity,1))}.text-gray-50{--tw-text-opacity:1;color:rgba(var(--color-gray-50-rgb),var(--tw-text-opacity,1))}.text-gray-100{--tw-text-opacity:1;color:rgba(var(--color-gray-100-rgb),var(--tw-text-opacity,1))}.text-gray-200,.text-lightest{--tw-text-opacity:1;color:rgba(var(--color-gray-200-rgb),var(--tw-text-opacity,1))}.text-gray-300,.text-lighter{--tw-text-opacity:1;color:rgba(var(--color-gray-300-rgb),var(--tw-text-opacity,1))}.text-gray-400,.text-lighten{--tw-text-opacity:1;color:rgba(var(--color-gray-400-rgb),var(--tw-text-opacity,1))}.text-gray,.text-gray-500{--tw-text-opacity:1;color:rgba(var(--color-gray-500-rgb),var(--tw-text-opacity,1))}.text-darken,.text-gray-600{--tw-text-opacity:1;color:rgba(var(--color-gray-600-rgb),var(--tw-text-opacity,1))}.text-darker,.text-gray-700{--tw-text-opacity:1;color:rgba(var(--color-gray-700-rgb),var(--tw-text-opacity,1))}.text-darkest,.text-gray-800{--tw-text-opacity:1;color:rgba(var(--color-gray-800-rgb),var(--tw-text-opacity,1))}.text-gray-900{--tw-text-opacity:1;color:rgba(var(--color-gray-900-rgb),var(--tw-text-opacity,1))}.text-gray-950{--tw-text-opacity:1;color:rgba(var(--color-gray-950-rgb),var(--tw-text-opacity,1))}.text-white{--tw-text-opacity:1;color:rgba(var(--color-white-rgb),var(--tw-text-opacity,1))}.text-black{--tw-text-opacity:1;color:rgba(var(--color-black-rgb),var(--tw-text-opacity,1))}.text-transparent{color:transparent}.text-canvas{--tw-text-opacity:1;color:rgba(var(--color-canvas-rgb),var(--tw-text-opacity,1))}.text-surface-light{--tw-text-opacity:1;color:rgba(var(--color-surface-light-rgb),var(--tw-text-opacity,1))}.text-surface{--tw-text-opacity:1;color:rgba(var(--color-surface-rgb),var(--tw-text-opacity,1))}.text-surface-strong{--tw-text-opacity:1;color:rgba(var(--color-surface-strong-rgb),var(--tw-text-opacity,1))}.text-inverse{--tw-text-opacity:1;color:rgba(var(--color-inverse-rgb),var(--tw-text-opacity,1))}.text-fore-in-light{--tw-text-opacity:1;color:rgba(var(--color-fore-in-light-rgb),var(--tw-text-opacity,1))}.text-fore-in-dark{--tw-text-opacity:1;color:rgba(var(--color-fore-in-dark-rgb),var(--tw-text-opacity,1))}.text-fore{--tw-text-opacity:1;color:rgba(var(--color-fore-rgb),var(--tw-text-opacity,1))}.text-focus{--tw-text-opacity:1;color:rgba(var(--color-focus-rgb),var(--tw-text-opacity,1))}.text-link{--tw-text-opacity:1;color:rgba(var(--color-link-rgb),var(--tw-text-opacity,1))}.text-link-hover{--tw-text-opacity:1;color:rgba(var(--color-link-hover-rgb),var(--tw-text-opacity,1))}.text-current{color:currentColor}.text-inherit{color:inherit}.clip,.ellipsis,.text-clip,.text-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.clip,.text-clip{text-overflow:clip}.whitespace-normal{white-space:normal}.nowrap,.whitespace-nowrap{white-space:nowrap}.pre,.whitespace-pre{white-space:pre}.pre-line,.whitespace-pre-line{white-space:pre-line}.pre-wrap,.whitespace-pre-wrap{white-space:pre-wrap}.break-normal{overflow-wrap:normal;word-break:normal}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.text-opacity-0{--tw-text-opacity:0}.text-opacity-5{--tw-text-opacity:.05}.text-opacity-10{--tw-text-opacity:.1}.text-opacity-20{--tw-text-opacity:.2}.text-opacity-25{--tw-text-opacity:.25}.text-opacity-30{--tw-text-opacity:.3}.text-opacity-40{--tw-text-opacity:.4}.text-opacity-50{--tw-text-opacity:.5}.text-opacity-60{--tw-text-opacity:.6}.text-opacity-70{--tw-text-opacity:.7}.text-opacity-80{--tw-text-opacity:.8}.text-opacity-90{--tw-text-opacity:.9}.text-opacity-95{--tw-text-opacity:.95}.text-opacity-100{--tw-text-opacity:1}.uppercase{text-transform:uppercase}.lowercase{text-transform:lowercase}.capitalize{text-transform:capitalize}.normal-case{text-transform:none}.list-none{list-style-type:none}.list-disc{list-style-type:disc}.list-decimal{list-style-type:decimal}.list-unstyled{list-style-type:none;padding-left:0}.underline{text-decoration-line:underline}.overline{text-decoration-line:overline}.line-through{text-decoration-line:line-through}.no-underline{text-decoration-line:none}.bg-primary{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-500-rgb),var(--tw-bg-opacity,1))}.bg-secondary{--tw-bg-opacity:1;background-color:rgba(var(--color-secondary-500-rgb),var(--tw-bg-opacity,1))}.bg-success{--tw-bg-opacity:1;background-color:rgba(var(--color-success-500-rgb),var(--tw-bg-opacity,1))}.bg-warning{--tw-bg-opacity:1;background-color:rgba(var(--color-warning-500-rgb),var(--tw-bg-opacity,1))}.bg-danger{--tw-bg-opacity:1;background-color:rgba(var(--color-danger-500-rgb),var(--tw-bg-opacity,1))}.bg-important{--tw-bg-opacity:1;background-color:rgba(var(--color-important-500-rgb),var(--tw-bg-opacity,1))}.bg-special{--tw-bg-opacity:1;background-color:rgba(var(--color-special-500-rgb),var(--tw-bg-opacity,1))}.bg-primary-50{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-50-rgb),var(--tw-bg-opacity,1))}.bg-primary-100{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-100-rgb),var(--tw-bg-opacity,1))}.bg-primary-200{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-200-rgb),var(--tw-bg-opacity,1))}.bg-primary-300{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-300-rgb),var(--tw-bg-opacity,1))}.bg-primary-400{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-400-rgb),var(--tw-bg-opacity,1))}.bg-primary-500{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-500-rgb),var(--tw-bg-opacity,1))}.bg-primary-600{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-600-rgb),var(--tw-bg-opacity,1))}.bg-primary-700{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-700-rgb),var(--tw-bg-opacity,1))}.bg-primary-800{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-800-rgb),var(--tw-bg-opacity,1))}.bg-primary-900{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-900-rgb),var(--tw-bg-opacity,1))}.bg-primary-950{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-950-rgb),var(--tw-bg-opacity,1))}.bg-secondary-50{--tw-bg-opacity:1;background-color:rgba(var(--color-secondary-50-rgb),var(--tw-bg-opacity,1))}.bg-secondary-100{--tw-bg-opacity:1;background-color:rgba(var(--color-secondary-100-rgb),var(--tw-bg-opacity,1))}.bg-secondary-200{--tw-bg-opacity:1;background-color:rgba(var(--color-secondary-200-rgb),var(--tw-bg-opacity,1))}.bg-secondary-300{--tw-bg-opacity:1;background-color:rgba(var(--color-secondary-300-rgb),var(--tw-bg-opacity,1))}.bg-secondary-400{--tw-bg-opacity:1;background-color:rgba(var(--color-secondary-400-rgb),var(--tw-bg-opacity,1))}.bg-secondary-500{--tw-bg-opacity:1;background-color:rgba(var(--color-secondary-500-rgb),var(--tw-bg-opacity,1))}.bg-secondary-600{--tw-bg-opacity:1;background-color:rgba(var(--color-secondary-600-rgb),var(--tw-bg-opacity,1))}.bg-secondary-700{--tw-bg-opacity:1;background-color:rgba(var(--color-secondary-700-rgb),var(--tw-bg-opacity,1))}.bg-secondary-800{--tw-bg-opacity:1;background-color:rgba(var(--color-secondary-800-rgb),var(--tw-bg-opacity,1))}.bg-secondary-900{--tw-bg-opacity:1;background-color:rgba(var(--color-secondary-900-rgb),var(--tw-bg-opacity,1))}.bg-secondary-950{--tw-bg-opacity:1;background-color:rgba(var(--color-secondary-950-rgb),var(--tw-bg-opacity,1))}.bg-gray-50{--tw-bg-opacity:1;background-color:rgba(var(--color-gray-50-rgb),var(--tw-bg-opacity,1))}.bg-gray-100{--tw-bg-opacity:1;background-color:rgba(var(--color-gray-100-rgb),var(--tw-bg-opacity,1))}.bg-gray-200,.bg-lightest{--tw-bg-opacity:1;background-color:rgba(var(--color-gray-200-rgb),var(--tw-bg-opacity,1))}.bg-gray-300,.bg-lighter{--tw-bg-opacity:1;background-color:rgba(var(--color-gray-300-rgb),var(--tw-bg-opacity,1))}.bg-gray-400,.bg-light{--tw-bg-opacity:1;background-color:rgba(var(--color-gray-400-rgb),var(--tw-bg-opacity,1))}.bg-gray,.bg-gray-500{--tw-bg-opacity:1;background-color:rgba(var(--color-gray-500-rgb),var(--tw-bg-opacity,1))}.bg-darken,.bg-gray-600{--tw-bg-opacity:1;background-color:rgba(var(--color-gray-600-rgb),var(--tw-bg-opacity,1))}.bg-darker,.bg-gray-700{--tw-bg-opacity:1;background-color:rgba(var(--color-gray-700-rgb),var(--tw-bg-opacity,1))}.bg-darkest,.bg-gray-800{--tw-bg-opacity:1;background-color:rgba(var(--color-gray-800-rgb),var(--tw-bg-opacity,1))}.bg-gray-900{--tw-bg-opacity:1;background-color:rgba(var(--color-gray-900-rgb),var(--tw-bg-opacity,1))}.bg-gray-950{--tw-bg-opacity:1;background-color:rgba(var(--color-gray-950-rgb),var(--tw-bg-opacity,1))}.bg-canvas{--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1))}.bg-surface-light{--tw-bg-opacity:1;background-color:rgba(var(--color-surface-light-rgb),var(--tw-bg-opacity,1))}.bg-surface{--tw-bg-opacity:1;background-color:rgba(var(--color-surface-rgb),var(--tw-bg-opacity,1))}.bg-surface-strong{--tw-bg-opacity:1;background-color:rgba(var(--color-surface-strong-rgb),var(--tw-bg-opacity,1))}.bg-inverse{--tw-bg-opacity:1;background-color:rgba(var(--color-inverse-rgb),var(--tw-bg-opacity,1))}.bg-fore-in-light{--tw-bg-opacity:1;background-color:rgba(var(--color-fore-in-light-rgb),var(--tw-bg-opacity,1))}.bg-fore-in-dark{--tw-bg-opacity:1;background-color:rgba(var(--color-fore-in-dark-rgb),var(--tw-bg-opacity,1))}.bg-fore{--tw-bg-opacity:1;background-color:rgba(var(--color-fore-rgb),var(--tw-bg-opacity,1))}.bg-focus{--tw-bg-opacity:1;background-color:rgba(var(--color-focus-rgb),var(--tw-bg-opacity,1))}.bg-white{--tw-bg-opacity:1;background-color:rgba(var(--color-white-rgb),var(--tw-bg-opacity,1))}.bg-black{--tw-bg-opacity:1;background-color:rgba(var(--color-black-rgb),var(--tw-bg-opacity,1))}.bg-transparent{background-color:transparent}.bg-current{background-color:currentColor}.bg-inherit{background-color:inherit}.bg-none{background-image:none}.bg-opacity-0{--tw-bg-opacity:0}.bg-opacity-5{--tw-bg-opacity:.05}.bg-opacity-10{--tw-bg-opacity:.1}.bg-opacity-20{--tw-bg-opacity:.2}.bg-opacity-25{--tw-bg-opacity:.25}.bg-opacity-30{--tw-bg-opacity:.3}.bg-opacity-40{--tw-bg-opacity:.4}.bg-opacity-50{--tw-bg-opacity:.5}.bg-opacity-60{--tw-bg-opacity:.6}.bg-opacity-70{--tw-bg-opacity:.7}.bg-opacity-80{--tw-bg-opacity:.8}.bg-opacity-90{--tw-bg-opacity:.9}.bg-opacity-100{--tw-bg-opacity:1}.bg-auto{background-size:auto}.bg-cover{background-size:cover}.bg-contain{background-size:contain}.bg-repeat{background-repeat:repeat}.bg-no-repeat{background-repeat:no-repeat}.bg-repeat-x{background-repeat:repeat-x}.bg-repeat-y{background-repeat:repeat-y}.bg-repeat-round{background-repeat:round}.bg-repeat-space{background-repeat:space}.bg-bottom{background-position:bottom}.bg-center{background-position:50%}.bg-left{background-position:0}.bg-left-bottom{background-position:0 100%}.bg-left-top{background-position:0 0}.bg-right{background-position:100%}.bg-right-bottom{background-position:100% 100%}.bg-right-top{background-position:100% 0}.bg-top{background-position:top}.bg-fixed{background-attachment:fixed}.bg-local{background-attachment:local}.bg-scroll{background-attachment:scroll}.divider{align-self:stretch;border-color:currentColor;border-left-width:1px;border-top-width:1px;opacity:.1}.border-0{border-width:0}.border{border-width:1px}.border-2{border-width:2px}.border-4{border-width:4px}.border-t{border-top-width:1px}.border-l{border-left-width:1px}.border-r{border-right-width:1px}.border-b{border-bottom-width:1px}.border-t-0{border-top-width:0}.border-r-0{border-right-width:0}.border-b-0{border-bottom-width:0}.border-l-0{border-left-width:0}.border-t-2{border-top-width:2px}.border-l-2{border-left-width:2px}.border-r-2{border-right-width:2px}.border-b-2{border-bottom-width:2px}.border-t-4{border-top-width:4px}.border-l-4{border-left-width:4px}.border-r-4{border-right-width:4px}.border-b-4{border-bottom-width:4px}.border-light{--tw-border-opacity:1;border-color:rgba(var(--color-border-light-rgb),var(--tw-border-opacity,1))}.border-strong{--tw-border-opacity:1;border-color:rgba(var(--color-border-strong-rgb),var(--tw-border-opacity,1))}.border-primary{--tw-border-opacity:1;border-color:rgba(var(--color-primary-500-rgb),var(--tw-border-opacity,1))}.border-secondary{--tw-border-opacity:1;border-color:rgba(var(--color-secondary-500-rgb),var(--tw-border-opacity,1))}.border-success{--tw-border-opacity:1;border-color:rgba(var(--color-success-500-rgb),var(--tw-border-opacity,1))}.border-warning{--tw-border-opacity:1;border-color:rgba(var(--color-warning-500-rgb),var(--tw-border-opacity,1))}.border-danger{--tw-border-opacity:1;border-color:rgba(var(--color-danger-500-rgb),var(--tw-border-opacity,1))}.border-important{--tw-border-opacity:1;border-color:rgba(var(--color-important-500-rgb),var(--tw-border-opacity,1))}.border-special{--tw-border-opacity:1;border-color:rgba(var(--color-special-500-rgb),var(--tw-border-opacity,1))}.border-gray-50{--tw-border-opacity:1;border-color:rgba(var(--color-gray-50-rgb),var(--tw-border-opacity,1))}.border-gray-100{--tw-border-opacity:1;border-color:rgba(var(--color-gray-100-rgb),var(--tw-border-opacity,1))}.border-gray-200{--tw-border-opacity:1;border-color:rgba(var(--color-gray-200-rgb),var(--tw-border-opacity,1))}.border-gray-300{--tw-border-opacity:1;border-color:rgba(var(--color-gray-300-rgb),var(--tw-border-opacity,1))}.border-gray-400{--tw-border-opacity:1;border-color:rgba(var(--color-gray-400-rgb),var(--tw-border-opacity,1))}.border-gray,.border-gray-500{--tw-border-opacity:1;border-color:rgba(var(--color-gray-500-rgb),var(--tw-border-opacity,1))}.border-gray-600{--tw-border-opacity:1;border-color:rgba(var(--color-gray-600-rgb),var(--tw-border-opacity,1))}.border-gray-700{--tw-border-opacity:1;border-color:rgba(var(--color-gray-700-rgb),var(--tw-border-opacity,1))}.border-gray-800{--tw-border-opacity:1;border-color:rgba(var(--color-gray-800-rgb),var(--tw-border-opacity,1))}.border-gray-900{--tw-border-opacity:1;border-color:rgba(var(--color-gray-900-rgb),var(--tw-border-opacity,1))}.border-gray-950{--tw-border-opacity:1;border-color:rgba(var(--color-gray-950-rgb),var(--tw-border-opacity,1))}.border-white{--tw-border-opacity:1;border-color:rgba(var(--color-white-rgb),var(--tw-border-opacity,1))}.border-black{--tw-border-opacity:1;border-color:rgba(var(--color-black-rgb),var(--tw-border-opacity,1))}.border-canvas{--tw-border-opacity:1;border-color:rgba(var(--color-canvas-rgb),var(--tw-border-opacity,1))}.border-surface-light{--tw-border-opacity:1;border-color:rgba(var(--color-surface-light-rgb),var(--tw-border-opacity,1))}.border-surface{--tw-border-opacity:1;border-color:rgba(var(--color-surface-rgb),var(--tw-border-opacity,1))}.border-surface-strong{--tw-border-opacity:1;border-color:rgba(var(--color-surface-strong-rgb),var(--tw-border-opacity,1))}.border-inverse{--tw-border-opacity:1;border-color:rgba(var(--color-inverse-rgb),var(--tw-border-opacity,1))}.border-fore-in-light{--tw-border-opacity:1;border-color:rgba(var(--color-fore-in-light-rgb),var(--tw-border-opacity,1))}.border-fore-in-dark{--tw-border-opacity:1;border-color:rgba(var(--color-fore-in-dark-rgb),var(--tw-border-opacity,1))}.border-fore{--tw-border-opacity:1;border-color:rgba(var(--color-fore-rgb),var(--tw-border-opacity,1))}.border-focus{--tw-border-opacity:1;border-color:rgba(var(--color-focus-rgb),var(--tw-border-opacity,1))}.border-link{--tw-border-opacity:1;border-color:rgba(var(--color-link-rgb),var(--tw-border-opacity,1))}.border-link-hover{--tw-border-opacity:1;border-color:rgba(var(--color-link-hover-rgb),var(--tw-border-opacity,1))}.border-transparent{border-color:transparent}.border-current{border-color:currentColor}.border-inherit{border-color:inherit}.border-solid{border-style:solid}.border-dashed{border-style:dashed}.border-dotted{border-style:dotted}.border-double{border-style:double}.border-hidden{border-style:hidden}.border-none{border-style:none}.border-opacity-0{--tw-border-opacity:0}.border-opacity-5{--tw-border-opacity:.05}.border-opacity-10{--tw-border-opacity:.1}.border-opacity-20{--tw-border-opacity:.2}.border-opacity-25{--tw-border-opacity:.25}.border-opacity-30{--tw-border-opacity:.3}.border-opacity-40{--tw-border-opacity:.4}.border-opacity-50{--tw-border-opacity:.5}.border-opacity-60{--tw-border-opacity:.6}.border-opacity-70{--tw-border-opacity:.7}.border-opacity-80{--tw-border-opacity:.8}.border-opacity-90{--tw-border-opacity:.9}.border-opacity-95{--tw-border-opacity:.95}.border-opacity-100{--tw-border-opacity:1}.rounded-none{border-radius:var(--radius-none)}.rounded-sm{border-radius:var(--radius-sm)}.rounded{border-radius:var(--radius)}.rounded-md{border-radius:var(--radius-md)}.rounded-lg{border-radius:var(--radius-lg)}.rounded-xl{border-radius:var(--radius-xl)}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-3xl{border-radius:var(--radius-3xl)}.circle,.rounded-full{border-radius:var(--radius-full)}.rounded-l-none{border-bottom-left-radius:var(--radius-none);border-top-left-radius:var(--radius-none)}.rounded-t-none{border-top-left-radius:var(--radius-none)}.rounded-r-none,.rounded-t-none{border-top-right-radius:var(--radius-none)}.rounded-b-none,.rounded-r-none{border-bottom-right-radius:var(--radius-none)}.rounded-b-none{border-bottom-left-radius:var(--radius-none)}.rounded-br-none{border-bottom-right-radius:var(--radius-none)}.rounded-bl-none{border-bottom-left-radius:var(--radius-none)}.rounded-tr-none{border-top-right-radius:var(--radius-none)}.rounded-tl-none{border-top-left-radius:var(--radius-none)}.ring{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-border-rgb),var(--tw-ring-opacity,1))}.ring-border-light{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-border-light-rgb),var(--tw-ring-opacity,1))}.ring-border{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-border-rgb),var(--tw-ring-opacity,1))}.ring-border-strong{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-border-strong-rgb),var(--tw-ring-opacity,1))}.ring-light{--tw-ring-color:rgba(var(--color-inverse-rgb),var(--tw-ring-opacity,1));--tw-ring-opacity:0.05}.ring-gray{--tw-ring-color:rgba(var(--color-inverse-rgb),var(--tw-ring-opacity,1));--tw-ring-opacity:0.1}.ring-dark{--tw-ring-color:rgba(var(--color-inverse-rgb),var(--tw-ring-opacity,1));--tw-ring-opacity:0.2}.ring-darker{--tw-ring-color:rgba(var(--color-inverse-rgb),var(--tw-ring-opacity,1));--tw-ring-opacity:0.3}.ring-darkest{--tw-ring-color:rgba(var(--color-inverse-rgb),var(--tw-ring-opacity,1));--tw-ring-opacity:0.5}.ring-primary{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-primary-500-rgb),var(--tw-ring-opacity,1))}.ring-secondary{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-secondary-500-rgb),var(--tw-ring-opacity,1))}.ring-warning{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-warning-500-rgb),var(--tw-ring-opacity,1))}.ring-success{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-success-500-rgb),var(--tw-ring-opacity,1))}.ring-danger{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-danger-500-rgb),var(--tw-ring-opacity,1))}.ring-important{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-important-500-rgb),var(--tw-ring-opacity,1))}.ring-special{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-special-500-rgb),var(--tw-ring-opacity,1))}.ring-gray-50{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-gray-50-rgb),var(--tw-ring-opacity,1))}.ring-gray-100{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-gray-100-rgb),var(--tw-ring-opacity,1))}.ring-gray-200{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-gray-200-rgb),var(--tw-ring-opacity,1))}.ring-gray-300{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-gray-300-rgb),var(--tw-ring-opacity,1))}.ring-gray-400{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-gray-400-rgb),var(--tw-ring-opacity,1))}.ring-gray-500{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-gray-500-rgb),var(--tw-ring-opacity,1))}.ring-gray-600{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-gray-600-rgb),var(--tw-ring-opacity,1))}.ring-gray-700{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-gray-700-rgb),var(--tw-ring-opacity,1))}.ring-gray-800{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-gray-800-rgb),var(--tw-ring-opacity,1))}.ring-gray-900{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-gray-900-rgb),var(--tw-ring-opacity,1))}.ring-gray-950{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-gray-950-rgb),var(--tw-ring-opacity,1))}.ring-inverse{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-inverse-rgb),var(--tw-ring-opacity,1))}.ring-canvas{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-canvas-rgb),var(--tw-ring-opacity,1))}.ring-surface{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-surface-rgb),var(--tw-ring-opacity,1))}.ring-fore{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-fore-rgb),var(--tw-ring-opacity,1))}.ring-transparent{--tw-ring-color:transparent}.ring-black{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-black-rgb),var(--tw-ring-opacity,1))}.ring-white{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-white-rgb),var(--tw-ring-opacity,1))}.ring-inherit{--tw-ring-color:inherit}.ring-current{--tw-ring-color:currentColor}.ring-opacity-0{--tw-ring-opacity:0}.ring-opacity-5{--tw-ring-opacity:.05}.ring-opacity-10{--tw-ring-opacity:.1}.ring-opacity-20{--tw-ring-opacity:.2}.ring-opacity-30{--tw-ring-opacity:.3}.ring-opacity-40{--tw-ring-opacity:.4}.ring-opacity-50{--tw-ring-opacity:.5}.ring-opacity-60{--tw-ring-opacity:.6}.ring-opacity-70{--tw-ring-opacity:.7}.ring-opacity-80{--tw-ring-opacity:.8}.ring-opacity-90{--tw-ring-opacity:.9}.ring-opacity-100{--tw-ring-opacity:1}.ring-0{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color)}.ring-0,.ring-2{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.ring-2{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color)}.ring-3{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color)}.ring-3,.ring-4{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.ring-4{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color)}.ring-8{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(8px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.ring-inset{--tw-ring-inset:inset}.ring-offset-0{--tw-ring-offset-width:0px}.ring-offset-1{--tw-ring-offset-width:1px}.ring-offset-2{--tw-ring-offset-width:2px}.ring-offset-4{--tw-ring-offset-width:4px}.ring-offset-8{--tw-ring-offset-width:8px}.shadow-sm{--tw-shadow:0 1px 2px 0 rgba(0,0,0,.04),0 0 2px -1px rgba(0,0,0,.01);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color),0 0 2px -1px var(--tw-shadow-color)}.shadow,.shadow-sm{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow{--tw-shadow:0 3px 8px 0 rgba(0,0,0,.04),0 1px 2px -1px rgba(0,0,0,.01);--tw-shadow-colored:0 3px 8px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color)}.shadow-md{--tw-shadow:0 2px 6px -1px rgba(0,0,0,.2),0 1px 4px -2px rgba(0,0,0,.15);--tw-shadow-colored:0 2px 6px -1px var(--tw-shadow-color),0 1px 4px -2px var(--tw-shadow-color)}.shadow-lg,.shadow-md{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 5px 15px -3px rgba(0,0,0,.2),0 2px 6px -4px rgba(0,0,0,.15);--tw-shadow-colored:0 5px 15px -3px var(--tw-shadow-color),0 2px 6px -4px var(--tw-shadow-color)}.shadow-xl{--tw-shadow:0 10px 25px -5px rgba(0,0,0,.2),0 4px 10px -6px rgba(0,0,0,.15);--tw-shadow-colored:0 10px 25px -5px var(--tw-shadow-color),0 4px 10px -6px var(--tw-shadow-color)}.shadow-2xl,.shadow-xl{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-2xl{--tw-shadow:0 10px 50px -10px rgba(0,0,0,.4),0 8px 20px -10px rgba(0,0,0,.3);--tw-shadow-colored:0 10px 50px -10px var(--tw-shadow-color),0 8px 20px -10px var(--tw-shadow-color)}.shadow-inner{--tw-shadow:inset 0 2px 4px 0 rgba(0,0,0,.05);--tw-shadow-colored:inset 0 2px 4px 0 var(--tw-shadow-color)}.shadow-inner,.shadow-none{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-none{--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000}.muted{opacity:var(--opacity-muted)}.opacity-0{opacity:0}.opacity-5{opacity:.05}.opacity-10{opacity:.1}.opacity-20{opacity:.2}.opacity-25{opacity:.25}.opacity-30{opacity:.3}.opacity-40{opacity:.4}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-75{opacity:.75}.opacity-80{opacity:.8}.opacity-90{opacity:.9}.opacity-95{opacity:.95}.opacity-100{opacity:1}.blur-none{--tw-blur: }.blur-none,.blur-sm{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.blur-sm{--tw-blur:blur(4px)}.blur{--tw-blur:blur(8px)}.blur,.blur-md{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.blur-md{--tw-blur:blur(12px)}.blur-lg{--tw-blur:blur(16px)}.blur-lg,.blur-xl{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.blur-xl{--tw-blur:blur(24px)}.grayscale{--tw-grayscale:grayscale(100%)}.grayscale,.invert{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.invert{--tw-invert:invert(100%)}.filter-none{filter:none!important}.drop-shadow-none{--tw-drop-shadow:drop-shadow(0 0 #0000)}.drop-shadow-none,.drop-shadow-sm{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.drop-shadow-sm{--tw-drop-shadow:drop-shadow(0 1px 1px rgba(0,0,0,.05))}.drop-shadow{--tw-drop-shadow:drop-shadow(0 1px 2px rgba(0,0,0,.1)) drop-shadow(0 1px 1px rgba(0,0,0,.06))}.drop-shadow,.drop-shadow-md{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.drop-shadow-md{--tw-drop-shadow:drop-shadow(0 4px 3px rgba(0,0,0,.07)) drop-shadow(0 2px 2px rgba(0,0,0,.06))}.drop-shadow-lg{--tw-drop-shadow:drop-shadow(0 10px 8px rgba(0,0,0,.04)) drop-shadow(0 4px 3px rgba(0,0,0,.1))}.drop-shadow-lg,.drop-shadow-xl{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.drop-shadow-xl{--tw-drop-shadow:drop-shadow(0 20px 13px rgba(0,0,0,.03)) drop-shadow(0 8px 5px rgba(0,0,0,.08))}.drop-shadow-2xl{--tw-drop-shadow:drop-shadow(0 25px 25px rgba(0,0,0,.15));filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-none{--tw-backdrop-blur: }.backdrop-blur-none,.backdrop-blur-sm{-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-sm{--tw-backdrop-blur:blur(4px)}.backdrop-blur{--tw-backdrop-blur:blur(8px)}.backdrop-blur,.backdrop-blur-md{-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-md{--tw-backdrop-blur:blur(12px)}.backdrop-blur-lg{--tw-backdrop-blur:blur(16px)}.backdrop-blur-lg,.backdrop-blur-xl{-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-xl{--tw-backdrop-blur:blur(24px)}.backdrop-blur-2xl{--tw-backdrop-blur:blur(40px)}.backdrop-blur-2xl,.backdrop-blur-3xl{-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-3xl{--tw-backdrop-blur:blur(64px)}.transition{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-all{transition-duration:.15s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-colors{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-opacity{transition-duration:.15s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-shadow{transition-duration:.15s;transition-property:box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-transform{transition-duration:.15s;transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-none{transition-property:none}.fade,.fade-from-bottom,.fade-from-center,.fade-from-left,.fade-from-right,.fade-from-top{opacity:0;transition-duration:.15s;transition-property:opacity,transform;transition-timing-function:cubic-bezier(.4,0,.2,1)}.fade-from-bottom,.fade-from-center,.fade-from-left,.fade-from-right,.fade-from-top{--tw-scale-x:.9;--tw-scale-y:.9}.fade-from-bottom,.fade-from-center,.fade-from-left,.fade-from-right,.fade-from-top{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.fade-from-bottom{--tw-translate-y:25%}.fade-from-top{--tw-translate-y:-25%}.fade-from-left,.fade-from-top{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.fade-from-left{--tw-translate-x:-25%}.fade-from-right{--tw-translate-x:25%}.fade-from-bottom.in,.fade-from-center.in,.fade-from-left.in,.fade-from-right,.fade-from-right.in,.fade-from-top.in,.fade.in{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.fade-from-bottom.in,.fade-from-center.in,.fade-from-left.in,.fade-from-right.in,.fade-from-top.in,.fade.in{--tw-translate-x:0px;--tw-translate-y:0px;--tw-scale-x:1;--tw-scale-y:1;opacity:1}.duration-75{transition-duration:75ms}.duration-100{transition-duration:.1s}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}.duration-500{transition-duration:.5s}.duration-1000{transition-duration:1s}@keyframes -spin{to{transform:rotate(1turn)}}.animate-spin,.spin{animation:-spin 1s linear infinite}@keyframes -ping{75%,to{opacity:0;transform:scale(2)}}.animate-ping,.ping{animation:-ping 1s cubic-bezier(0,0,.2,1) infinite}@keyframes -pulse{50%{opacity:.5}}.animate-pulse,.pulse{animation:-pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes -bounce{0%,to{animation-timing-function:cubic-bezier(.8,0,1,1);transform:translateY(-25%)}50%{animation-timing-function:cubic-bezier(0,0,.2,1);transform:none}}.animate-bounce,.bounce{animation:-bounce 1s infinite}.animate-highlight,.highlight{animation:-highlight 2s ease-in-out infinite;outline-color:#fde047;outline-offset:-1px;outline-style:solid;outline-width:1px}@keyframes -highlight{50%{--tw-bg-opacity:1;background-color:rgb(254 252 232/var(--tw-bg-opacity,1));outline-offset:-4px;outline-width:4px}}.scale-0{--tw-scale-x:0;--tw-scale-y:0}.scale-0,.scale-50{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-50{--tw-scale-x:.5;--tw-scale-y:.5}.scale-75{--tw-scale-x:.75;--tw-scale-y:.75}.scale-75,.scale-90{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-90{--tw-scale-x:.9;--tw-scale-y:.9}.scale-95{--tw-scale-x:.95;--tw-scale-y:.95}.scale-100,.scale-95{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-100{--tw-scale-x:1;--tw-scale-y:1}.scale-105{--tw-scale-x:1.05;--tw-scale-y:1.05}.scale-105,.scale-110{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-110{--tw-scale-x:1.1;--tw-scale-y:1.1}.scale-125{--tw-scale-x:1.25;--tw-scale-y:1.25}.scale-125,.scale-150{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-150{--tw-scale-x:1.5;--tw-scale-y:1.5}.flip-x{--tw-scale-x:-1}.flip-x,.flip-y{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.flip-y{--tw-scale-y:-1}.rotate-0{--tw-rotate:0deg}.rotate-0,.rotate-1{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-1{--tw-rotate:1deg}.rotate-2{--tw-rotate:2deg}.rotate-2,.rotate-3{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-3{--tw-rotate:3deg}.rotate-6{--tw-rotate:6deg}.rotate-12,.rotate-6{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-12{--tw-rotate:12deg}.rotate-45{--tw-rotate:45deg}.rotate-45,.rotate-90{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-90{--tw-rotate:90deg}.rotate-135{--tw-rotate:135deg}.rotate-135,.rotate-180{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-180{--tw-rotate:180deg}.rotate-270{--tw-rotate:270deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.basis-0{flex-basis:0px}.basis-1{flex-basis:0.25rem}.basis-2{flex-basis:0.5rem}.basis-3{flex-basis:0.75rem}.basis-4{flex-basis:1rem}.basis-5{flex-basis:1.25rem}.basis-6{flex-basis:1.5rem}.basis-7{flex-basis:1.75rem}.basis-8{flex-basis:2rem}.basis-9{flex-basis:2.25rem}.basis-10{flex-basis:2.5rem}.basis-11{flex-basis:2.75rem}.basis-12{flex-basis:3rem}.basis-14{flex-basis:3.5rem}.basis-16{flex-basis:4rem}.basis-20{flex-basis:5rem}.basis-24{flex-basis:6rem}.basis-28{flex-basis:7rem}.basis-32{flex-basis:8rem}.basis-36{flex-basis:9rem}.basis-40{flex-basis:10rem}.basis-44{flex-basis:11rem}.basis-48{flex-basis:12rem}.basis-52{flex-basis:13rem}.basis-56{flex-basis:14rem}.basis-60{flex-basis:15rem}.basis-64{flex-basis:16rem}.basis-72{flex-basis:18rem}.basis-80{flex-basis:20rem}.basis-96{flex-basis:24rem}.basis-auto{flex-basis:auto}.basis-px{flex-basis:1px}.basis-0\.5{flex-basis:0.125rem}.basis-1\.5{flex-basis:0.375rem}.basis-2\.5{flex-basis:0.625rem}.basis-3\.5{flex-basis:0.875rem}.basis-1\/2{flex-basis:50%}.basis-1\/3{flex-basis:33.333333%}.basis-2\/3{flex-basis:66.666667%}.basis-1\/4{flex-basis:25%}.basis-2\/4{flex-basis:50%}.basis-3\/4{flex-basis:75%}.basis-1\/5{flex-basis:20%}.basis-2\/5{flex-basis:40%}.basis-3\/5{flex-basis:60%}.basis-4\/5{flex-basis:80%}.basis-1\/6{flex-basis:16.666667%}.basis-2\/6{flex-basis:33.333333%}.basis-3\/6{flex-basis:50%}.basis-4\/6{flex-basis:66.666667%}.basis-5\/6{flex-basis:83.333333%}.basis-1\/12{flex-basis:8.333333%}.basis-2\/12{flex-basis:16.666667%}.basis-3\/12{flex-basis:25%}.basis-4\/12{flex-basis:33.333333%}.basis-5\/12{flex-basis:41.666667%}.basis-6\/12{flex-basis:50%}.basis-7\/12{flex-basis:58.333333%}.basis-8\/12{flex-basis:66.666667%}.basis-9\/12{flex-basis:75%}.basis-10\/12{flex-basis:83.333333%}.basis-11\/12{flex-basis:91.666667%}.basis-full{flex-basis:100%}.row{display:flex;flex-direction:row}.center,.col{display:flex;flex-direction:column}.center,.center-row{align-items:center;justify-content:center}.center-row{display:flex;flex-direction:row}.center-x,.center-y{align-items:center;display:flex}.center-y{flex-direction:column}.row-reverse{display:flex;flex-direction:row-reverse}.col-reverse{display:flex;flex-direction:column-reverse}.flex-wrap{flex-wrap:wrap}.flex-wrap-reverse{flex-wrap:wrap-reverse}.flex-nowrap{flex-wrap:nowrap}.flex-1{flex:1 1 0%}.flex-auto{flex:1 1 auto}.flex-initial{flex:0 1 auto}.flex-none{flex:none}.grow{flex-grow:1!important}.grow-0{flex-grow:0!important}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.order-1{order:1}.order-2{order:2}.order-3{order:3}.order-4{order:4}.order-5{order:5}.order-6{order:6}.order-7{order:7}.order-8{order:8}.order-9{order:9}.order-10{order:10}.order-11{order:11}.order-12{order:12}.order-first{order:-9999}.order-last{order:9999}.order-none{order:0}.gap-0{gap:0}.gap-x-0{-moz-column-gap:0;column-gap:0}.gap-y-0{row-gap:0}.gap-px{gap:1px}.gap-x-px{-moz-column-gap:1px;column-gap:1px}.gap-y-px{row-gap:1px}.gap-0\.5{gap:.125rem}.gap-x-0\.5{-moz-column-gap:.125rem;column-gap:.125rem}.gap-y-0\.5{row-gap:.125rem}.gap-3px{gap:3px}.gap-1{gap:.25rem}.gap-x-1{-moz-column-gap:.25rem;column-gap:.25rem}.gap-y-1{row-gap:.25rem}.gap-1\.5{gap:.375rem}.gap-x-1\.5{-moz-column-gap:.375rem;column-gap:.375rem}.gap-y-1\.5{row-gap:.375rem}.gap-2{gap:.5rem}.gap-x-2{-moz-column-gap:.5rem;column-gap:.5rem}.gap-y-2{row-gap:.5rem}.gap-2\.5{gap:.625rem}.gap-x-2\.5{-moz-column-gap:.625rem;column-gap:.625rem}.gap-y-2\.5{row-gap:.625rem}.gap-3{gap:.75rem}.gap-x-3{-moz-column-gap:.75rem;column-gap:.75rem}.gap-y-3{row-gap:.75rem}.gap-3\.5{gap:.875rem}.gap-x-3\.5{-moz-column-gap:.875rem;column-gap:.875rem}.gap-y-3\.5{row-gap:.875rem}.gap-4{gap:1rem}.gap-x-4{-moz-column-gap:1rem;column-gap:1rem}.gap-y-4{row-gap:1rem}.gap-5{gap:1.25rem}.gap-x-5{-moz-column-gap:1.25rem;column-gap:1.25rem}.gap-y-5{row-gap:1.25rem}.gap-6{gap:1.5rem}.gap-x-6{-moz-column-gap:1.5rem;column-gap:1.5rem}.gap-y-6{row-gap:1.5rem}.gap-7{gap:1.75rem}.gap-x-7{-moz-column-gap:1.75rem;column-gap:1.75rem}.gap-y-7{row-gap:1.75rem}.gap-8{gap:2rem}.gap-x-8{-moz-column-gap:2rem;column-gap:2rem}.gap-y-8{row-gap:2rem}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.justify-around{justify-content:space-around}.justify-evenly{justify-content:space-evenly}.self-auto{align-self:auto}.self-start{align-self:flex-start}.self-end{align-self:flex-end}.self-center{align-self:center}.self-stretch{align-self:stretch}.self-baseline{align-self:baseline}.content-center{align-content:center}.content-start{align-content:flex-start}.content-end{align-content:flex-end}.content-between{align-content:space-between}.content-around{align-content:space-around}.content-evenly{align-content:space-evenly}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-baseline{align-items:baseline}.items-stretch{align-items:stretch}@font-face{font-display:fallback;font-family:D-DIN-PRO;font-weight:400;src:url(./fonts/D-DIN-PRO-400-Regular.otf)}@font-face{font-display:fallback;font-family:D-DIN-PRO;font-weight:500;src:url(./fonts/D-DIN-PRO-700-Bold.otf)}.num{font-family:D-DIN-PRO}@font-face{font-display:fallback;font-family:Nunito;font-weight:400;src:url(./fonts/Nunito-Regular.ttf)}@font-face{font-display:fallback;font-family:Nunito;font-weight:700;src:url(./fonts/Nunito-Bold.ttf)}@font-face{font-display:fallback;font-family:Nunito;font-weight:300;src:url(./fonts/Nunito-Light.ttf)}.font-brand{font-family:Nunito;font-weight:400}@supports not (gap:4px){.gap-px>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1px*(1 - var(--tw-space-x-reverse)));margin-right:calc(1px*var(--tw-space-x-reverse))}.gap-0\.5>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(2px*(1 - var(--tw-space-x-reverse)));margin-right:calc(2px*var(--tw-space-x-reverse))}.gap-3px>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(3px*(1 - var(--tw-space-x-reverse)));margin-right:calc(3px*var(--tw-space-x-reverse))}.gap-1>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.25rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.25rem*var(--tw-space-x-reverse))}.gap-1\.5>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(6px*(1 - var(--tw-space-x-reverse)));margin-right:calc(6px*var(--tw-space-x-reverse))}.gap-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.5rem*var(--tw-space-x-reverse))}.gap-2\.5>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(10px*(1 - var(--tw-space-x-reverse)));margin-right:calc(10px*var(--tw-space-x-reverse))}.gap-3>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.75rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.75rem*var(--tw-space-x-reverse))}.gap-3\.5>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(14px*(1 - var(--tw-space-x-reverse)));margin-right:calc(14px*var(--tw-space-x-reverse))}.gap-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1rem*var(--tw-space-x-reverse))}.gap-5>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1.25rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1.25rem*var(--tw-space-x-reverse))}.gap-6>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1.5rem*var(--tw-space-x-reverse))}.gap-7>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1.75rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1.75rem*var(--tw-space-x-reverse))}.gap-8>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(2rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(2rem*var(--tw-space-x-reverse))}.col.gap-px>:not([hidden])~:not([hidden]),.gap-px.flex-row>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1px*var(--tw-space-y-reverse));margin-top:calc(1px*(1 - var(--tw-space-y-reverse)))}.col.gap-0\.5>:not([hidden])~:not([hidden]),.gap-0\.5.flex-row>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(2px*var(--tw-space-y-reverse));margin-top:calc(2px*(1 - var(--tw-space-y-reverse)))}.col.gap-3px>:not([hidden])~:not([hidden]),.gap-3px.flex-row>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(3px*var(--tw-space-y-reverse));margin-top:calc(3px*(1 - var(--tw-space-y-reverse)))}.col.gap-1>:not([hidden])~:not([hidden]),.gap-1.flex-row>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.25rem*var(--tw-space-y-reverse));margin-top:calc(.25rem*(1 - var(--tw-space-y-reverse)))}.col.gap-1\.5>:not([hidden])~:not([hidden]),.gap-1\.5.flex-row>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(6px*var(--tw-space-y-reverse));margin-top:calc(6px*(1 - var(--tw-space-y-reverse)))}.col.gap-2>:not([hidden])~:not([hidden]),.gap-2.flex-row>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.5rem*var(--tw-space-y-reverse));margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)))}.col.gap-2\.5>:not([hidden])~:not([hidden]),.gap-2\.5.flex-row>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(10px*var(--tw-space-y-reverse));margin-top:calc(10px*(1 - var(--tw-space-y-reverse)))}.col.gap-3>:not([hidden])~:not([hidden]),.gap-3.flex-row>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.75rem*var(--tw-space-y-reverse));margin-top:calc(.75rem*(1 - var(--tw-space-y-reverse)))}.col.gap-3\.5>:not([hidden])~:not([hidden]),.gap-3\.5.flex-row>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(14px*var(--tw-space-y-reverse));margin-top:calc(14px*(1 - var(--tw-space-y-reverse)))}.col.gap-4>:not([hidden])~:not([hidden]),.gap-4.flex-row>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1rem*var(--tw-space-y-reverse));margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)))}.col.gap-5>:not([hidden])~:not([hidden]),.gap-5.flex-row>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1.25rem*var(--tw-space-y-reverse));margin-top:calc(1.25rem*(1 - var(--tw-space-y-reverse)))}.col.gap-6>:not([hidden])~:not([hidden]),.gap-6.flex-row>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1.5rem*var(--tw-space-y-reverse));margin-top:calc(1.5rem*(1 - var(--tw-space-y-reverse)))}.col.gap-7>:not([hidden])~:not([hidden]),.gap-7.flex-row>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1.75rem*var(--tw-space-y-reverse));margin-top:calc(1.75rem*(1 - var(--tw-space-y-reverse)))}.col.gap-8>:not([hidden])~:not([hidden]),.gap-8.flex-row>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(2rem*var(--tw-space-y-reverse));margin-top:calc(2rem*(1 - var(--tw-space-y-reverse)))}.nav-item>a>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.25rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.25rem*var(--tw-space-x-reverse))}} \ No newline at end of file +*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*! tailwindcss v3.4.17 | MIT License | https://tailwindcss.com*/*,:after,:before{border-color:rgb(var(--color-gray-200-rgb));border-style:solid;border-width:0;box-sizing:border-box}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;font-family:-apple-system,Noto Sans,Helvetica Neue,Helvetica,Nimbus Sans L,Arial,Liberation Sans,PingFang SC,Hiragino Sans GB,Noto Sans CJK SC,Source Han Sans SC,Source Han Sans CN,Microsoft YaHei,Wenquanyi Micro Hei,WenQuanYi Zen Hei,ST Heiti,SimHei,WenQuanYi Zen Hei Sharp,sans-serif;font-feature-settings:normal;font-variation-settings:normal;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-tap-highlight-color:transparent}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-size:1em;font-variation-settings:normal}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{color:inherit;font-family:inherit;font-feature-settings:inherit;font-size:100%;font-variation-settings:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:rgb(var(--color-gray-400-rgb));opacity:1}input::placeholder,textarea::placeholder{color:rgb(var(--color-gray-400-rgb));opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]:where(:not([hidden=until-found])){display:none}:root{--screen-2xl:1720px;--color-gray-50:#fcfdfe;--color-gray-100:#eff1f3;--color-gray-200:#ebedf3;--color-gray-300:#d2d6e5;--color-gray-400:#b2b9c5;--color-gray-500:#64758b;--color-gray-600:#4a577f;--color-gray-700:#3d4667;--color-gray-800:#353d57;--color-gray-900:#30394a;--color-gray-950:#0b0f18;--color-gray-50-rgb:252,253,254;--color-gray-100-rgb:239,241,243;--color-gray-200-rgb:235,237,243;--color-gray-300-rgb:210,214,229;--color-gray-400-rgb:178,185,197;--color-gray-500-rgb:100,117,139;--color-gray-600-rgb:74,87,127;--color-gray-700-rgb:61,70,103;--color-gray-800-rgb:53,61,87;--color-gray-900-rgb:48,57,74;--color-gray-950-rgb:11,15,24;--color-primary-50:#eef6ff;--color-primary-100:#d9eaff;--color-primary-200:#bcdcff;--color-primary-300:#8ec6ff;--color-primary-400:#59a5ff;--color-primary-500:#3883fa;--color-primary-600:#2b67e5;--color-primary-700:#144ce1;--color-primary-800:#173db6;--color-primary-900:#19388f;--color-primary-950:#142457;--color-primary-50-rgb:238,246,255;--color-primary-100-rgb:217,234,255;--color-primary-200-rgb:188,220,255;--color-primary-300-rgb:142,198,255;--color-primary-400-rgb:89,165,255;--color-primary-500-rgb:56,131,250;--color-primary-600-rgb:43,103,229;--color-primary-700-rgb:20,76,225;--color-primary-800-rgb:23,61,182;--color-primary-900-rgb:25,56,143;--color-primary-950-rgb:20,36,87;--color-secondary-50:#e7f6ff;--color-secondary-100:#cdecff;--color-secondary-200:#9bd9ff;--color-secondary-300:#77cbff;--color-secondary-400:#60c2ff;--color-secondary-500:#37b2fe;--color-secondary-600:#18a6fd;--color-secondary-700:#1099ed;--color-secondary-800:#078ada;--color-secondary-900:#046bab;--color-secondary-950:#062a4b;--color-secondary-50-rgb:231,246,255;--color-secondary-100-rgb:205,236,255;--color-secondary-200-rgb:155,217,255;--color-secondary-300-rgb:119,203,255;--color-secondary-400-rgb:96,194,255;--color-secondary-500-rgb:55,178,254;--color-secondary-600-rgb:24,166,253;--color-secondary-700-rgb:16,153,237;--color-secondary-800-rgb:7,138,218;--color-secondary-900-rgb:4,107,171;--color-secondary-950-rgb:6,42,75;--color-success-50:#effaf6;--color-success-100:#d6f2e7;--color-success-200:#ade5ce;--color-success-300:#83d7b6;--color-success-400:#5aca9d;--color-success-500:#31bd85;--color-success-600:#2ba675;--color-success-700:#28996c;--color-success-800:#21805a;--color-success-900:#185e3b;--color-success-950:#0e3421;--color-success-50-rgb:239,250,246;--color-success-100-rgb:214,242,231;--color-success-200-rgb:173,229,206;--color-success-300-rgb:131,215,182;--color-success-400-rgb:90,202,157;--color-success-500-rgb:49,189,133;--color-success-600-rgb:43,166,117;--color-success-700-rgb:40,153,108;--color-success-800-rgb:33,128,90;--color-success-900-rgb:24,94,59;--color-success-950-rgb:14,52,33;--color-warning-50:#fff4ea;--color-warning-100:#ffecdb;--color-warning-200:#ffd2a9;--color-warning-300:#ffbc7e;--color-warning-400:#ffaf65;--color-warning-500:#ff9f46;--color-warning-600:#f38f19;--color-warning-700:#ed8307;--color-warning-800:#d17100;--color-warning-900:#af5f01;--color-warning-950:#441506;--color-warning-50-rgb:255,244,234;--color-warning-100-rgb:255,236,219;--color-warning-200-rgb:255,210,169;--color-warning-300-rgb:255,188,126;--color-warning-400-rgb:255,175,101;--color-warning-500-rgb:255,159,70;--color-warning-600-rgb:243,143,25;--color-warning-700-rgb:237,131,7;--color-warning-800-rgb:209,113,0;--color-warning-900-rgb:175,95,1;--color-warning-950-rgb:68,21,6;--color-danger-50:#ffebeb;--color-danger-100:#ffd5d5;--color-danger-200:#ffb1b1;--color-danger-300:#ff9292;--color-danger-400:#ff7c7c;--color-danger-500:#fc5959;--color-danger-600:#fb2b2b;--color-danger-700:#d91b1b;--color-danger-800:#ba1313;--color-danger-900:#a20606;--color-danger-950:#470808;--color-danger-50-rgb:255,235,235;--color-danger-100-rgb:255,213,213;--color-danger-200-rgb:255,177,177;--color-danger-300-rgb:255,146,146;--color-danger-400-rgb:255,124,124;--color-danger-500-rgb:252,89,89;--color-danger-600-rgb:251,43,43;--color-danger-700-rgb:217,27,27;--color-danger-800-rgb:186,19,19;--color-danger-900-rgb:162,6,6;--color-danger-950-rgb:71,8,8;--color-important-50:#fff8f5;--color-important-100:#ffe2d9;--color-important-200:#ffcebf;--color-important-300:#ffb29b;--color-important-400:#ff8c68;--color-important-500:#ff8058;--color-important-600:#ff6f42;--color-important-700:#ff4912;--color-important-800:#c83509;--color-important-900:#611700;--color-important-950:#440609;--color-important-50-rgb:255,248,245;--color-important-100-rgb:255,226,217;--color-important-200-rgb:255,206,191;--color-important-300-rgb:255,178,155;--color-important-400-rgb:255,140,104;--color-important-500-rgb:255,128,88;--color-important-600-rgb:255,111,66;--color-important-700-rgb:255,73,18;--color-important-800-rgb:200,53,9;--color-important-900-rgb:97,23,0;--color-important-950-rgb:68,6,9;--color-special-50:#efecfa;--color-special-100:#e4dff7;--color-special-200:#c4b6ff;--color-special-300:#a38cff;--color-special-400:#8a6ff5;--color-special-500:#8166ee;--color-special-600:#7055df;--color-special-700:#513baa;--color-special-800:#452da5;--color-special-900:#30216e;--color-special-950:#271560;--color-special-50-rgb:239,236,250;--color-special-100-rgb:228,223,247;--color-special-200-rgb:196,182,255;--color-special-300-rgb:163,140,255;--color-special-400-rgb:138,111,245;--color-special-500-rgb:129,102,238;--color-special-600-rgb:112,85,223;--color-special-700-rgb:81,59,170;--color-special-800-rgb:69,45,165;--color-special-900-rgb:48,33,110;--color-special-950-rgb:39,21,96;--color-inherit:inherit;--color-transparent:transparent;--color-current:currentColor;--color-black:#000;--color-white:#fff;--color-canvas:#fff;--color-canvas-light:#fff;--color-canvas-dark:#fcfdfe;--color-inverse:#000;--color-surface:#eff1f3;--color-surface-light:#fcfdfe;--color-surface-strong:#ebedf3;--color-fore:#30394a;--color-fore-in-light:#30394a;--color-fore-in-dark:#fff;--color-focus:#bcdcff;--color-link:#2b47a2;--color-link-hover:#144ce1;--color-link-visited:#6328a4;--color-link-active:#144ce1;--color-placeholder:#64758b;--color-border:#ebedf3;--color-border-strong:#d2d6e5;--color-border-light:#eff1f3;--color-black-rgb:0,0,0;--color-white-rgb:255,255,255;--color-canvas-rgb:255,255,255;--color-canvas-light-rgb:255,255,255;--color-canvas-dark-rgb:252,253,254;--color-inverse-rgb:0,0,0;--color-surface-rgb:239,241,243;--color-surface-light-rgb:252,253,254;--color-surface-strong-rgb:235,237,243;--color-fore-rgb:48,57,74;--color-fore-in-light-rgb:48,57,74;--color-fore-in-dark-rgb:255,255,255;--color-focus-rgb:188,220,255;--color-link-rgb:43,71,162;--color-link-hover-rgb:20,76,225;--color-link-visited-rgb:99,40,164;--color-link-active-rgb:20,76,225;--color-placeholder-rgb:100,117,139;--color-border-rgb:235,237,243;--color-border-strong-rgb:210,214,229;--color-border-light-rgb:239,241,243;--radius-none:0px;--radius-sm:0.0625rem;--radius:0.125rem;--radius-md:0.25rem;--radius-lg:0.375rem;--radius-xl:0.5rem;--radius-2xl:0.75rem;--radius-3xl:1rem;--radius-full:9999px;--shadow-sm:0 1px 2px 0 rgba(0,0,0,.04),0 0 2px -1px rgba(0,0,0,.01);--shadow:0 3px 8px 0 rgba(0,0,0,.04),0 1px 2px -1px rgba(0,0,0,.01);--shadow-md:0 2px 6px -1px rgba(0,0,0,.2),0 1px 4px -2px rgba(0,0,0,.15);--shadow-lg:0 5px 15px -3px rgba(0,0,0,.2),0 2px 6px -4px rgba(0,0,0,.15);--shadow-xl:0 10px 25px -5px rgba(0,0,0,.2),0 4px 10px -6px rgba(0,0,0,.15);--shadow-2xl:0 10px 50px -10px rgba(0,0,0,.4),0 8px 20px -10px rgba(0,0,0,.3);--shadow-inner:inset 0 2px 4px 0 rgba(0,0,0,.05);--shadow-none:none;--space:0.25rem;--font-size-article:0.875rem;--font-size-root:16px;--font-size-page-lineHeight:1.5384615385}.dark{--color-gray-50:#0b0f18;--color-gray-100:#30394a;--color-gray-200:#353d57;--color-gray-300:#3d4667;--color-gray-400:#4a577f;--color-gray-500:#64758b;--color-gray-600:#b2b9c5;--color-gray-700:#d2d6e5;--color-gray-800:#ebedf3;--color-gray-900:#eff1f3;--color-gray-950:#fcfdfe;--color-gray-50-rgb:11,15,24;--color-gray-100-rgb:48,57,74;--color-gray-200-rgb:53,61,87;--color-gray-300-rgb:61,70,103;--color-gray-400-rgb:74,87,127;--color-gray-500-rgb:100,117,139;--color-gray-600-rgb:178,185,197;--color-gray-700-rgb:210,214,229;--color-gray-800-rgb:235,237,243;--color-gray-900-rgb:239,241,243;--color-gray-950-rgb:252,253,254;--color-primary-50:#142457;--color-primary-100:#19388f;--color-primary-200:#173db6;--color-primary-300:#144ce1;--color-primary-400:#2b67e5;--color-primary-500:#3883fa;--color-primary-600:#59a5ff;--color-primary-700:#8ec6ff;--color-primary-800:#bcdcff;--color-primary-900:#d9eaff;--color-primary-950:#eef6ff;--color-primary-50-rgb:20,36,87;--color-primary-100-rgb:25,56,143;--color-primary-200-rgb:23,61,182;--color-primary-300-rgb:20,76,225;--color-primary-400-rgb:43,103,229;--color-primary-500-rgb:56,131,250;--color-primary-600-rgb:89,165,255;--color-primary-700-rgb:142,198,255;--color-primary-800-rgb:188,220,255;--color-primary-900-rgb:217,234,255;--color-primary-950-rgb:238,246,255;--color-secondary-50:#062a4b;--color-secondary-100:#046bab;--color-secondary-200:#078ada;--color-secondary-300:#1099ed;--color-secondary-400:#18a6fd;--color-secondary-500:#37b2fe;--color-secondary-600:#60c2ff;--color-secondary-700:#77cbff;--color-secondary-800:#9bd9ff;--color-secondary-900:#cdecff;--color-secondary-950:#e7f6ff;--color-secondary-50-rgb:6,42,75;--color-secondary-100-rgb:4,107,171;--color-secondary-200-rgb:7,138,218;--color-secondary-300-rgb:16,153,237;--color-secondary-400-rgb:24,166,253;--color-secondary-500-rgb:55,178,254;--color-secondary-600-rgb:96,194,255;--color-secondary-700-rgb:119,203,255;--color-secondary-800-rgb:155,217,255;--color-secondary-900-rgb:205,236,255;--color-secondary-950-rgb:231,246,255;--color-success-50:#0e3421;--color-success-100:#185e3b;--color-success-200:#21805a;--color-success-300:#28996c;--color-success-400:#2ba675;--color-success-500:#31bd85;--color-success-600:#5aca9d;--color-success-700:#83d7b6;--color-success-800:#ade5ce;--color-success-900:#d6f2e7;--color-success-950:#effaf6;--color-success-50-rgb:14,52,33;--color-success-100-rgb:24,94,59;--color-success-200-rgb:33,128,90;--color-success-300-rgb:40,153,108;--color-success-400-rgb:43,166,117;--color-success-500-rgb:49,189,133;--color-success-600-rgb:90,202,157;--color-success-700-rgb:131,215,182;--color-success-800-rgb:173,229,206;--color-success-900-rgb:214,242,231;--color-success-950-rgb:239,250,246;--color-warning-50:#441506;--color-warning-100:#af5f01;--color-warning-200:#d17100;--color-warning-300:#ed8307;--color-warning-400:#f38f19;--color-warning-500:#ff9f46;--color-warning-600:#ffaf65;--color-warning-700:#ffbc7e;--color-warning-800:#ffd2a9;--color-warning-900:#ffecdb;--color-warning-950:#fff4ea;--color-warning-50-rgb:68,21,6;--color-warning-100-rgb:175,95,1;--color-warning-200-rgb:209,113,0;--color-warning-300-rgb:237,131,7;--color-warning-400-rgb:243,143,25;--color-warning-500-rgb:255,159,70;--color-warning-600-rgb:255,175,101;--color-warning-700-rgb:255,188,126;--color-warning-800-rgb:255,210,169;--color-warning-900-rgb:255,236,219;--color-warning-950-rgb:255,244,234;--color-danger-50:#470808;--color-danger-100:#a20606;--color-danger-200:#ba1313;--color-danger-300:#d91b1b;--color-danger-400:#fb2b2b;--color-danger-500:#fc5959;--color-danger-600:#ff7c7c;--color-danger-700:#ff9292;--color-danger-800:#ffb1b1;--color-danger-900:#ffd5d5;--color-danger-950:#ffebeb;--color-danger-50-rgb:71,8,8;--color-danger-100-rgb:162,6,6;--color-danger-200-rgb:186,19,19;--color-danger-300-rgb:217,27,27;--color-danger-400-rgb:251,43,43;--color-danger-500-rgb:252,89,89;--color-danger-600-rgb:255,124,124;--color-danger-700-rgb:255,146,146;--color-danger-800-rgb:255,177,177;--color-danger-900-rgb:255,213,213;--color-danger-950-rgb:255,235,235;--color-important-50:#440609;--color-important-100:#611700;--color-important-200:#c83509;--color-important-300:#ff4912;--color-important-400:#ff6f42;--color-important-500:#ff8058;--color-important-600:#ff8c68;--color-important-700:#ffb29b;--color-important-800:#ffcebf;--color-important-900:#ffe2d9;--color-important-950:#fff8f5;--color-important-50-rgb:68,6,9;--color-important-100-rgb:97,23,0;--color-important-200-rgb:200,53,9;--color-important-300-rgb:255,73,18;--color-important-400-rgb:255,111,66;--color-important-500-rgb:255,128,88;--color-important-600-rgb:255,140,104;--color-important-700-rgb:255,178,155;--color-important-800-rgb:255,206,191;--color-important-900-rgb:255,226,217;--color-important-950-rgb:255,248,245;--color-special-50:#271560;--color-special-100:#30216e;--color-special-200:#452da5;--color-special-300:#513baa;--color-special-400:#7055df;--color-special-500:#8166ee;--color-special-600:#8a6ff5;--color-special-700:#a38cff;--color-special-800:#c4b6ff;--color-special-900:#e4dff7;--color-special-950:#efecfa;--color-special-50-rgb:39,21,96;--color-special-100-rgb:48,33,110;--color-special-200-rgb:69,45,165;--color-special-300-rgb:81,59,170;--color-special-400-rgb:112,85,223;--color-special-500-rgb:129,102,238;--color-special-600-rgb:138,111,245;--color-special-700-rgb:163,140,255;--color-special-800-rgb:196,182,255;--color-special-900-rgb:228,223,247;--color-special-950-rgb:239,236,250;--color-canvas:#0b0f18;--color-inverse:#fff;--color-surface:#353d57;--color-surface-light:#30394a;--color-surface-strong:#3d4667;--color-fore:#ebedf3;--color-focus:#173db6;--color-link:#59a5ff;--color-link-hover:#3883fa;--color-link-visited:#bcdcff;--color-link-active:#bcdcff;--color-placeholder:#4a577f;--color-border:#353d57;--color-border-strong:#3d4667;--color-border-light:#30394a;--color-canvas-rgb:11,15,24;--color-inverse-rgb:255,255,255;--color-surface-rgb:53,61,87;--color-surface-light-rgb:48,57,74;--color-surface-strong-rgb:61,70,103;--color-fore-rgb:235,237,243;--color-focus-rgb:23,61,182;--color-link-rgb:89,165,255;--color-link-hover-rgb:56,131,250;--color-link-visited-rgb:188,220,255;--color-link-active-rgb:188,220,255;--color-placeholder-rgb:74,87,127;--color-border-rgb:53,61,87;--color-border-strong-rgb:61,70,103;--color-border-light-rgb:48,57,74}.light-in-dark{--color-gray-50:#fcfdfe;--color-gray-100:#eff1f3;--color-gray-200:#ebedf3;--color-gray-300:#d2d6e5;--color-gray-400:#b2b9c5;--color-gray-500:#64758b;--color-gray-600:#4a577f;--color-gray-700:#3d4667;--color-gray-800:#353d57;--color-gray-900:#30394a;--color-gray-950:#0b0f18;--color-gray-50-rgb:252,253,254;--color-gray-100-rgb:239,241,243;--color-gray-200-rgb:235,237,243;--color-gray-300-rgb:210,214,229;--color-gray-400-rgb:178,185,197;--color-gray-500-rgb:100,117,139;--color-gray-600-rgb:74,87,127;--color-gray-700-rgb:61,70,103;--color-gray-800-rgb:53,61,87;--color-gray-900-rgb:48,57,74;--color-gray-950-rgb:11,15,24;--color-primary-50:#eef6ff;--color-primary-100:#d9eaff;--color-primary-200:#bcdcff;--color-primary-300:#8ec6ff;--color-primary-400:#59a5ff;--color-primary-500:#3883fa;--color-primary-600:#2b67e5;--color-primary-700:#144ce1;--color-primary-800:#173db6;--color-primary-900:#19388f;--color-primary-950:#142457;--color-primary-50-rgb:238,246,255;--color-primary-100-rgb:217,234,255;--color-primary-200-rgb:188,220,255;--color-primary-300-rgb:142,198,255;--color-primary-400-rgb:89,165,255;--color-primary-500-rgb:56,131,250;--color-primary-600-rgb:43,103,229;--color-primary-700-rgb:20,76,225;--color-primary-800-rgb:23,61,182;--color-primary-900-rgb:25,56,143;--color-primary-950-rgb:20,36,87;--color-secondary-50:#e7f6ff;--color-secondary-100:#cdecff;--color-secondary-200:#9bd9ff;--color-secondary-300:#77cbff;--color-secondary-400:#60c2ff;--color-secondary-500:#37b2fe;--color-secondary-600:#18a6fd;--color-secondary-700:#1099ed;--color-secondary-800:#078ada;--color-secondary-900:#046bab;--color-secondary-950:#062a4b;--color-secondary-50-rgb:231,246,255;--color-secondary-100-rgb:205,236,255;--color-secondary-200-rgb:155,217,255;--color-secondary-300-rgb:119,203,255;--color-secondary-400-rgb:96,194,255;--color-secondary-500-rgb:55,178,254;--color-secondary-600-rgb:24,166,253;--color-secondary-700-rgb:16,153,237;--color-secondary-800-rgb:7,138,218;--color-secondary-900-rgb:4,107,171;--color-secondary-950-rgb:6,42,75;--color-success-50:#effaf6;--color-success-100:#d6f2e7;--color-success-200:#ade5ce;--color-success-300:#83d7b6;--color-success-400:#5aca9d;--color-success-500:#31bd85;--color-success-600:#2ba675;--color-success-700:#28996c;--color-success-800:#21805a;--color-success-900:#185e3b;--color-success-950:#0e3421;--color-success-50-rgb:239,250,246;--color-success-100-rgb:214,242,231;--color-success-200-rgb:173,229,206;--color-success-300-rgb:131,215,182;--color-success-400-rgb:90,202,157;--color-success-500-rgb:49,189,133;--color-success-600-rgb:43,166,117;--color-success-700-rgb:40,153,108;--color-success-800-rgb:33,128,90;--color-success-900-rgb:24,94,59;--color-success-950-rgb:14,52,33;--color-warning-50:#fff4ea;--color-warning-100:#ffecdb;--color-warning-200:#ffd2a9;--color-warning-300:#ffbc7e;--color-warning-400:#ffaf65;--color-warning-500:#ff9f46;--color-warning-600:#f38f19;--color-warning-700:#ed8307;--color-warning-800:#d17100;--color-warning-900:#af5f01;--color-warning-950:#441506;--color-warning-50-rgb:255,244,234;--color-warning-100-rgb:255,236,219;--color-warning-200-rgb:255,210,169;--color-warning-300-rgb:255,188,126;--color-warning-400-rgb:255,175,101;--color-warning-500-rgb:255,159,70;--color-warning-600-rgb:243,143,25;--color-warning-700-rgb:237,131,7;--color-warning-800-rgb:209,113,0;--color-warning-900-rgb:175,95,1;--color-warning-950-rgb:68,21,6;--color-danger-50:#ffebeb;--color-danger-100:#ffd5d5;--color-danger-200:#ffb1b1;--color-danger-300:#ff9292;--color-danger-400:#ff7c7c;--color-danger-500:#fc5959;--color-danger-600:#fb2b2b;--color-danger-700:#d91b1b;--color-danger-800:#ba1313;--color-danger-900:#a20606;--color-danger-950:#470808;--color-danger-50-rgb:255,235,235;--color-danger-100-rgb:255,213,213;--color-danger-200-rgb:255,177,177;--color-danger-300-rgb:255,146,146;--color-danger-400-rgb:255,124,124;--color-danger-500-rgb:252,89,89;--color-danger-600-rgb:251,43,43;--color-danger-700-rgb:217,27,27;--color-danger-800-rgb:186,19,19;--color-danger-900-rgb:162,6,6;--color-danger-950-rgb:71,8,8;--color-important-50:#fff8f5;--color-important-100:#ffe2d9;--color-important-200:#ffcebf;--color-important-300:#ffb29b;--color-important-400:#ff8c68;--color-important-500:#ff8058;--color-important-600:#ff6f42;--color-important-700:#ff4912;--color-important-800:#c83509;--color-important-900:#611700;--color-important-950:#440609;--color-important-50-rgb:255,248,245;--color-important-100-rgb:255,226,217;--color-important-200-rgb:255,206,191;--color-important-300-rgb:255,178,155;--color-important-400-rgb:255,140,104;--color-important-500-rgb:255,128,88;--color-important-600-rgb:255,111,66;--color-important-700-rgb:255,73,18;--color-important-800-rgb:200,53,9;--color-important-900-rgb:97,23,0;--color-important-950-rgb:68,6,9;--color-special-50:#efecfa;--color-special-100:#e4dff7;--color-special-200:#c4b6ff;--color-special-300:#a38cff;--color-special-400:#8a6ff5;--color-special-500:#8166ee;--color-special-600:#7055df;--color-special-700:#513baa;--color-special-800:#452da5;--color-special-900:#30216e;--color-special-950:#271560;--color-special-50-rgb:239,236,250;--color-special-100-rgb:228,223,247;--color-special-200-rgb:196,182,255;--color-special-300-rgb:163,140,255;--color-special-400-rgb:138,111,245;--color-special-500-rgb:129,102,238;--color-special-600-rgb:112,85,223;--color-special-700-rgb:81,59,170;--color-special-800-rgb:69,45,165;--color-special-900-rgb:48,33,110;--color-special-950-rgb:39,21,96;--color-inherit:inherit;--color-transparent:transparent;--color-current:currentColor;--color-black:#000;--color-white:#fff;--color-canvas:#fff;--color-canvas-light:#fff;--color-canvas-dark:#fcfdfe;--color-inverse:#000;--color-surface:#eff1f3;--color-surface-light:#fcfdfe;--color-surface-strong:#ebedf3;--color-fore:#30394a;--color-fore-in-light:#30394a;--color-fore-in-dark:#fff;--color-focus:#bcdcff;--color-link:#2b47a2;--color-link-hover:#144ce1;--color-link-visited:#6328a4;--color-link-active:#144ce1;--color-placeholder:#64758b;--color-border:#ebedf3;--color-border-strong:#d2d6e5;--color-border-light:#eff1f3;--color-black-rgb:0,0,0;--color-white-rgb:255,255,255;--color-canvas-rgb:255,255,255;--color-canvas-light-rgb:255,255,255;--color-canvas-dark-rgb:252,253,254;--color-inverse-rgb:0,0,0;--color-surface-rgb:239,241,243;--color-surface-light-rgb:252,253,254;--color-surface-strong-rgb:235,237,243;--color-fore-rgb:48,57,74;--color-fore-in-light-rgb:48,57,74;--color-fore-in-dark-rgb:255,255,255;--color-focus-rgb:188,220,255;--color-link-rgb:43,71,162;--color-link-hover-rgb:20,76,225;--color-link-visited-rgb:99,40,164;--color-link-active-rgb:20,76,225;--color-placeholder-rgb:100,117,139;--color-border-rgb:235,237,243;--color-border-strong-rgb:210,214,229;--color-border-light-rgb:239,241,243}body{--btn-bg:var(--color-gray-50)}@media (prefers-color-scheme:dark){.dark-auto{--color-gray-50:#0b0f18;--color-gray-100:#30394a;--color-gray-200:#353d57;--color-gray-300:#3d4667;--color-gray-400:#4a577f;--color-gray-500:#64758b;--color-gray-600:#b2b9c5;--color-gray-700:#d2d6e5;--color-gray-800:#ebedf3;--color-gray-900:#eff1f3;--color-gray-950:#fcfdfe;--color-gray-50-rgb:11,15,24;--color-gray-100-rgb:48,57,74;--color-gray-200-rgb:53,61,87;--color-gray-300-rgb:61,70,103;--color-gray-400-rgb:74,87,127;--color-gray-500-rgb:100,117,139;--color-gray-600-rgb:178,185,197;--color-gray-700-rgb:210,214,229;--color-gray-800-rgb:235,237,243;--color-gray-900-rgb:239,241,243;--color-gray-950-rgb:252,253,254;--color-primary-50:#142457;--color-primary-100:#19388f;--color-primary-200:#173db6;--color-primary-300:#144ce1;--color-primary-400:#2b67e5;--color-primary-500:#3883fa;--color-primary-600:#59a5ff;--color-primary-700:#8ec6ff;--color-primary-800:#bcdcff;--color-primary-900:#d9eaff;--color-primary-950:#eef6ff;--color-primary-50-rgb:20,36,87;--color-primary-100-rgb:25,56,143;--color-primary-200-rgb:23,61,182;--color-primary-300-rgb:20,76,225;--color-primary-400-rgb:43,103,229;--color-primary-500-rgb:56,131,250;--color-primary-600-rgb:89,165,255;--color-primary-700-rgb:142,198,255;--color-primary-800-rgb:188,220,255;--color-primary-900-rgb:217,234,255;--color-primary-950-rgb:238,246,255;--color-secondary-50:#062a4b;--color-secondary-100:#046bab;--color-secondary-200:#078ada;--color-secondary-300:#1099ed;--color-secondary-400:#18a6fd;--color-secondary-500:#37b2fe;--color-secondary-600:#60c2ff;--color-secondary-700:#77cbff;--color-secondary-800:#9bd9ff;--color-secondary-900:#cdecff;--color-secondary-950:#e7f6ff;--color-secondary-50-rgb:6,42,75;--color-secondary-100-rgb:4,107,171;--color-secondary-200-rgb:7,138,218;--color-secondary-300-rgb:16,153,237;--color-secondary-400-rgb:24,166,253;--color-secondary-500-rgb:55,178,254;--color-secondary-600-rgb:96,194,255;--color-secondary-700-rgb:119,203,255;--color-secondary-800-rgb:155,217,255;--color-secondary-900-rgb:205,236,255;--color-secondary-950-rgb:231,246,255;--color-success-50:#0e3421;--color-success-100:#185e3b;--color-success-200:#21805a;--color-success-300:#28996c;--color-success-400:#2ba675;--color-success-500:#31bd85;--color-success-600:#5aca9d;--color-success-700:#83d7b6;--color-success-800:#ade5ce;--color-success-900:#d6f2e7;--color-success-950:#effaf6;--color-success-50-rgb:14,52,33;--color-success-100-rgb:24,94,59;--color-success-200-rgb:33,128,90;--color-success-300-rgb:40,153,108;--color-success-400-rgb:43,166,117;--color-success-500-rgb:49,189,133;--color-success-600-rgb:90,202,157;--color-success-700-rgb:131,215,182;--color-success-800-rgb:173,229,206;--color-success-900-rgb:214,242,231;--color-success-950-rgb:239,250,246;--color-warning-50:#441506;--color-warning-100:#af5f01;--color-warning-200:#d17100;--color-warning-300:#ed8307;--color-warning-400:#f38f19;--color-warning-500:#ff9f46;--color-warning-600:#ffaf65;--color-warning-700:#ffbc7e;--color-warning-800:#ffd2a9;--color-warning-900:#ffecdb;--color-warning-950:#fff4ea;--color-warning-50-rgb:68,21,6;--color-warning-100-rgb:175,95,1;--color-warning-200-rgb:209,113,0;--color-warning-300-rgb:237,131,7;--color-warning-400-rgb:243,143,25;--color-warning-500-rgb:255,159,70;--color-warning-600-rgb:255,175,101;--color-warning-700-rgb:255,188,126;--color-warning-800-rgb:255,210,169;--color-warning-900-rgb:255,236,219;--color-warning-950-rgb:255,244,234;--color-danger-50:#470808;--color-danger-100:#a20606;--color-danger-200:#ba1313;--color-danger-300:#d91b1b;--color-danger-400:#fb2b2b;--color-danger-500:#fc5959;--color-danger-600:#ff7c7c;--color-danger-700:#ff9292;--color-danger-800:#ffb1b1;--color-danger-900:#ffd5d5;--color-danger-950:#ffebeb;--color-danger-50-rgb:71,8,8;--color-danger-100-rgb:162,6,6;--color-danger-200-rgb:186,19,19;--color-danger-300-rgb:217,27,27;--color-danger-400-rgb:251,43,43;--color-danger-500-rgb:252,89,89;--color-danger-600-rgb:255,124,124;--color-danger-700-rgb:255,146,146;--color-danger-800-rgb:255,177,177;--color-danger-900-rgb:255,213,213;--color-danger-950-rgb:255,235,235;--color-important-50:#440609;--color-important-100:#611700;--color-important-200:#c83509;--color-important-300:#ff4912;--color-important-400:#ff6f42;--color-important-500:#ff8058;--color-important-600:#ff8c68;--color-important-700:#ffb29b;--color-important-800:#ffcebf;--color-important-900:#ffe2d9;--color-important-950:#fff8f5;--color-important-50-rgb:68,6,9;--color-important-100-rgb:97,23,0;--color-important-200-rgb:200,53,9;--color-important-300-rgb:255,73,18;--color-important-400-rgb:255,111,66;--color-important-500-rgb:255,128,88;--color-important-600-rgb:255,140,104;--color-important-700-rgb:255,178,155;--color-important-800-rgb:255,206,191;--color-important-900-rgb:255,226,217;--color-important-950-rgb:255,248,245;--color-special-50:#271560;--color-special-100:#30216e;--color-special-200:#452da5;--color-special-300:#513baa;--color-special-400:#7055df;--color-special-500:#8166ee;--color-special-600:#8a6ff5;--color-special-700:#a38cff;--color-special-800:#c4b6ff;--color-special-900:#e4dff7;--color-special-950:#efecfa;--color-special-50-rgb:39,21,96;--color-special-100-rgb:48,33,110;--color-special-200-rgb:69,45,165;--color-special-300-rgb:81,59,170;--color-special-400-rgb:112,85,223;--color-special-500-rgb:129,102,238;--color-special-600-rgb:138,111,245;--color-special-700-rgb:163,140,255;--color-special-800-rgb:196,182,255;--color-special-900-rgb:228,223,247;--color-special-950-rgb:239,236,250;--color-canvas:#0b0f18;--color-inverse:#fff;--color-surface:#353d57;--color-surface-light:#30394a;--color-surface-strong:#3d4667;--color-fore:#ebedf3;--color-focus:#173db6;--color-link:#59a5ff;--color-link-hover:#3883fa;--color-link-visited:#bcdcff;--color-link-active:#bcdcff;--color-placeholder:#4a577f;--color-border:#353d57;--color-border-strong:#3d4667;--color-border-light:#30394a;--color-canvas-rgb:11,15,24;--color-inverse-rgb:255,255,255;--color-surface-rgb:53,61,87;--color-surface-light-rgb:48,57,74;--color-surface-strong-rgb:61,70,103;--color-fore-rgb:235,237,243;--color-focus-rgb:23,61,182;--color-link-rgb:89,165,255;--color-link-hover-rgb:56,131,250;--color-link-visited-rgb:188,220,255;--color-link-active-rgb:188,220,255;--color-placeholder-rgb:74,87,127;--color-border-rgb:53,61,87;--color-border-strong-rgb:61,70,103;--color-border-light-rgb:48,57,74}}*,:after,:before{--tw-border-opacity:1;border-color:rgba(var(--color-border-rgb),var(--tw-border-opacity,1))}:focus-visible{outline-color:transparent}html{font-size:var(--font-size-root)}body{--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1));font-size:.8125rem;line-height:1.5384615385}.dark,body{--tw-text-opacity:1;color:rgba(var(--color-fore-rgb),var(--tw-text-opacity,1))}:root{--font-h1-size:2.25rem;--article-p-space:0.5em;--article-heading-space:0.5em;--article-hr-space:1.5em;--article-cell-padding:0.25rem 0.75rem}a,a.disabled:hover{--tw-text-opacity:1;color:rgba(var(--color-link-rgb),var(--tw-text-opacity,1))}a:hover{--tw-text-opacity:1;color:rgba(var(--color-link-hover-rgb),var(--tw-text-opacity,1))}a:focus-visible{outline-color:rgb(var(--color-focus-rgb));outline-offset:2px;outline-width:2px}.code,code{background-color:rgba(var(--color-important-500-rgb),.1);border-radius:var(--radius);padding-left:.25rem;padding-right:.25rem;--tw-text-opacity:1;color:rgba(var(--color-important-500-rgb),var(--tw-text-opacity,1))}pre{font-size:.75rem;line-height:1rem;overflow:auto;padding:.5rem}pre code{background-color:transparent;color:inherit;padding:0}samp,var{font-weight:700}.blockquote,blockquote{border-left-width:4px;font-size:.875rem;line-height:1.3rem;padding-left:.75rem;text-wrap:pretty}.blockquote figcaption,blockquote figcaption{font-size:.75rem;line-height:1rem;--tw-text-opacity:1;color:rgba(var(--color-gray-500-rgb),var(--tw-text-opacity,1))}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-weight:700;line-height:1.5;text-wrap:balance}.h1,h1{font-size:1.75rem}.h2,h2{font-size:1.5rem}.h3,h3{font-size:1.25rem}.h4,h4{font-size:1rem}.h5,h5{font-size:.875rem}.h6,h6{font-size:.75rem}ul{list-style-type:disc}ol,ul{padding-left:1.5em}ol{list-style-type:decimal}dt{font-weight:700}dd{padding-left:2em}.article{color:var(--font-size-article);hyphens:auto;overflow-wrap:break-word;white-space:pre-wrap}.article h1,.article h2,.article h3,.article h4{margin-bottom:var(--article-heading-space);margin-top:var(--article-heading-space)}.article audio,.article blockquote,.article figure,.article img,.article ol,.article p,.article table,.article ul,.article video{margin-bottom:var(--article-p-space);margin-top:var(--article-p-space);text-wrap:pretty}.article p{min-height:1em}.article p:empty:before{content:" ";display:inline-block}.article hr{margin-bottom:var(--article-hr-space);margin-top:var(--article-hr-space)}.article table{border-width:1px}.article td,.article th{border-bottom-width:1px;padding:var(--article-cell-padding)}.article thead{background-color:var(--table-head-bg,var(--color-gray-100))}.article ol *,.article table *,.article ul *{margin-bottom:0;margin-top:0}.article pre{border-radius:var(--radius);border-width:1px;--tw-bg-opacity:1;background-color:rgba(var(--color-gray-50-rgb),var(--tw-bg-opacity,1))}:root{--alert-bg:var(--color-surface)}.alert{align-items:center;background-color:var(--alert-bg);border-radius:var(--radius);display:flex;gap:.75rem;padding:.5rem .75rem}.alert-content{display:flex;flex:1 1 auto;flex-direction:column;gap:1rem}.alert-close{margin-bottom:-.375rem;margin-right:-.5rem;margin-top:-.375rem}.alert-link{color:inherit;font-weight:700}.alert-link:hover{color:inherit;text-decoration-line:underline}.alert-heading{font-weight:700;margin:0}.alert-text{flex:1 1 auto;white-space:pre-line}.alert-actions{align-items:center;display:flex;gap:.5rem}:root{--breadcrumb-divider:"/";--breadcrumb-divider-color:var(--color-gray-500);--breadcrumb-color-active:var(--color-gray-500)}.breadcrumb{display:flex;gap:1.25rem;list-style-type:none;padding-left:0}.breadcrumb>li{position:relative}.breadcrumb>li+li:before{color:var(--breadcrumb-divider-color);content:var(--breadcrumb-divider);display:block;left:-1.25rem;position:absolute;text-align:center;width:1.25rem}.breadcrumb>.active{color:var(--breadcrumb-color-active)}:root{--btn-radius:var(--radius);--btn-bg:var(--color-surface);--btn-border-color:var(--color-gray-300);--btn-height:2rem}.btn{align-items:center;background-color:var(--btn-bg);border-radius:var(--btn-radius);display:inline-flex;gap:.375rem;height:var(--btn-height);justify-content:center;padding-left:.75rem;padding-right:.75rem;white-space:nowrap;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:var(--btn-border-color)}.btn,.btn-default:hover{color:inherit}.btn-link{--tw-text-opacity:1;color:rgba(var(--color-link-rgb),var(--tw-text-opacity,1));text-decoration-line:underline;text-underline-offset:2px;--tw-ring-color:transparent}.btn-link:visited{color:rgba(var(--color-link-visited-rgb),var(--tw-text-opacity,1))}.btn-link:hover{--tw-text-opacity:1;color:rgba(var(--color-link-hover-rgb),var(--tw-text-opacity,1))}.btn-link{--btn-bg:transparent}.btn.size-xs,.size-xs>.btn{padding-left:.25rem;padding-right:.25rem;--btn-height:1.25rem}.btn.size-sm,.btn.size-xs,.size-sm>.btn,.size-xs>.btn{font-size:.75rem;line-height:1rem}.btn.size-sm,.size-sm>.btn{--btn-height:1.5rem}.btn.size-md,.btn.size-sm,.size-md>.btn,.size-sm>.btn{padding-left:.5rem;padding-right:.5rem}.btn.size-md,.size-md>.btn{--btn-height:1.75rem}.btn.size-lg,.size-lg>.btn{font-size:1rem;line-height:1.5rem;padding-left:1rem;padding-right:1rem;--btn-height:2.5rem}.btn.size-xl,.size-xl>.btn{font-size:1.125rem;line-height:1.75rem;padding-left:1.25rem;padding-right:1.25rem;--btn-height:3rem}.btn.square{aspect-ratio:1/1;gap:.125rem;padding-left:0;padding-right:0}@supports not (aspect-ratio:1/1){.btn.square{width:var(--btn-height)}}.btn.btn-caret{padding-left:.25rem;padding-right:.25rem}.btn.btn-wide{min-width:80px}:root{--checkbox-size:12px;--checkbox-color:var(--color-primary-500)}.checkbox,.radio{align-items:center;cursor:pointer;display:flex;gap:.375rem;min-height:20px}.checkbox>input[type=checkbox],.radio>input[type=radio]{accent-color:rgb(var(--color-primary-500-rgb));border-radius:var(--radius-lg)}.checkbox-primary,.radio-primary{display:flex;gap:.375rem;min-height:20px;position:relative}.checkbox-primary>input[type=checkbox],.radio-primary>input[type=radio]{bottom:0;left:0;opacity:0;position:absolute;right:0;top:0}.checkbox-primary>label,.radio-primary>label{cursor:pointer;padding-left:calc(var(--checkbox-size) + 8px);position:relative}.checkbox-primary>label:after,.checkbox-primary>label:before,.radio-primary>label:after,.radio-primary>label:before{display:block;height:var(--checkbox-size);left:0;position:absolute;transition-duration:.15s;transition-property:transform,background-color,color,opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);width:var(--checkbox-size);--tw-content:"";content:var(--tw-content);top:calc((20px - var(--checkbox-size))/2)}.checkbox-primary>label:before{border-radius:var(--radius-sm);border-width:1px;--tw-border-opacity:1;border-color:rgba(var(--color-gray-400-rgb),var(--tw-border-opacity,1));--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1))}.checkbox-primary>label:after{--tw-scale-x:.9;--tw-scale-y:.9;background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHBhdGggZmlsbD0iI2ZmZiIgZD0ibTkgMjAuNDItNi4yMS02LjIxIDIuODMtMi44M0w5IDE0Ljc3bDkuODgtOS44OSAyLjgzIDIuODN6Ii8+PC9zdmc+");transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.radio-primary>label:before{border-radius:var(--radius-full);border-width:1px;--tw-border-opacity:1;border-color:rgba(var(--color-gray-400-rgb),var(--tw-border-opacity,1))}.radio-primary>label:after{background-color:var(--checkbox-color);border-radius:var(--radius-full);opacity:0;--checkbox-radio-size:calc(var(--checkbox-size)*2/3);height:var(--checkbox-radio-size);left:calc((var(--checkbox-size) - var(--checkbox-radio-size))/2);top:calc((20px - var(--checkbox-radio-size))/2);width:var(--checkbox-radio-size)}.checkbox-primary>label:hover:before,.radio-primary>label:hover:before{border-color:var(--checkbox-color)}.checkbox-primary.focus>label:before,.checkbox-primary>input[type=checkbox]:focus+label:before,.radio-primary.focus>label:before,.radio-primary>input[type=radio]:focus+label:before{border-color:var(--checkbox-color);outline-color:rgb(var(--color-focus-rgb));outline-style:solid;outline-width:2px}.checkbox-primary.checked>label:before,.checkbox-primary>input[type=checkbox]:checked+label:before{background-color:var(--checkbox-color);border-color:var(--checkbox-color)}.radio-primary.checked>label:before,.radio-primary>input[type=radio]:checked+label:before{border-color:var(--checkbox-color)}.checkbox-primary.checked>label:after,.checkbox-primary>input[type=checkbox]:checked+label:after,.radio-primary.checked>label:after,.radio-primary>input[type=radio]:checked+label:after{opacity:1}.checkbox-primary.disabled>label,.checkbox-primary>input[type=checkbox]:disabled+label,.radio-primary.disabled>label,.radio-primary>input[type=radio]:disabled+label{cursor:not-allowed;opacity:.7;pointer-events:none;--tw-grayscale:grayscale(100%);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.checkbox-primary.indeterminate>label:after,.checkbox-primary>input[type=checkbox]:indeterminate+label:after{--tw-border-opacity:1;background-color:var(--checkbox-color);background-image:none;border-color:rgba(var(--color-canvas-rgb),var(--tw-border-opacity,1));border-width:calc((var(--checkbox-size) - 2px)/2) 2px;opacity:1}.check-list{align-items:flex-start;flex-direction:column;gap:.5rem}.check-list,.check-list-inline{display:flex;padding-bottom:.375rem;padding-top:.375rem}.check-list-inline{align-items:center;-moz-column-gap:1rem;column-gap:1rem;flex-direction:row;flex-wrap:wrap;row-gap:.5rem}.switch{display:flex;gap:.375rem;min-height:20px;padding-left:2.5rem;position:relative}.switch>input{bottom:0;left:0;opacity:0;position:absolute;right:0;top:0}.switch>label:after,.switch>label:before{border-radius:var(--radius-full);border-width:1px;height:1rem;left:0;position:absolute;top:.125rem;width:2rem;--tw-border-opacity:1;border-color:rgba(var(--color-border-strong-rgb),var(--tw-border-opacity,1));--tw-bg-opacity:1;background-color:rgba(var(--color-surface-rgb),var(--tw-bg-opacity,1));transition-duration:.3s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);--tw-content:"";content:var(--tw-content)}.switch>label:before{cursor:pointer;--tw-shadow:inset 0 2px 4px 0 rgba(0,0,0,.05);--tw-shadow-colored:inset 0 2px 4px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.switch>label:hover:before{--tw-border-opacity:1;border-color:rgba(var(--color-border-rgb),var(--tw-border-opacity,1))}.switch>label:after{height:.75rem;left:.125rem;top:.25rem;width:.75rem;--tw-border-opacity:1;border-color:rgba(var(--color-canvas-rgb),var(--tw-border-opacity,1));--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1));--tw-shadow:0 3px 8px 0 rgba(0,0,0,.04),0 1px 2px -1px rgba(0,0,0,.01);--tw-shadow-colored:0 3px 8px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.switch>input:checked+label:before{background-color:var(--checkbox-color);border-color:rgba(var(--color-inverse-rgb),.2)}.switch>input:checked+label:after{color:var(--checkbox-color);left:18px}.switch.focus>label:before,.switch>input:focus+label:before{border-color:var(--checkbox-color);outline-color:rgb(var(--color-focus-rgb));outline-style:solid;outline-width:2px}.switch.disabled>label:before,.switch>input:disabled+label:before{cursor:not-allowed;opacity:.7;pointer-events:none;--tw-grayscale:grayscale(100%);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.arrow,.arrow:before{background:inherit;height:calc(var(--arrow-size)*1.4142);position:absolute;width:calc(var(--arrow-size)*1.4142)}.arrow{visibility:hidden;--arrow-size:5px}.arrow:before{border:inherit;content:"";visibility:visible;--tw-rotate:45deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.arrow-top,.arrow-up{border-bottom:inherit;border-right:inherit;border-width:1px 0 0 1px;top:calc(1px - var(--arrow-size))}.white>.arrow-top,.white>.arrow-up{top:calc(0px - var(--arrow-size))}.arrow-bottom,.arrow-down{border-left:inherit;border-top:inherit;border-width:0 1px 1px 0;bottom:calc(1px - var(--arrow-size))}.white>.arrow-bottom,.white>.arrow-down{bottom:calc(0px - var(--arrow-size))}.arrow-left{border-right:inherit;border-top:inherit;border-width:0 0 1px 1px;left:calc(1px - var(--arrow-size))}.white>.arrow-left{left:calc(0px - var(--arrow-size))}.arrow-right{border-bottom:inherit;border-left:inherit;border-width:1px 1px 0 0;right:calc(1px - var(--arrow-size))}.white>.arrow-right{right:calc(0px - var(--arrow-size))}.caret,.caret-down,.caret-left,.caret-right,.caret-up{align-items:center;display:inline-flex;height:.75rem;justify-content:center;position:relative;width:.75rem}.caret-down:before,.caret-left:before,.caret-right:before,.caret-up:before,.caret:before{display:block;height:.35rem;transform-origin:center;width:.35rem;--tw-translate-y:-1px;--tw-rotate:45deg;border-color:currentColor;border-width:0 1px 1px 0;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-content:"";content:var(--tw-content)}.caret-left:before{--tw-translate-x:0.125rem;--tw-translate-y:0px;--tw-rotate:135deg}.caret-left:before,.caret-right:before{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.caret-right:before{--tw-translate-x:-0.125rem;--tw-translate-y:0px;--tw-rotate:-45deg}.caret-up:before{--tw-translate-y:0.125rem;--tw-rotate:225deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}:focus>.caret,:hover>.caret{opacity:inherit}.disabled .caret,.readonly .caret{opacity:var(--caret-opacity,.5)}:root{--toggle-icon-size:calc(var(--font-size-root)*3/4 + 1px)}.toggle-icon,.toggle-icon-collapse,.toggle-icon-expand{border-color:currentColor;border-width:1px;display:block;opacity:.5;position:relative}.toggle-icon-collapse:hover,.toggle-icon-expand:hover,.toggle-icon:hover{opacity:.9}.toggle-icon,.toggle-icon-collapse,.toggle-icon-expand{border-radius:inherit;height:var(--toggle-icon-size);width:var(--toggle-icon-size)}.is-collapsed .toggle-icon:after,.is-collapsed .toggle-icon:before,.is-expanded .toggle-icon:before,.toggle-icon-collapse:after,.toggle-icon-collapse:before,.toggle-icon-expand:before{background-color:currentColor;content:" ";display:block;height:1px;left:2px;position:absolute;right:2px;top:calc((var(--toggle-icon-size) - 3px)/2)}.is-collapsed .toggle-icon:after,.toggle-icon-collapse:after{--tw-rotate:90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.close{aspect-ratio:1/1;display:block;position:relative;width:1em}.close:after,.close:before{content:"";display:block;height:1px;left:0;position:absolute;width:100%;--tw-rotate:45deg;background-color:currentColor;border-radius:var(--radius-full);top:calc(50% - .5px)}.close:after,.close:before{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.close:after{--tw-rotate:-45deg}.spinner,.spinner:after,.spinner:before{display:block;height:1em;position:relative;width:1em}.spinner:after,.spinner:before{border-radius:var(--radius-full);content:" ";position:absolute}.spinner:before{animation:-spin 1s cubic-bezier(.6,0,.4,1) infinite;border:.16667em solid transparent;border-top-color:currentcolor}.spinner:after{border:.16667em solid;opacity:.2}.magnifier{display:inline-block;height:1em;position:relative;width:1em}.magnifier:after,.magnifier:before{border-radius:var(--radius-full);content:"";display:block;position:absolute}.magnifier:before{border:1px solid;height:.75em;width:.75em}.magnifier:after{height:1px;left:.55em;top:.7em;width:.5em;--tw-rotate:45deg;background-color:currentColor;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.more,.more-vert{margin:.5rem;position:relative}.more,.more-vert,.more-vert:after,.more-vert:before,.more:after,.more:before{background-color:currentColor;border-radius:var(--radius-full);height:.125rem;width:.125rem}.more-vert:after,.more-vert:before,.more:after,.more:before{display:block;left:-5px;position:absolute;top:0;--tw-content:"";content:var(--tw-content)}.more-vert:after,.more:after{left:5px}.more-vert{--tw-rotate:90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.chevron-down,.chevron-left,.chevron-right,.chevron-up{align-items:center;display:inline-flex;height:1em;justify-content:center;position:relative;width:1em}.chevron-down:before,.chevron-left:before,.chevron-right:before,.chevron-up:before{display:block;height:.6923077em;transform-origin:center;width:.6923077em;--tw-translate-y:-0.125rem;--tw-rotate:45deg;border-color:currentColor;border-width:0 1px 1px 0;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-content:"";content:var(--tw-content)}.chevron-left:before{--tw-translate-y:0px;--tw-translate-x:0.125rem;--tw-rotate:135deg}.chevron-left:before,.chevron-right:before{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.chevron-right:before{--tw-translate-y:0px;--tw-translate-x:-0.125rem;--tw-rotate:-45deg}.chevron-up:before{--tw-translate-y:0.125rem;--tw-rotate:225deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.i-time{border-color:currentColor;border-radius:50%;border-width:.08em;display:inline-block;height:1em;position:relative;width:1em}.i-time:after{border-color:currentColor;border-width:0 0 .08em .08em;height:.385em;left:.3846em;position:absolute;top:.08em;width:.385em;--tw-content:"";content:var(--tw-content)}.i-calendar{border-color:currentColor;border-radius:2px;border-width:.08em;display:inline-block;height:.79em;margin-top:.16em;position:relative;width:1em}.i-calendar:after,.i-calendar:before{border-color:currentColor;border-width:.08em;position:absolute;--tw-content:"";content:var(--tw-content)}.i-calendar:before{border-bottom-width:0;left:.15em;top:.307em;width:.6em}.i-calendar:after{border-bottom-width:0;border-top-width:0;height:.3077em;left:.17em;top:-.154em;width:.538em}.collapsible{border-radius:var(--radius-md)}.collapsible-header{align-items:center;display:flex;gap:.5rem;padding:.25rem .25rem 0}.collapsible-toggle-btn{margin-right:-.25rem;opacity:.5}.collapsible-toggle-btn:hover{opacity:1}.collapsible-header-title{font-weight:700}.collapsible-header-caption{font-size:.75rem;line-height:1rem;--tw-text-opacity:1;color:rgba(var(--color-gray-500-rgb),var(--tw-text-opacity,1))}.collapsible+.collapsible{margin-top:1rem}.collapsible-body{padding:.5rem .625rem}.collapsible.is-collapsed .collapsible-body{display:none}.collapsible.bordered{border-width:1px}.collapsible .collapsible-header{padding-bottom:.25rem}.collapsible.bordered .collapsible-body{border-top-width:1px}:root{--form-control-radius:var(--radius);--form-control-border:var(--color-border);--form-control-focus:var(--color-primary-500);--form-control-disabled:var(--color-surface);--form-control-readonly:var(--color-surface)}.dark{--form-control-border:var(--color-border-strong)}input::-moz-placeholder,textarea::-moz-placeholder{--tw-placeholder-opacity:1;color:rgba(var(--color-placeholder-rgb),var(--tw-placeholder-opacity,1))}input::placeholder,textarea::placeholder{--tw-placeholder-opacity:1;color:rgba(var(--color-placeholder-rgb),var(--tw-placeholder-opacity,1))}.form-control{border-radius:var(--form-control-radius);display:block;height:2rem;width:100%;--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1));outline-color:transparent;outline-style:solid;outline-width:1px;padding:.25rem .5rem;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:var(--form-control-border);transition-duration:.15s;transition-property:outline,box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1)}.form-control.focus,.form-control:focus{outline-color:var(--form-control-focus);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:rgba(var(--color-focus-rgb),var(--tw-ring-opacity,1));--tw-ring-opacity:0.3}.form-control.disabled,.form-control[disabled]{background-color:var(--form-control-disabled);opacity:1}.form-control.readonly,.form-control[readonly]{background-color:var(--form-control-readonly)}.form-static-text{padding-bottom:.25rem;padding-top:.25rem}select{-webkit-appearance:none;background-image:url("data:image/gif;base64,R0lGODlhBwAEAIAAAMvQ2////yH5BAEAAAEALAAAAAAHAAQAAAIIhA+BGWoNWSgAOw==");background-position:right 8px top 50%;background-repeat:no-repeat;background-size:8px auto;padding-right:1rem}select.form-control[multiple]{background-image:none;height:auto}textarea.form-control{height:auto;min-height:32px}input[type=file].form-control{padding:.125rem}input[type=file].form-control::-webkit-file-upload-button{-webkit-appearance:none;appearance:none;border-radius:inherit;border-style:none;cursor:pointer;height:1.75rem;padding-left:.5rem;padding-right:.5rem}input[type=file].form-control::-webkit-file-upload-button:hover{background-color:rgba(var(--color-black-rgb),.1)}.has-error .form-control,.has-error.form-control{--tw-ring-color:rgba(var(--color-danger-500-rgb),0.6)}.has-error .form-control.focus,.has-error .form-control:focus,.has-error.form-control.focus,.has-error.form-control:focus{outline-color:rgb(var(--color-danger-500-rgb));--tw-ring-color:rgba(var(--color-danger-500-rgb),0.1)}.has-warning .form-control,.has-warning.form-control{--tw-ring-color:rgba(var(--color-warning-500-rgb),0.6)}.has-warning .form-control.focus,.has-warning .form-control:focus,.has-warning.form-control.focus,.has-warning.form-control:focus{outline-color:rgb(var(--color-warning-500-rgb));--tw-ring-color:rgba(var(--color-warning-500-rgb),0.2)}.has-success .form-control,.has-success.form-control{--tw-ring-color:rgba(var(--color-success-500-rgb),0.6)}.has-success .form-control.focus,.has-success .form-control:focus,.has-success.form-control.focus,.has-success.form-control:focus{outline-color:rgb(var(--color-success-500-rgb));--tw-ring-color:rgba(var(--color-success-500-rgb),0.2)}.form-control.size-sm,.size-sm>.form-control{font-size:.75rem;height:1.5rem;line-height:1rem;padding-left:.5rem;padding-right:.5rem}.form-control.size-md,.size-md>.form-control{height:1.75rem;padding-left:.5rem;padding-right:.5rem}.form-control.size-lg,.size-lg>.form-control{font-size:1rem;height:2.5rem;line-height:1.5rem;padding-left:.75rem;padding-right:.75rem}.map-edit{--map-edit-key-width:8rem;--map-edit-value-width:auto}.map-edit-item{align-items:center;display:flex;flex-direction:row;gap:.75rem}.map-edit-item+.map-edit-item{margin-top:.75rem}.map-edit-item-key{flex:none;width:var(--map-edit-key-width)}.map-edit-item-value{flex:auto;width:var(--map-edit-value-width)}.map-edit-item-actions{align-items:center;display:flex;flex-direction:row;gap:.5rem}.string-list-edit{--string-list-edit-item-width:auto}.string-list-edit-item{align-items:center;display:flex;flex-direction:row;gap:.75rem}.string-list-edit-item+.string-list-edit-item{margin-top:.75rem}.string-list-edit-item-value{flex:auto;width:var(--string-list-edit-item-width)}.string-list-edit-item-actions{align-items:center;display:flex;flex-direction:row;gap:.5rem}:root{--input-group-addon-bg:var(--color-gray-50)}.input-group{align-items:stretch;display:flex}.input-group>.form-control,.input-group>.input-control{flex:1 1 auto;z-index:1}.input-group-addon{align-items:center;background-color:var(--input-group-addon-bg);border-radius:var(--form-control-radius);display:flex;flex:none;height:2rem;padding-left:.5rem;padding-right:.5rem;z-index:0;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:var(--form-control-border)}.size-sm>.input-group-addon{font-size:.75rem;height:1.5rem;line-height:1rem;padding-left:.5rem;padding-right:.5rem}.size-lg>.input-group-addon{font-size:1rem;height:2.5rem;line-height:1.5rem;padding-left:.75rem;padding-right:.75rem}.input-group-control{flex:1 1 auto}.input-group>*+*,.input-group>*+* .form-control{border-bottom-left-radius:var(--radius-none);border-top-left-radius:var(--radius-none)}.input-group>:not(:last-child),.input-group>:not(:last-child) .form-control{border-bottom-right-radius:var(--radius-none);border-top-right-radius:var(--radius-none)}.input-group .btn:focus-visible,.input-group .form-control:focus{z-index:2}:root{--form-tip-color:var(--color-gray-400);--form-label-color:var(--color-gray-700);--form-horz-label-width:6rem;--form-grid-gap-x:1.25rem;--form-grid-gap-y:.75rem}.form{flex-direction:column;gap:1rem}.form,.form-label{display:flex}.form-label{align-items:center;color:var(--form-label-color);flex-direction:row;gap:.25rem;height:2rem;overflow:hidden;position:relative;text-overflow:ellipsis;white-space:nowrap}.form-label.required:after{content:"*";display:inline-block;margin-left:.25rem;--tw-translate-y:0.125rem;--tw-scale-x:1.25;--tw-scale-y:1.25;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-text-opacity:1;color:rgba(var(--color-danger-500-rgb),var(--tw-text-opacity,1))}.no-required .form-label.required:after{display:none}.form-label-actions{flex:1 1 auto;justify-content:flex-end}.form-label>.checkbox-primary{margin-left:.75rem}.form-tip{color:var(--form-tip-color);display:block;margin-top:.25rem}.has-error .form-tip{--tw-text-opacity:1;color:rgba(var(--color-danger-500-rgb),var(--tw-text-opacity,1))}.has-warning .form-tip{--tw-text-opacity:1;color:rgba(var(--color-warning-500-rgb),var(--tw-text-opacity,1))}.has-success .form-tip{--tw-text-opacity:1;color:rgba(var(--color-success-500-rgb),var(--tw-text-opacity,1))}.form-actions{display:flex;flex-direction:row;gap:1rem;justify-content:center}.form-grid{--form-grid-gap-x-half:calc(var(--form-grid-gap-x)/2);--form-grid-gap-y-half:calc(var(--form-grid-gap-y)/2);align-items:flex-start;flex-direction:row;flex-wrap:wrap;gap:0}.form-grid .form-group{padding:var(--form-grid-gap-y-half) var(--form-grid-gap-x-half)}.form-grid .form-label.required:after{margin-left:.25rem;order:-9999}.form-grid .form-label .checkbox{margin-left:.75rem;margin-right:.75rem}.form-grid .has-wrap-after:after{display:block;width:100%;--tw-content:"";content:var(--tw-content)}.form-grid-wrap{width:100%}.form-grid-row{display:flex;flex-direction:row;padding-bottom:var(--form-grid-gap-y-half);padding-top:var(--form-grid-gap-y-half);position:relative;width:100%}.form-grid-col{padding-left:var(--form-grid-gap-x-half);padding-right:var(--form-grid-gap-x-half)}.form-grid .form-actions{gap:1.5rem;justify-content:center;padding:var(--form-grid-gap-y) var(--form-grid-gap-x-half);width:100%}.form-grid .form-actions.is-pinned{border-top-width:1px}.form-horz .form-row{align-items:flex-start;display:flex;flex-direction:row}.form-horz .form-group{align-items:flex-start;display:flex;flex:none;flex-direction:row;flex-wrap:wrap;min-height:32px;min-width:0;padding-left:var(--form-horz-label-width);position:relative}.form-horz .form-row .form-group{flex:1 1 auto}.form-horz .form-group[class*=" w-"],.form-horz .form-group[class^=w-]{flex:none}.form-horz .form-group>*{min-width:0}.form-horz .form-group.no-label{padding-left:0}.form-horz .form-group.no-label>.check-list-inline{padding-left:1rem;padding-right:1rem}.form-horz .form-label{justify-content:flex-end;left:0;padding-left:1rem;padding-right:.5rem;position:absolute;top:0;width:var(--form-horz-label-width)}.form-horz .form-label.required:after{margin-left:0;order:-9999}.form-horz .form-tip{width:100%}.form-horz .form-tip,.form-horz .input-control,.form-horz .input-group{flex:1 1 auto}.form .form-group-wrapper,.form-horz .form-group-wrapper{flex:1 1 auto;min-width:0;width:100%;z-index:1}.form .form-group-wrapper.flex-none,.form-horz .form-group-wrapper.flex-none{flex:none}.form fieldset>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.5rem*var(--tw-space-y-reverse));margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)))}.form fieldset{padding-bottom:1rem;padding-left:1rem}.form-grid fieldset>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1rem*var(--tw-space-y-reverse));margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)))}.form legend{border-bottom-width:1px;display:flex;justify-content:flex-start;margin-left:-1rem;width:100%;--tw-border-opacity:1;border-bottom-color:rgba(var(--color-primary-100-rgb),var(--tw-border-opacity,1));width:calc(100% + 1rem)}.form-title{align-items:center;background-color:rgba(var(--color-primary-50-rgb),.5);display:flex;font-weight:700;height:1.75rem;padding-left:.75rem;padding-right:.75rem}:root{--input-control-fix-width-sm:2rem;--input-control-fix-width:4.375rem;--input-control-fix-width-lg:6.75rem}.input-control{position:relative;--input-control-prefix:8px;--input-control-suffix:8px}.input-control-prefix,.input-control-suffix{align-items:center;display:flex;height:100%;left:0;opacity:.5;padding-left:.5rem;padding-right:.5rem;position:absolute;top:0;white-space:nowrap;width:var(--input-control-prefix);z-index:1}.input-control-suffix{justify-content:flex-end;left:auto;right:0;width:var(--input-control-suffix)}.form-control:focus+.input-control-prefix,.form-control:focus+.input-control-suffix{opacity:1}.input-control>.form-control{padding-left:var(--input-control-prefix);padding-right:var(--input-control-suffix)}.input-control>select.form-control{background-position-x:calc(100% - var(--input-control-suffix) - 8px);padding-right:calc(var(--input-control-suffix) + 20px)}.has-prefix{--input-control-prefix:var(--input-control-fix-width)}.has-suffix{--input-control-suffix:var(--input-control-fix-width)}.has-prefix-sm{--input-control-prefix:var(--input-control-fix-width-sm)}.has-suffix-sm{--input-control-suffix:var(--input-control-fix-width-sm)}.has-prefix-lg{--input-control-prefix:var(--input-control-fix-width-lg)}.has-suffix-lg{--input-control-suffix:var(--input-control-fix-width-lg)}.has-prefix-icon{--input-control-prefix:32px}.has-suffix-icon{--input-control-suffix:32px}.input-control.has-prefix-icon{--input-control-prefix:32px}.input-control.has-suffix-icon{--input-control-suffix:32px}.input-control.has-prefix-icon>.input-control-prefix,.input-control.has-suffix-icon>.input-control-suffix{justify-content:center;padding:0}.input-control.size-sm>.form-control,.input-control.size-sm>.input-control-prefix,.input-control.size-sm>.input-control-suffix{font-size:.75rem;line-height:1rem}.input-control.size-lg>.form-control,.input-control.size-lg>.input-control-prefix,.input-control.size-lg>.input-control-suffix{font-size:1rem;line-height:1.5rem}:root{--label-bg:rgba(var(--color-canvas-rgb),.1);--label-border-color:var(--color-gray-300);--label-color:var(--color-gray-500);--label-radius:var(--radius)}.label{align-items:center;background-color:var(--label-bg);border-radius:var(--label-radius);color:var(--label-color);display:inline-flex;font-size:.75rem;height:1.25rem;justify-content:center;line-height:1rem;min-width:1.25rem;padding-left:.25rem;padding-right:.25rem;white-space:pre-line;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:var(--label-border-color)}.label.size-lg{font-size:.8125rem;height:1.5rem;line-height:1.25rem;min-width:1.5rem;padding-left:.5rem;padding-right:.5rem}.label.size-sm{height:1rem;min-width:1rem}.label-dot{aspect-ratio:1/1;border-radius:var(--radius-full);height:.5rem;min-width:0;padding-left:0;padding-right:0}.caret,.caret-down,.caret-left,.caret-right,.caret-up{align-items:center;display:inline-flex;height:.75rem;justify-content:center;position:relative;width:.75rem}.caret-down:before,.caret-left:before,.caret-right:before,.caret-up:before,.caret:before{display:block;height:.35rem;transform-origin:center;width:.35rem;--tw-translate-y:-1px;--tw-rotate:45deg;border-color:currentColor;border-width:0 1px 1px 0;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-content:"";content:var(--tw-content)}.caret-left:before{--tw-translate-x:0.125rem;--tw-translate-y:0px;--tw-rotate:135deg}.caret-left:before,.caret-right:before{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.caret-right:before{--tw-translate-x:-0.125rem;--tw-translate-y:0px;--tw-rotate:-45deg}.caret-up:before{--tw-translate-y:0.125rem;--tw-rotate:225deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}:focus>.caret,:hover>.caret{opacity:inherit}.disabled .caret,.readonly .caret{opacity:var(--caret-opacity,.5)}.listitem{align-items:center;border-radius:var(--radius);display:flex;flex-direction:row;flex-wrap:nowrap;gap:.5rem;padding:.25rem}.listitem.selected{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-50-rgb),var(--tw-bg-opacity,1))}.listitem.active{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-500-rgb),var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgba(var(--color-canvas-rgb),var(--tw-text-opacity,1))}.item-actions,.item-avatar,.item-icon,.item-trailing,.item-trailing-icon{flex:none}.item-icon.icon-EMPTY{display:none}.item-subtitle{font-size:.75rem;line-height:1rem;opacity:.8}.item-content,.item-text{flex:1 1 auto;min-width:0}.item-leading,.item-trailing{align-items:center;display:flex;flex:none;gap:.5rem}.item-checkbox{margin-right:-.5rem}.item-content{align-items:center;display:flex;gap:.5rem}.multiline>.item-content{align-items:flex-start;flex-direction:column;gap:.25rem}.list{list-style-type:none;padding-left:0}.list-heading-inner .item-title{font-weight:700;--tw-text-opacity:1;color:rgba(var(--color-gray-500-rgb),var(--tw-text-opacity,1))}.with-hover-actions>.item{position:relative}.with-hover-actions>.item>.item-inner .item-actions{opacity:0;pointer-events:none;position:absolute;right:.25rem;top:0;transition-duration:.15s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1)}.with-hover-actions>.item>.item-inner:hover .item-actions{display:flex;margin-top:-.25rem;opacity:1;pointer-events:auto;position:static}.list.is-nested-sub{padding-left:var(--list-indent)}.is-nested-collapsed{display:none}.nested-toggle-icon{align-items:center;border-radius:var(--radius);display:flex;height:1rem;justify-content:center;margin-right:-.25rem;width:1rem}.magnifier{display:inline-block;height:1em;position:relative;width:1em}.magnifier:after,.magnifier:before{border-radius:var(--radius-full);content:"";display:block;position:absolute}.magnifier:before{border:1px solid;height:.75em;width:.75em}.magnifier:after{height:1px;left:.55em;top:.7em;width:.5em;--tw-rotate:45deg;background-color:currentColor;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.close{aspect-ratio:1/1;display:block;position:relative;width:1em}.close:after,.close:before{content:"";display:block;height:1px;left:0;position:absolute;width:100%;--tw-rotate:45deg;background-color:currentColor;border-radius:var(--radius-full);top:calc(50% - .5px)}.close:after,.close:before{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.close:after{--tw-rotate:-45deg}.search-box.compact.has-prefix-icon{--input-control-prefix:24px}.search-box.compact.has-suffix-icon{--input-control-suffix:24px}:root{--menu-bg:var(--color-canvas);--menu-active-bg:var(--color-primary-500);--menu-active-color:var(--color-canvas);--menu-selected-bg:var(--color-primary-50);--menu-selected-color:var(--color-primary-500);--menu-icon-opacity:.5;--menu-icon-margin:1.75rem;--menu-min-width:3rem;--menu-heading-color:var(--color-gray-500)}.menu{background:var(--menu-bg);max-width:var(--menu-max-width);min-width:var(--menu-min-width);padding:.5rem}.menu-wrapper{display:flex;flex-direction:column;min-height:0}.menu-wrapper>.menu{flex:1 1 auto;min-height:0;overflow:auto}.menu-item>.item-inner,.menu-item>a{align-items:center;border-radius:var(--radius);color:inherit;cursor:pointer;display:flex;gap:.5rem;justify-content:space-between;overflow:hidden;padding:.25rem .5rem;position:relative;text-overflow:ellipsis;transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);white-space:nowrap}.menu-item>.selected{background:var(--menu-selected-bg);color:var(--menu-selected-color)}.menu-item>.active,.menu-item>a.hover,.menu-item>a:hover{background:var(--menu-active-bg);color:var(--menu-active-color)}.menu-item>a.no-hover.hover,.menu-item>a.no-hover:hover{background:unset;color:unset}.menu-item.disabled>a:hover,.menu-item>a.disabled:hover{background-color:inherit;color:inherit}.menu-item .item-title,.menu-item>a>.text{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:clip;white-space:nowrap}.menu>.divider{margin:.25rem}.menu-heading{align-items:center;color:var(--menu-heading-color);display:flex;font-size:.75rem;font-weight:700;height:2rem;line-height:1rem;padding-left:.25rem;padding-right:.25rem}.has-icons>.menu-item>a>.item-icon{align-items:center;display:flex;height:1rem;justify-content:center;opacity:var(--menu-icon-opacity);width:1rem}.menu-nested{--menu-indent:10px}.menu-nested .menu{background-color:transparent;margin-bottom:-.5rem;margin-left:var(--menu-indent);margin-top:-.5rem;padding-right:0}.menu-nested .menu-item>.item-inner{padding-left:0}.menu-nested .search-menu-footer,.menu-nested .search-menu-header{margin-bottom:.25rem;margin-left:var(--menu-indent);margin-top:-.125rem;padding-right:1px}.menu.compact .menu-item>a{padding-bottom:.125rem;padding-top:.125rem}.menu.compact .menu-heading{height:1.75rem}.search-menu-header{padding:.5rem .5rem .125rem}.search-menu-footer{padding:.125rem .5rem .5rem}.search-menu .item.is-not-match,.search-menu-footer:empty,.search-menu-header:empty{display:none}.search-menu .item.is-not-match.has-match-child{display:list-item}.search-menu .item.is-not-match.has-match-child>.item-inner{opacity:.5;pointer-events:none}.search-menu.no-toggle-on-search .nested-toggle-icon{pointer-events:none}.search-menu .is-match-keys{font-weight:700;text-decoration-line:underline}.search-menu-no-match-hint{display:none;font-size:.75rem;line-height:1rem;padding:.5rem;--tw-text-opacity:1;color:rgba(var(--color-gray-500-rgb),var(--tw-text-opacity,1))}.no-match-child .search-menu-no-match-hint{display:block}.no-match-child>.menu{display:none}.search-menu-exceed-limit-hint{font-size:.75rem;line-height:1rem;padding:.25rem;--tw-text-opacity:1;color:rgba(var(--color-gray-500-rgb),var(--tw-text-opacity,1))}:root{--alert-bg:var(--color-surface)}.alert{align-items:center;background-color:var(--alert-bg);border-radius:var(--radius);display:flex;gap:.75rem;padding:.5rem .75rem}.alert-content{display:flex;flex:1 1 auto;flex-direction:column;gap:1rem}.alert-close{margin-bottom:-.375rem;margin-right:-.5rem;margin-top:-.375rem}.alert-link{color:inherit;font-weight:700}.alert-link:hover{color:inherit;text-decoration-line:underline}.alert-heading{font-weight:700;margin:0}.alert-text{flex:1 1 auto;white-space:pre-line}.alert-actions{align-items:center;display:flex;gap:.5rem}.close{aspect-ratio:1/1;display:block;position:relative;width:1em}.close:after,.close:before{content:"";display:block;height:1px;left:0;position:absolute;width:100%;--tw-rotate:45deg;background-color:currentColor;border-radius:var(--radius-full);top:calc(50% - .5px)}.close:after,.close:before{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.close:after{--tw-rotate:-45deg}.messagers{align-items:flex-end;bottom:0;display:flex;flex-direction:column;gap:.5rem;justify-content:flex-end;left:0;padding:1rem;pointer-events:none;position:fixed;right:0;top:0;z-index:1900}.messagers-top-left,.messagers-top-right{justify-content:flex-start}.messagers-bottom-left,.messagers-top-left{align-items:flex-start}.messagers-bottom,.messagers-center,.messagers-top{align-items:center}.messagers-top,.messagers-top-left,.messagers-top-right{justify-content:flex-start}.messagers-center{justify-content:center}.messager{background-color:rgba(var(--color-inverse-rgb),.8);pointer-events:auto;--tw-text-opacity:1;color:rgba(var(--color-canvas-rgb),var(--tw-text-opacity,1));--tw-shadow:0 10px 25px -5px rgba(0,0,0,.2),0 4px 10px -6px rgba(0,0,0,.15);--tw-shadow-colored:0 10px 25px -5px var(--tw-shadow-color),0 4px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-backdrop-blur:blur(8px);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);transition-duration:.3s}:root{--progress-radius:var(--radius);--progress-striped-size:40px;--progress-bg:var(--color-surface);--progress-bar-color:var(--color-primary-500)}.progress{background:var(--progress-bg);border-radius:var(--progress-radius);display:flex;height:1.25rem}.progress-bar{background:var(--progress-bar-color);height:100%;transition-duration:.5s;transition-property:width;transition-timing-function:cubic-bezier(.4,0,.2,1)}.progress-striped>.progress-bar{background-image:linear-gradient(45deg,rgba(var(--color-canvas-rgb),.15) 25%,transparent 25%,transparent 50%,rgba(var(--color-canvas-rgb),.15) 50%,rgba(var(--color-canvas-rgb),.15) 75%,transparent 75%,transparent);background-size:var(--progress-striped-size) var(--progress-striped-size)}.progress>.progress-bar:first-child{border-bottom-left-radius:inherit;border-top-left-radius:inherit}.progress>.progress-bar:last-child{border-bottom-right-radius:inherit;border-top-right-radius:inherit}.progress.active .progress-bar{animation:progress-bar-stripes 2s linear infinite}@keyframes progress-bar-stripes{0%{background-position:40px 0}to{background-position:0 0}}.scrollbar,:root{--scrollbar-size:10px;--scrollbar-opacity:.6;--scrollbar-bg:rgba(var(--color-inverse-rgb),.15);--scrollbar-inset:inset 0 0 0 1px rgba(var(--color-inverse-rgb),.05);--scrollbar-bar-bg:rgba(var(--color-inverse-rgb),.3);--scrollbar-hover-bg:rgba(var(--color-inverse-rgb),.4);--scrollbar-drag-bg:rgba(var(--color-inverse-rgb),.5);--scrollbar-radius:var(--radius-sm);--scrollbar-duration:.7s}::-webkit-scrollbar{height:var(--scrollbar-size);width:var(--scrollbar-size)}::-webkit-scrollbar-track{background:var(--scrollbar-bg);box-shadow:var(--scrollbar-shadow);-webkit-transition:background-color var(--scrollbar-duration);transition:background-color var(--scrollbar-duration)}::-webkit-scrollbar-track:hover,:hover::-webkit-scrollbar-track{background:var(--scrollbar-hover-bg)}::-webkit-scrollbar-thumb{background:var(--scrollbar-bar-bg);border-radius:var(--scrollbar-radius);min-height:var(--scrollbar-size);-webkit-transition:var(--scrollbar-duration);transition:var(--scrollbar-duration);-webkit-transition-property:background-color;transition-property:background-color}::-webkit-scrollbar-thumb:hover{background:var(--scrollbar-hover-bg)}::-webkit-scrollbar-thumb:active{background:var(--scrollbar-drag-bg)}@-moz-document url-prefix(){.scrollbar-thin{scrollbar-width:thin}}.scrollbar-thin::-webkit-scrollbar{height:calc(var(--scrollbar-size)/2);width:calc(var(--scrollbar-size)/2)}.scrollbar-hover::-webkit-scrollbar,.scrollbar-hover::-webkit-scrollbar-thumb,.scrollbar-hover::-webkit-scrollbar-track{visibility:hidden}.scrollbar-hover:hover::-webkit-scrollbar,.scrollbar-hover:hover::-webkit-scrollbar-thumb,.scrollbar-hover:hover::-webkit-scrollbar-track{visibility:visible}@font-face{font-family:ZentaoIcon;font-style:normal;font-weight:400;src:url(./icons/ZentaoIcon.eot?v=1.74);src:url(./icons/ZentaoIcon.woff?v=1.74) format("woff"),url(./icons/ZentaoIcon.ttf?v=1.74) format("truetype"),url(./icons/ZentaoIcon.svg?v=1.74#regular) format("svg")}.icon,[class*=" icon-"],[class^=icon-]{display:inline-block;font-display:block;font-family:ZentaoIcon;font-size:14px;font-style:normal;font-variant:normal;font-weight:400;line-height:1;text-transform:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.icon:before{display:inline-block;min-width:14px;text-align:center}.icon-xs:before{font-size:.7em}.icon-sm:before{font-size:.8em}.icon-lg:before{font-size:1.25em;vertical-align:-10%}.icon-2x{font-size:28px}.icon-3x{font-size:42px}.icon-4x{font-size:56px}.icon-5x{font-size:70px}.icon-run{position:relative}.icon-run:before{opacity:.5}.icon-run:after{bottom:0;content:"\ea07";display:block;left:0;position:absolute;right:0;text-align:center;top:0}.icon-docspace:before{content:"\ea1b"}.icon-doclib:before{content:"\ea1c"}.icon-guihua:before{content:"\ea02"}.icon-memory:before{content:"\e9fd"}.icon-cpu:before{content:"\e9fe"}.icon-pause-pure:before{content:"\e9ff"}.icon-exclamation-pure:before{content:"\ea00"}.icon-zentao:before{content:"\e901"}.icon-zentao-alt:before{content:"\e900"}.icon-safe:before{content:"\ea06"}.icon-ai:before{content:"\e983"}.icon-kanban:before{content:"\e997"}.icon-college:before{content:"\e9c8"}.icon-home:before,.icon-menu-my:before{content:"\e97a"}.icon-program:before{content:"\e9aa"}.icon-lightbulb-alt:before,.icon-product:before{content:"\e98f"}.icon-project:before,.icon-rocket:before{content:"\e99c"}.icon-run:before{content:"\e9a9"}.icon-run-alt:before{content:"\ea07"}.icon-test:before{content:"\e956"}.icon-devops:before,.icon-infinite:before{content:"\e9a3"}.icon-doc:before,.icon-menu-doc:before{content:"\e99b"}.icon-statistic:before{content:"\e999"}.icon-group:before,.icon-menu-users:before,.icon-persons:before,.icon-team:before{content:"\e97e"}.icon-assets:before,.icon-diamond:before{content:"\e9ae"}.icon-flow:before{content:"\e994"}.icon-backend:before,.icon-cog-outline:before{content:"\ea05"}.icon-help:before{content:"\e968"}.icon-download:before,.icon-import:before{content:"\e904"}.icon-export:before{content:"\e905"}.icon-lightbulb:before{content:"\e91c"}.icon-close:before{content:"\e936"}.icon-check:before{content:"\e5ca"}.icon-minus:before{content:"\e926"}.icon-expand-alt:before{content:"\e6f1"}.icon-collapse-alt:before{content:"\e6f2"}.icon-fullscreen:before{content:"\e96b"}.icon-star-empty:before{content:"\e94a"}.icon-star:before{content:"\e94b"}.icon-exclamation-sign:before{content:"\e930"}.icon-info-sign:before{content:"\e9d5"}.icon-flag:before{content:"\e937"}.icon-check-circle:before{content:"\e92f"}.icon-check-sign:before{content:"\e938"}.icon-chart-pie:before{content:"\e95b"}.icon-history:before{content:"\e95f"}.icon-pencil:before{content:"\e254"}.icon-search:before{content:"\e928"}.icon-restart:before{content:"\e95e"}.icon-cog:before{content:"\e93b"}.icon-chart-line:before{content:"\e95c"}.icon-bar-chart:before,.icon-chart-bar:before{content:"\e95d"}.icon-exchange:before{content:"\e927"}.icon-severity:before{content:"\e973"}.icon-book:before{content:"\f02d"}.icon-treemap-alt:before{content:"\e971"}.icon-severity-solid:before{content:"\e902"}.icon-chat-line:before{content:"\e998"}.icon-stack:before{content:"\e943"}.icon-cube:before{content:"\e967"}.icon-minus-sign:before{content:"\e939"}.icon-bars-sign:before{content:"\e93a"}.icon-chat:before,.icon-message:before{content:"\e940"}.icon-more:before{content:"\e744"}.icon-certificate:before{content:"\f0a3"}.icon-bell:before{content:"\e7f5"}.icon-columns:before{content:"\f0db"}.icon-envelope-o:before{content:"\e92a"}.icon-unfold-all:before{content:"\e931"}.icon-fold-all:before{content:"\e932"}.icon-bars:before{content:"\e948"}.icon-cards-view:before{content:"\e949"}.icon-ellipsis-v:before{content:"\e5d4"}.icon-spinner-indicator:before{content:"\e982"}.icon-up-circle:before{content:"\e92b"}.icon-right-circle:before{content:"\e92c"}.icon-down-circle:before{content:"\e92d"}.icon-left-circle:before{content:"\e92e"}.icon-angle-double-right:before{content:"\f101"}.icon-angle-down:before{content:"\e313"}.icon-angle-left:before{content:"\e314"}.icon-angle-right:before{content:"\e315"}.icon-angle-top:before{content:"\e316"}.icon-first-page:before{content:"\e5dc"}.icon-last-page:before{content:"\e5dd"}.icon-caret-down:before{content:"\f0d7"}.icon-caret-up:before{content:"\f0d8"}.icon-caret-left:before{content:"\f0d9"}.icon-caret-right:before{content:"\f0da"}.icon-sort:before{content:"\f0dc"}.icon-sort-down:before{content:"\f0dd"}.icon-sort-up:before{content:"\f0de"}.icon-arrow-up:before{content:"\e923"}.icon-arrow-down:before{content:"\e924"}.icon-arrow-left:before{content:"\e952"}.icon-arrow-right:before{content:"\e93e"}.icon-chevron-left:before{content:"\e934"}.icon-chevron-right:before{content:"\e935"}.icon-chevron-double-up:before{content:"\e959"}.icon-chevron-double-down:before{content:"\e95a"}.icon-folder-account:before{content:"\e942"}.icon-folder-move:before{content:"\e960"}.icon-folder-plus:before{content:"\e961"}.icon-folder-upload:before{content:"\e962"}.icon-folder-star:before{content:"\e963"}.icon-folder-edit:before{content:"\e964"}.icon-folder-download:before{content:"\e965"}.icon-folder-outline:before{content:"\e966"}.icon-folder:before{content:"\e944"}.icon-folder-o:before{content:"\e945"}.icon-folder-open-o:before{content:"\e946"}.icon-folder-open:before{content:"\e947"}.icon-paper-clip:before{content:"\e93d"}.icon-share:before{content:"\f064"}.icon-format-list-numbers:before{content:"\e969"}.icon-format-quote-close:before{content:"\e96a"}.icon-productplan:before{content:"\e9fc"}.icon-aiux:before{content:"\e99e"}.icon-qc:before{content:"\e986"}.icon-qc-q:before{content:"\e985"}.icon-qc-c:before{content:"\e987"}.icon-sonarqube:before{content:"\e9ba"}.icon-board:before{content:"\ea15"}.icon-market:before{content:"\ea01"}.icon-ztool:before{content:"\e9c1"}.icon-contacts:before{content:"\e9c3"}.icon-chats:before{content:"\e9c4"}.icon-ops:before{content:"\e903"}.icon-menu-backend:before{content:"\e993"}.icon-feedback:before{content:"\e991"}.icon-oa:before{content:"\e9a1"}.icon-more-circle:before{content:"\e988"}.icon-controls:before{content:"\e995"}.icon-account:before{content:"\e992"}.icon-about:before,.icon-info:before{content:"\e996"}.icon-exclamation:before{content:"\e9fa"}.icon-exit:before{content:"\e99a"}.icon-theme:before{content:"\e9a0"}.icon-globe:before,.icon-lang:before{content:"\f0ac"}.icon-template:before{content:"\e9fb"}.icon-seal:before{content:"\e9f8"}.icon-menu-arrow-left:before{content:"\e9f0"}.icon-menu-arrow-right:before{content:"\e9f1"}.icon-add-directory:before{content:"\e9ef"}.icon-design:before{content:"\e9ec"}.icon-download-alt:before{content:"\e9ea"}.icon-blame:before{content:"\e9e0"}.icon-draft-edit:before{content:"\e9dc"}.icon-sub-review-user:before{content:"\e9db"}.icon-sub-review:before{content:"\e9df"}.icon-ztf:before{content:"\e9dd"}.icon-save:before{content:"\e9d8"}.icon-list-box:before{content:"\e9b4"}.icon-usecase:before{content:"\e99d"}.icon-code:before{content:"\e990"}.icon-summary:before{content:"\e9ad"}.icon-more-alt:before{content:"\e9a7"}.icon-customer:before{content:"\e9d9"}.icon-alarm:before{content:"\ea16"}.icon-treeview:before{content:"\ea0d"}.icon-or:before{content:"\ea0b"}.icon-manager:before{content:"\ea0c"}.icon-target:before{content:"\ea0a"}.icon-ipd:before{content:"\e9f9"}.icon-wiki-lib:before{content:"\e9f5"}.icon-annex-lib:before{content:"\e9f6"}.icon-interface-lib:before{content:"\e9f7"}.icon-has-authority-pack:before{content:"\e9f3"}.icon-without-authority-pack:before{content:"\e9f4"}.icon-data-structure:before{content:"\e9f2"}.icon-waterfallplus:before{content:"\e9ed"}.icon-agileplus:before{content:"\e9ee"}.icon-horn:before{content:"\e9eb"}.icon-resume:before{content:"\e9e9"}.icon-mirror:before{content:"\e9e6"}.icon-remote:before{content:"\e9e7"}.icon-moon:before{content:"\e9e8"}.icon-ticket:before{content:"\e9e1"}.icon-gantt-alt:before{content:"\e9e2"}.icon-tree:before{content:"\e9c9"}.icon-list:before{content:"\e9cb"}.icon-gantt:before{content:"\e9cc"}.icon-group-view:before{content:"\e9cd"}.icon-inherit-space:before{content:"\e9c2"}.icon-card-archive:before{content:"\e9b8"}.icon-col-archive:before{content:"\e9b9"}.icon-col-add-right:before{content:"\e9bb"}.icon-col-add-left:before{content:"\e9bc"}.icon-col-split:before{content:"\e9bd"}.icon-waterfall:before{content:"\e9a4"}.icon-manual:before{content:"\e98d"}.icon-lane:before{content:"\e9b1"}.icon-analyze:before{content:"\ea1e"}.icon-var-x:before{content:"\ea1d"}.icon-mobile:before{content:"\ea18"}.icon-clear:before{content:"\ea19"}.icon-db:before{content:"\ea17"}.icon-unpinned:before{content:"\ea08"}.icon-pinned:before{content:"\ea09"}.icon-support-ticket:before{content:"\ea04"}.icon-snap-house:before{content:"\e9e3"}.icon-wrench:before{content:"\e9e4"}.icon-desktop:before{content:"\e9e5"}.icon-back-circle:before{content:"\e9da"}.icon-back:before{content:"\e9d3"}.icon-shield:before{content:"\e9ca"}.icon-meh:before{content:"\e9ce"}.icon-frown:before{content:"\e9cf"}.icon-smile:before{content:"\e9d0"}.icon-unlock-solid:before{content:"\e9d1"}.icon-lock-solid:before{content:"\e9d2"}.icon-ver:before{content:"\e9c6"}.icon-publish:before,.icon-send:before{content:"\e9c7"}.icon-tag:before{content:"\e9be"}.icon-tag-lock:before{content:"\e9bf"}.icon-code-fork:before{content:"\f126"}.icon-branch-lock:before{content:"\e9c0"}.icon-groups:before{content:"\e9af"}.icon-thumbs-up:before{content:"\f087"}.icon-thumbs-down:before{content:"\f088"}.icon-thumbs-up-solid:before{content:"\e9d6"}.icon-thumbs-down-solid:before{content:"\e9d7"}.icon-hash:before,.icon-version:before{content:"\e9ab"}.icon-p-square:before{content:"\e97b"}.icon-video-play:before{content:"\e97f"}.icon-plus-solid-circle:before{content:"\e974"}.icon-minuse-solid-circle:before{content:"\e9b6"}.icon-s:before{content:"\e975"}.icon-c:before{content:"\e976"}.icon-t:before{content:"\e977"}.icon-guide:before{content:"\e978"}.icon-todo:before{content:"\e979"}.icon-plus:before{content:"\e925"}.icon-side-left:before{content:"\e9b3"}.icon-side-right:before{content:"\e9b2"}.icon-fullscreen-exit:before{content:"\e972"}.icon-alert:before{content:"\e99f"}.icon-undo:before{content:"\e93f"}.icon-redo:before{content:"\e9d4"}.icon-swap:before{content:"\e9b0"}.icon-chat-solid:before{content:"\e9b5"}.icon-clock:before{content:"\e97c"}.icon-cost:before{content:"\e97d"}.icon-pencil-alt:before{content:"\e984"}.icon-size-height:before{content:"\e9c5"}.icon-list-collapse:before{content:"\ea52"}.icon-list-expand:before{content:"\ea53"}.icon-upload-file:before{content:"\ea03"}.icon-file-log:before{content:"\e9de"}.icon-rich-text:before{content:"\e913"}.icon-markdown:before{content:"\e916"}.icon-excel:before{content:"\e933"}.icon-text-link:before{content:"\e94d"}.icon-text-unlink:before{content:"\ea51"}.icon-ppt:before{content:"\e957"}.icon-word:before{content:"\e958"}.icon-doc-lib:before{content:"\e96f"}.icon-file-empty:before,.icon-file:before{content:"\f016"}.icon-file-text:before{content:"\f0f6"}.icon-file-alt:before{content:"\f15b"}.icon-file-text-alt:before{content:"\f15c"}.icon-file-pdf:before{content:"\f1c1"}.icon-file-word:before{content:"\f1c2"}.icon-file-excel:before{content:"\f1c3"}.icon-file-powerpoint:before{content:"\f1c4"}.icon-file-image:before{content:"\f1c5"}.icon-file-archive:before{content:"\f1c6"}.icon-file-audio:before{content:"\f1c7"}.icon-file-video:before{content:"\f1c8"}.icon-file-code:before{content:"\f1c9"}.icon-columns-2:before{content:"\ea54"}.icon-columns-3:before{content:"\ea55"}.icon-columns-4:before{content:"\ea56"}.icon-panel-right:before{content:"\ea57"}.icon-panel-left:before{content:"\ea58"}.icon-paragraph:before{content:"\ea50"}.icon-highlighter:before{content:"\ea4e"}.icon-eraser:before{content:"\ea4f"}.icon-paint-roller:before{content:"\ea4b"}.icon-brush-cleaning:before{content:"\ea4c"}.icon-add-divider:before{content:"\ea4d"}.icon-delete-row:before{content:"\ea42"}.icon-delete-column:before{content:"\ea43"}.icon-add-row:before{content:"\ea44"}.icon-add-column:before{content:"\ea45"}.icon-table-remove:before{content:"\ea46"}.icon-table-cells-split:before{content:"\ea47"}.icon-table-cells-merge:before{content:"\ea48"}.icon-sigma:before{content:"\ea49"}.icon-sigma-box:before{content:"\ea4a"}.icon-grid-2x2-remove:before{content:"\ea2f"}.icon-grid-2x2:before{content:"\ea30"}.icon-kanban-box:before{content:"\ea31"}.icon-align-center:before{content:"\ea32"}.icon-align-bottom:before{content:"\ea33"}.icon-align-top:before{content:"\ea34"}.icon-text-left:before{content:"\ea35"}.icon-text-center:before{content:"\ea36"}.icon-text-right:before{content:"\ea37"}.icon-text-justify:before{content:"\ea38"}.icon-code-block:before{content:"\ea39"}.icon-at:before{content:"\ea3a"}.icon-textbox:before{content:"\ea3b"}.icon-panel:before{content:"\ea3c"}.icon-task-box:before{content:"\ea3d"}.icon-check-list:before{content:"\ea3e"}.icon-text-sup:before{content:"\ea3f"}.icon-text-sub:before{content:"\ea40"}.icon-text-cols:before{content:"\ea41"}.icon-font-style:before{content:"\ea1f"}.icon-font-size:before{content:"\ea20"}.icon-quote:before{content:"\ea21"}.icon-background-color:before{content:"\ea22"}.icon-text-color:before{content:"\ea23"}.icon-formula:before{content:"\ea24"}.icon-format-heading-1:before{content:"\ea25"}.icon-format-heading-2:before{content:"\ea26"}.icon-format-heading-3:before{content:"\ea27"}.icon-format-heading-4:before{content:"\ea28"}.icon-format-heading-5:before{content:"\ea29"}.icon-format-heading-6:before{content:"\ea2a"}.icon-format-bold:before{content:"\e953"}.icon-format-italic:before{content:"\e955"}.icon-format-underline:before{content:"\ea2b"}.icon-format-strike:before{content:"\ea2c"}.icon-multi-input:before{content:"\ea1a"}.icon-cell-input:before{content:"\ea0e"}.icon-input:before{content:"\ea0f"}.icon-checkbox:before{content:"\ea10"}.icon-radio:before{content:"\ea11"}.icon-transition:before{content:"\ea12"}.icon-add-sub-chapter:before{content:"\ea13"}.icon-add-chapter:before{content:"\ea14"}.icon-color:before{content:"\e93c"}.icon-text:before{content:"\e929"}.icon-menu-collapse:before{content:"\e980"}.icon-menu-expand:before{content:"\e981"}.icon-format-list-bulleted:before{content:"\e9a8"}.icon-image:before{content:"\e96c"}.icon-table:before{content:"\e96d"}.icon-table-alt:before{content:"\ea2d"}.icon-data-table:before{content:"\ea2e"}.icon-estimate:before{content:"\e9ac"}.icon-sprint:before{content:"\e9a2"}.icon-shield-check:before{content:"\e9a5"}.icon-ok:before{content:"\e9a6"}.icon-printer:before{content:"\e906"}.icon-bullhorn:before{content:"\e910"}.icon-person:before{content:"\e941"}.icon-fields:before{content:"\e989"}.icon-trigger:before{content:"\e98a"}.icon-layout:before{content:"\e98b"}.icon-audit:before{content:"\e98c"}.icon-ban-circle:before,.icon-cancel:before{content:"\e951"}.icon-eye:before{content:"\e94e"}.icon-eye-off:before{content:"\e96e"}.icon-unlock:before{content:"\e94f"}.icon-lock:before,.icon-private:before{content:"\e950"}.icon-move:before{content:"\e94c"}.icon-hand-right:before{content:"\e907"}.icon-checked:before{content:"\e908"}.icon-off:before{content:"\e909"}.icon-play:before,.icon-start:before{content:"\e90a"}.icon-time:before{content:"\e90b"}.icon-edit:before{content:"\e90c"}.icon-trash:before{content:"\e90d"}.icon-link:before{content:"\e90e"}.icon-unlink:before{content:"\e90f"}.icon-bug:before{content:"\e911"}.icon-list-alt:before{content:"\e912"}.icon-alter:before,.icon-change:before{content:"\e970"}.icon-glasses:before,.icon-review:before{content:"\e914"}.icon-sitemap:before,.icon-testcase:before{content:"\e915"}.icon-pluses:before{content:"\e917"}.icon-report-list:before{content:"\e918"}.icon-active:before,.icon-magic:before{content:"\e919"}.icon-treemap:before{content:"\e91a"}.icon-confirm:before{content:"\e91b"}.icon-split:before{content:"\e98e"}.icon-calendar:before,.icon-delay:before{content:"\e91d"}.icon-pause:before{content:"\e91e"}.icon-ban:before{content:"\e91f"}.icon-plus-bold:before{content:"\e920"}.icon-copy:before{content:"\e921"}.icon-refresh:before{content:"\e922"}.icon-diff:before{content:"\e9b7"}.icon-format-header-pound:before{content:"\e954"}.status-active,.status-asked,.status-normal,.status-unconfirmed,.status-wait{color:var(--color-status-normal,#313c52)}.status-active.status-issue,.status-checking,.status-commenting,.status-confirmed,.status-doing{color:#ff6f42}.status-blocked,.status-hangup,.status-pause,.status-suspended{color:#b89664}.status-clarify,.status-draft{color:#8166ee}.status-noreview,.status-reviewing,.status-wait.status-testcase{color:#18a6fd}.status-active.status-risk,.status-changed,.status-changing,.status-fail{color:#fb2b2b}.status-checked,.status-done,.status-pass,.status-replied,.status-resolved,.status-success{color:#0dbb7d}.status-cancel,.status-canceled,.status-investigate{color:var(--color-status-cancel,#838a9d)}.status-closed,.status-testtask.status-done{color:var(--color-status-closed,#9ea3b0)}.dark{--color-status-normal:#eff1f3;--color-status-cancel:#9ea3b0;--color-status-closed:#838a9d}@media (prefers-color-scheme:dark){.dark-auto{--color-status-normal:#eff1f3;--color-status-cancel:#9ea3b0;--color-status-closed:#838a9d}}.pri,[class*=" pri-"],[class^=pri-]{border-color:currentColor;border-radius:var(--radius-full);border-width:1px;display:inline-block;font-size:.75rem;height:1rem;line-height:1rem;line-height:14px;max-width:54px;min-width:16px;overflow:hidden;padding-left:.125rem;padding-right:.125rem;text-align:center;white-space:nowrap;--tw-text-opacity:1;color:rgba(var(--color-gray-400-rgb),var(--tw-text-opacity,1))}.pri-1{color:rgb(255 73 18/var(--tw-text-opacity,1))}.pri-1,.pri-2{--tw-text-opacity:1}.pri-2{color:rgba(var(--color-warning-600-rgb),var(--tw-text-opacity,1))}.pri-3{color:rgb(59 130 246/var(--tw-text-opacity,1))}.pri-3,.pri-4{--tw-text-opacity:1}.pri-4{color:rgb(149 211 224/var(--tw-text-opacity,1))}.severity{display:inline-block;font-size:.75rem;height:1rem;line-height:1rem;line-height:14px;max-width:54px;min-width:16px;overflow:hidden;padding-left:.125rem;padding-right:.125rem;position:relative;text-align:center;white-space:nowrap;--tw-text-opacity:1;color:rgba(var(--color-gray-400-rgb),var(--tw-text-opacity,1))}.severity:before{background-color:currentColor;background-repeat:no-repeat;height:100%;left:0;position:absolute;top:0;width:100%;z-index:0;--tw-content:attr(data-severity);content:var(--tw-content);-webkit-mask:url('data:image/svg+xml;charset=utf-8,');mask:url('data:image/svg+xml;charset=utf-8,');-webkit-mask-size:100% 100%;mask-size:100% 100%}.severity:after,.severity:before{display:inline-block}.severity:after{--tw-scale-x:.75;--tw-scale-y:.75;content:attr(data-severity);line-height:20px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.severity[data-severity="1"]{--tw-text-opacity:1;color:rgb(185 28 28/var(--tw-text-opacity,1))}.severity[data-severity="2"]{--tw-text-opacity:1;color:rgb(249 115 22/var(--tw-text-opacity,1))}.severity[data-severity="3"]{--tw-text-opacity:1;color:rgb(250 174 26/var(--tw-text-opacity,1))}.severity[data-severity="4"]{--tw-text-opacity:1;color:rgb(184 150 100/var(--tw-text-opacity,1))}.severity[data-severity="5"]{--tw-text-opacity:1;color:rgb(158 163 176/var(--tw-text-opacity,1))}.severity-label{background-color:transparent}.severity-label:after,.severity-label:before{--tw-content:none;content:var(--tw-content)}.risk-high{color:rgb(220 38 38/var(--tw-text-opacity,1))}.risk-high,.risk-middle{--tw-text-opacity:1}.risk-middle{color:rgb(234 179 8/var(--tw-text-opacity,1))}.label.label-id{border-radius:var(--radius-full);flex:none;--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-gray-300-rgb),var(--tw-ring-opacity,1));--label-bg:rgba(var(--color-canvas-rgb),.1)}.nav-feature{--nav-active-bg:var(--color-primary-100);--nav-active-color:var(--color-fore)}.nav-feature .nav-checkbox>.checkbox,.nav-feature .nav-checkbox>.checkbox-primary,.nav-feature .nav-item>a{align-items:center;border-radius:var(--radius);height:2rem;padding-left:.625rem;padding-right:.625rem}.nav-feature .nav-item>a>.icon{--tw-text-opacity:1;color:rgba(var(--color-primary-500-rgb),var(--tw-text-opacity,1))}.sortable-list .listitem{cursor:move;--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1));padding-left:.5rem;padding-right:.5rem}.sortable-list .sortable-ghost>.listitem{--tw-bg-opacity:1;background-color:rgba(var(--color-warning-50-rgb),var(--tw-bg-opacity,1))}.sortable-empty-shadow{height:1px!important;left:0!important;opacity:0!important;pointer-events:none!important;position:absolute!important;top:0!important;width:1px!important}.chevron-down,.chevron-left,.chevron-right,.chevron-up{align-items:center;display:inline-flex;height:1em;justify-content:center;position:relative;width:1em}.chevron-down:before,.chevron-left:before,.chevron-right:before,.chevron-up:before{display:block;height:.6923077em;transform-origin:center;width:.6923077em;--tw-translate-y:-0.125rem;--tw-rotate:45deg;border-color:currentColor;border-width:0 1px 1px 0;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-content:"";content:var(--tw-content)}.chevron-left:before{--tw-translate-y:0px;--tw-translate-x:0.125rem;--tw-rotate:135deg}.chevron-left:before,.chevron-right:before{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.chevron-right:before{--tw-translate-y:0px;--tw-translate-x:-0.125rem;--tw-rotate:-45deg}.chevron-up:before{--tw-translate-y:0.125rem;--tw-rotate:225deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.split{display:flex;flex-direction:row}.split-vert{flex-direction:column}.split-cell{min-height:0;min-width:0}.has-animation>.split-cell{transition-duration:.15s;transition-property:width,height;transition-timing-function:cubic-bezier(.4,0,.2,1)}.gutter{align-items:stretch;border-radius:var(--radius);cursor:col-resize;display:flex;flex:none;flex-direction:row;justify-content:center;position:relative}.gutter-vert{cursor:row-resize;flex-direction:column}.gutter:before{display:block;--tw-bg-opacity:1;background-color:rgba(var(--color-border-rgb),var(--tw-bg-opacity,1));transition-duration:.15s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);--tw-content:"";content:var(--tw-content)}.gutter-horz:before{width:1px}.gutter-vert:before{height:1px}.gutter-horz:hover:before{width:75%}.gutter-vert:hover:before{height:75%}.gutter-resize-handler,.gutter-toggle{align-items:center;border-radius:var(--radius-lg);border-width:1px;display:flex;height:1.75rem;justify-content:center;margin-top:-.875rem;position:absolute;top:50%;width:.75rem;--tw-border-opacity:1;border-color:rgba(var(--color-border-rgb),var(--tw-border-opacity,1));--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgba(var(--color-fore-rgb),var(--tw-text-opacity,1));transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1)}.gutter-toggle>span{--tw-scale-x:.75;--tw-scale-y:.75;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));transition-duration:.15s;transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1)}.gutter:hover .gutter-toggle{--tw-border-opacity:1;border-color:rgba(var(--color-gray-500-rgb),var(--tw-border-opacity,1));--tw-bg-opacity:1;background-color:rgba(var(--color-gray-100-rgb),var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgba(var(--color-gray-500-rgb),var(--tw-text-opacity,1))}.gutter .gutter-toggle:hover{--tw-border-opacity:1;border-color:rgba(var(--color-primary-500-rgb),var(--tw-border-opacity,1));--tw-bg-opacity:1;background-color:rgba(var(--color-primary-500-rgb),var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgba(var(--color-canvas-rgb),var(--tw-text-opacity,1))}.is-last>.gutter-toggle{--tw-scale-x:-1}.is-first>.gutter-toggle,.is-last>.gutter-toggle{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.is-first>.gutter-toggle{--tw-scale-x:1}.gutter-vert .gutter-toggle{left:50%;margin-left:-.375rem;margin-top:0;top:auto;--tw-rotate:90deg}.gutter-vert .gutter-toggle,.gutter.is-next-collapsed>.gutter-toggle{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.gutter.is-next-collapsed>.gutter-toggle{--tw-scale-x:1}.gutter.is-prev-collapsed>.gutter-toggle{--tw-scale-x:-1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.gutter-horz.is-first.is-prev-collapsed{transform:translateX(calc(-1px - var(--split-gutter-size)/2))}.gutter-horz.is-last.is-next-collapsed{transform:translateX(calc(1px + var(--split-gutter-size)/2))}.gutter-vert.is-first.is-prev-collapsed{transform:translateY(calc(-1px - var(--split-gutter-size)/2))}.gutter-vert.is-last.is-next-collapsed{transform:translateY(calc(1px + var(--split-gutter-size)/2))}.gutter-resize-handler{background-color:transparent;border-width:0}.gutter-resize-handler:before{border-left-width:1px;border-right-width:1px;bottom:0;left:.25rem;position:absolute;right:.25rem;top:0;--tw-content:"";content:var(--tw-content)}:root{--avatar-radius:12.5%;--avatar-bg:var(--color-surface)}.avatar{align-items:center;aspect-ratio:1/1;background:var(--avatar-bg);border-radius:var(--avatar-radius);display:inline-flex;justify-content:center;overflow:hidden;width:2rem}.avatar>img{height:100%;margin:0;-o-object-fit:cover;object-fit:cover;width:100%}.avatar.size-xs{width:1.25rem}.avatar.size-sm,.avatar.size-xs{font-size:.75rem;line-height:1rem}.avatar.size-sm{width:1.5rem}.avatar.size-lg{font-size:1.5rem;line-height:2rem;width:3rem}.avatar.size-xl{font-size:2.25rem;line-height:2.5rem;width:5rem}.avatar-group{display:flex;gap:.625rem}.avatar-group>.avatar{box-shadow:0 0 0 1px var(--color-canvas)}.avatar-group>*+*{margin-left:-1rem}.avatar-group.size-xs>*+*{margin-left:-.75rem}.avatar-group.size-sm>*+*{margin-left:-.875rem}.avatar-group.size-lg>*+*{margin-left:-1.25rem}.avatar-group.size-xl>*+*{margin-left:-1.5rem}.btn-group{display:flex;gap:1px}.btn-group>.btn.active{z-index:1}.btn-group>.btn:focus-within,.btn-group>.btn:hover{z-index:2}.btn-group>.btn.disabled,.btn-group>.btn:disabled{z-index:0}.btn-group>.btn:not(:first-child){border-bottom-left-radius:var(--radius-none);border-left-color:rgba(var(--color-canvas-rgb),.2);border-left-width:1px;border-top-left-radius:var(--radius-none)}.btn-group>.btn:not(:first-child):before{left:-1px}.btn-group>.btn:not(:last-child){border-bottom-right-radius:var(--radius-none);border-top-right-radius:var(--radius-none)}.color-picker-heading{align-items:center;font-weight:700;justify-content:space-between;margin-bottom:-.25rem;padding:.5rem}.color-picker-heading,.color-picker-row{display:flex;flex-direction:row}.color-picker-row{flex-wrap:wrap;gap:.5rem;padding:.75rem}.color-picker-item{align-items:center;border-radius:var(--radius-full);display:flex;height:1.25rem;justify-content:center;padding-left:.125rem;padding-right:.125rem;width:1.25rem;--tw-text-opacity:1;color:rgba(var(--color-canvas-rgb),var(--tw-text-opacity,1));--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.pick-container{left:0;pointer-events:none;position:absolute;top:0;z-index:1600}.pick-pop{display:flex;flex-direction:column;opacity:0;pointer-events:auto;position:absolute;transition-duration:.15s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);z-index:1200}.pick-pop.in{opacity:1}.date-picker-menu{--menu-bg:none}.date-picker-menu .mini-calendar{margin-top:-.75rem}.date-pick-menu-month,.date-pick-menu-years{display:flex;flex-direction:row;flex-wrap:wrap;gap:1px;max-height:237px;padding-bottom:.5rem;padding-left:.5rem;padding-right:.5rem}.date-pick-menu-years>.btn{width:2.5rem}.date-pick-menu-years>.btn.is-current{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-100-rgb),var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgba(var(--color-primary-500-rgb),var(--tw-text-opacity,1))}.date-pick-menu-month>.btn.active,.date-pick-menu-years>.btn.active{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-500-rgb),var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgba(var(--color-canvas-rgb),var(--tw-text-opacity,1))}.date-pick-menu-month>.btn{width:3rem}.date-picker-menu-footer{border-top-width:1px;display:flex;flex-direction:row;padding:.25rem}.date-picker-menu-footer>.toolbar{flex:1 1 auto;justify-content:center}.date-picker-menu>.menu{border-right-width:1px}.date-picker-menu .menu-item{--tw-text-opacity:1;color:rgba(var(--color-primary-500-rgb),var(--tw-text-opacity,1))}.time-picker-menu{max-height:inherit}.time-picker-menu .menu-item>a{justify-content:center;padding-left:0;padding-right:0;text-align:center}.datetime-picker-menu{max-height:inherit}.mini-calendar{padding:.5rem}.mini-calendar>.row>.col{align-items:center;justify-content:center;width:14.2857%}.mini-calendar-day{height:2rem}.mini-calendar-day.disabled{pointer-events:none;--tw-bg-opacity:1;background-color:rgba(var(--color-gray-200-rgb),var(--tw-bg-opacity,1));opacity:.5}.mini-calendar-day>.btn{width:2rem}.mini-calendar-day.is-weekend>.btn{--tw-text-opacity:1;color:rgba(var(--color-gray-500-rgb),var(--tw-text-opacity,1))}.mini-calendar-day.active>.btn,.mini-calendar-day.is-today>.btn{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-100-rgb),var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgba(var(--color-primary-500-rgb),var(--tw-text-opacity,1))}.mini-calendar-day.selected>.btn{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-500-rgb),var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgba(var(--color-canvas-rgb),var(--tw-text-opacity,1))}.mini-calendar-day.is-out-month{opacity:.5}.i-time{border-color:currentColor;border-radius:50%;border-width:.08em;display:inline-block;height:1em;position:relative;width:1em}.i-time:after{border-color:currentColor;border-width:0 0 .08em .08em;height:.385em;left:.3846em;position:absolute;top:.08em;width:.385em;--tw-content:"";content:var(--tw-content)}.i-calendar{border-radius:2px;display:inline-block;height:.79em;margin-top:.16em;position:relative;width:1em}.i-calendar,.i-calendar:after,.i-calendar:before{border-color:currentColor;border-width:.08em}.i-calendar:after,.i-calendar:before{position:absolute;--tw-content:"";content:var(--tw-content)}.i-calendar:before{border-bottom-width:0;left:.15em;top:.307em;width:.6em}.i-calendar:after{border-bottom-width:0;border-top-width:0;height:.3077em;left:.17em;top:-.154em;width:.538em}:root{--modal-radius:var(--radius-lg);--modal-bg:rgba(var(--color-inverse-rgb),.4);--modal-sm:37.5rem;--modal-base:50rem;--modal-lg:75rem;--modal-xl:90rem}.modal{align-items:center;background-color:var(--modal-bg);bottom:0;display:none;justify-content:center;left:0;overflow:hidden;position:fixed;right:0;top:0;z-index:1500}.modal.load-indicator:before{background-color:transparent;transition-property:none}.modal.loading:after{--tw-text-opacity:1;color:rgba(var(--color-canvas-rgb),var(--tw-text-opacity,1))}.modal.loading .modal-dialog{opacity:0!important}.modal.show{display:flex}.modal-no-backdrop{background-color:transparent;pointer-events:none}.modal-hide{opacity:0!important}.modal-dialog{background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1));pointer-events:auto;position:relative;--tw-bg-opacity:0.9;--tw-shadow:0 10px 50px -10px rgba(0,0,0,.4),0 8px 20px -10px rgba(0,0,0,.3);--tw-shadow-colored:0 10px 50px -10px var(--tw-shadow-color),0 8px 20px -10px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:rgba(var(--color-inverse-rgb),var(--tw-ring-opacity,1));--tw-ring-opacity:0.05;--tw-backdrop-blur:blur(8px);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);border-radius:var(--modal-radius);width:var(--modal-base)}.modal-content,.modal-dialog{max-height:100vh}.modal-content{display:flex;flex-direction:column;height:100%}.loading>.modal-dialog>.modal-content{opacity:0;visibility:hidden}.modal-dialog.loading{background-color:transparent}.modal-dialog.loading>.modal-content{display:none}.close{aspect-ratio:1/1;display:block;position:relative;width:1em}.close:after,.close:before{content:"";display:block;height:1px;left:0;position:absolute;width:100%;--tw-rotate:45deg;background-color:currentColor;border-radius:var(--radius-full);top:calc(50% - .5px)}.close:after,.close:before{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.close:after{--tw-rotate:-45deg}.modal-header{align-items:center;display:flex;flex:none;flex-wrap:nowrap;gap:1rem;padding:1rem 1.25rem;position:relative}.modal-title{flex:1 1 auto;font-size:1rem;font-weight:700;line-height:1.5rem}.modal-actions{position:absolute;right:.75rem;top:.75rem;z-index:15}.modal-body{flex:1 1 auto;overflow:auto;padding:1rem 1.25rem}.modal-footer{align-items:center;display:flex;flex:none;gap:.75rem;padding:1.25rem}.modal-dialog.size-full,.modal-dialog[data-size=full]{border-radius:var(--radius-none);height:100vh;width:100vw}.modal-dialog.size-sm,.modal-dialog[data-size=sm]{width:var(--modal-sm)}.modal-dialog.size-lg,.modal-dialog[data-size=lg]{width:var(--modal-lg)}.modal-dialog.size-xl,.modal-dialog[data-size=xl]{width:var(--modal-xl)}.modal-iframe{flex:1 1 auto;width:100%}.modal-trans{opacity:0;transition-duration:.2s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1)}.modal-trans.in{opacity:1}.modal-trans>.modal-dialog{transition-property:transform,opacity;--tw-scale-x:.95;--tw-scale-y:.95;opacity:0;transition-duration:.3s}.modal-trans.in>.modal-dialog,.modal-trans>.modal-dialog{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.modal-trans.in>.modal-dialog{--tw-scale-x:1;--tw-scale-y:1;opacity:1}.modal-alert .modal-footer{justify-content:flex-end}.modal-alert .modal-header{margin-bottom:-1rem}.modal-alert .modal-body{overflow-wrap:break-word;white-space:pre-line}.modal-alert .modal-actions+.modal-body{padding-right:3rem}.modal-alert .modal-header+.modal-actions+.modal-body{padding-right:1.25rem}.file-selector{gap:.5rem;width:100%}.file-selector,.file-selector-box{display:flex;flex-direction:column}.file-selector-box{border-style:dashed;border-width:1px;gap:0;height:auto;justify-content:center;position:relative;--tw-border-opacity:1;background-color:rgba(var(--color-primary-50-rgb),.3);border-color:rgba(var(--color-primary-400-rgb),var(--tw-border-opacity,1));padding:.5rem .75rem;--tw-ring-color:transparent;--state-color:rgba(var(--color-primary-500-rgb),.05)}.file-selector-box .text{--tw-text-opacity:1;color:rgba(var(--color-primary-500-rgb),var(--tw-text-opacity,1))}.is-dragging .file-selector-box{border-style:solid}.file-selector-btn{align-items:center;display:flex;gap:.5rem;position:relative}.is-dragging .file-selector-btn{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-50-rgb),var(--tw-bg-opacity,1))}.file-selector-input{-webkit-appearance:none;-moz-appearance:none;appearance:none;bottom:0;cursor:pointer;left:0;opacity:.1;position:absolute;right:0;top:0}.file-selector-tip{--tw-text-opacity:1;color:rgba(var(--color-gray-400-rgb),var(--tw-text-opacity,1))}.file-selector.is-mode-button{flex-direction:column-reverse}.file-selector-list.is-empty{display:none}.file-selector-item .item-avatar{--tw-bg-opacity:1;background-color:rgba(var(--color-gray-50-rgb),var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgba(var(--color-gray-500-rgb),var(--tw-text-opacity,1))}.file-selector-item .item-subtitle{--tw-text-opacity:1;color:rgba(var(--color-gray-400-rgb),var(--tw-text-opacity,1))}.file-selector-item .item-content{flex:none;margin-right:.25rem;max-width:100%}.file-selector-item>.listitem:hover{background-color:rgba(var(--color-gray-500-rgb),.05)}.file-selector-item.is-renaming .item-avatar+.item-content{max-width:calc(100% - 32px)}.file-selector-rename-text{max-width:100%;min-width:100px;position:relative}.file-selector-rename-text>div{overflow:hidden;pointer-events:none;visibility:hidden;white-space:nowrap}.file-selector-rename-input{bottom:0;left:0;position:absolute;right:0;top:0}.file-selector-grid{align-items:flex-start;border-color:transparent;border-radius:var(--radius);border-width:1px;display:flex;flex-direction:row;flex-wrap:wrap;gap:var(--file-selector-grid-gap);--tw-bg-opacity:1;background-color:rgba(var(--color-surface-light-rgb),var(--tw-bg-opacity,1));padding:.5rem}.file-selector-grid-item{height:var(--file-selector-grid-height)}.file-selector-grid-btn,.file-selector-grid-item{width:var(--file-selector-grid-width)}.file-selector-grid-btn{aspect-ratio:1/1;border-style:dashed;border-width:1px;display:flex;flex-direction:column;gap:0;height:auto;justify-content:center;--tw-border-opacity:1;background-color:rgba(var(--color-primary-50-rgb),.3);border-color:rgba(var(--color-primary-400-rgb),var(--tw-border-opacity,1));padding:.5rem;--tw-ring-color:transparent;--state-color:rgba(var(--color-primary-500-rgb),.05)}.file-selector-grid-btn .text{--tw-text-opacity:1;color:rgba(var(--color-primary-500-rgb),var(--tw-text-opacity,1))}.file-selector-grid-item .listitem{flex-direction:column;height:100%;padding:0;position:relative;width:100%}.file-selector-grid-item .item-avatar{border-radius:var(--radius);border-width:1px;width:100%;--tw-text-opacity:1;color:rgba(var(--color-gray-500-rgb),var(--tw-text-opacity,1))}.file-selector-grid-item .item-avatar.has-icon>.icon{font-size:calc(var(--file-selector-grid-width)/2)}.file-selector-grid-item .item-content,.file-selector-grid-item .toolbar{aspect-ratio:1/1;left:0;position:absolute;right:0;top:0;width:100%}.file-selector-grid-item .item-title{bottom:-1.25rem;font-size:.75rem;left:0;line-height:1rem;overflow:hidden;position:absolute;right:1.5rem;white-space:nowrap}.file-selector-grid-item .item-subtitle{border-radius:var(--radius-full);bottom:.25rem;left:.25rem;position:absolute;--tw-bg-opacity:1;background-color:rgba(var(--color-fore-rgb),var(--tw-bg-opacity,1));font-size:.75rem;line-height:1rem;padding-left:.25rem;padding-right:.25rem;--tw-text-opacity:1;color:rgba(var(--color-canvas-rgb),var(--tw-text-opacity,1));opacity:0;transition-duration:.15s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1)}.file-selector-grid-item:hover .item-subtitle{opacity:1}.file-selector-grid-item .toolbar .btn[data-remove-file]{background-color:rgba(var(--color-inverse-rgb),.5);padding:.375rem;position:absolute;right:1px;top:1px;--tw-text-opacity:1;color:rgba(var(--color-canvas-rgb),var(--tw-text-opacity,1))}.file-selector-grid-item .toolbar .btn[data-rename-file]{bottom:-1.5rem;padding:0;position:absolute;right:0}.file-selector-grid .file-selector-rename{bottom:0;height:1.5rem;position:absolute;top:auto}.file-selector-grid .file-selector-rename-text{width:100%}.is-dragging .file-selector-grid{border-width:1px;--tw-border-opacity:1;border-color:rgba(var(--color-primary-400-rgb),var(--tw-border-opacity,1));--tw-bg-opacity:1;background-color:rgba(var(--color-primary-50-rgb),var(--tw-bg-opacity,1))}:root{--nav-radius:var(--radius);--nav-active-color:var(--color-primary-500);--nav-active-bg:var(--color-inherit);--nav-heading-color:var(--color-gray-500);--nav-gap:0.25rem;--nav-item-color:inherit;--nav-item-bg:transparent;--nav-item-padding:1rem;--nav-item-height:2rem;--nav-item-gap:0.75rem;--nav-divider-height:calc(var(--nav-item-height)/2);--nav-divider-margin:0.5rem}.nav{list-style-type:none;padding-left:0}.nav,.nav-item{align-items:center;display:flex;position:relative}.nav-item{gap:var(--nav-item-gap)}.nav-item>a{align-items:center;background-color:var(--nav-item-bg);color:var(--nav-item-color);cursor:pointer;display:flex;gap:var(--nav-gap);height:var(--nav-item-height);justify-content:center;padding-left:var(--nav-item-padding);padding-right:var(--nav-item-padding)}.nav-item>a>.text{white-space:nowrap}.nav-item>.active{font-weight:700;--nav-item-color:var(--nav-active-color);--nav-item-bg:var(--nav-active-bg)}.nav-item>.selected{--nav-item-color:var(--nav-selected-color);--nav-item-bg:var(--nav-selected-bg)}.nav-item>.disabled{--nav-item-color:var(--nav-disabled-color);--nav-item-bg:var(--nav-disabled-bg)}.nav-item>.disabled>*{opacity:var(--opacity-disabled)}.nav-divider,.nav>.divider{align-self:center;height:var(--nav-divider-height);margin-left:var(--nav-divider-margin);margin-right:var(--nav-divider-margin)}.nav-heading{align-items:center;color:var(--nav-heading-color);display:flex;font-weight:700;gap:.25rem;height:2rem;justify-content:center;padding-left:1rem;padding-right:1rem}.nav-space{flex:1 1 auto;width:1rem}.nav-compact{--nav-gap:0.25rem;--nav-item-gap:0.5rem;--nav-item-height:1.75rem;--nav-item-padding:0.5rem;--nav-divider-margin:0.25rem}.nav-primary>.nav-item{position:relative}.nav-primary>.nav-item:hover{z-index:10}.nav-primary>.nav-item+.nav-item{margin-left:-1px}.nav-primary>.nav-item>a{border-radius:var(--radius-none);border-width:1px}.nav-primary>.nav-item:first-child>a,.nav-primary>.nav-item:has(.nav-heading)+.nav-item>a{border-bottom-left-radius:var(--nav-radius);border-top-left-radius:var(--nav-radius)}.nav-primary>.nav-item:last-child>a{border-bottom-right-radius:var(--nav-radius);border-top-right-radius:var(--nav-radius)}.nav-primary>.nav-item>.active{--tw-text-opacity:1;background:var(--nav-active-color);border-color:var(--nav-active-color);color:rgba(var(--color-canvas-rgb),var(--tw-text-opacity,1))}.nav-primary>.nav-divider{display:none}.nav-secondary>.nav-item>a{border-radius:var(--radius-none);position:relative}.nav-secondary>.nav-item>a:after{bottom:-2px;display:block;height:2px;left:0;position:absolute;right:0;--tw-bg-opacity:1;background-color:rgba(var(--color-border-rgb),var(--tw-bg-opacity,1));--tw-content:"";content:var(--tw-content)}.nav-secondary>.nav-item>.active:after{background-color:currentColor}.nav-secondary>.nav-divider{margin:0 0 0 -1px}.nav-tabs>.nav-item>a{border-bottom-left-radius:var(--radius-none);border-bottom-right-radius:var(--radius-none);position:relative}.nav-tabs>.nav-item>a:after{border-color:transparent;border-width:1px;bottom:-1px;display:block;left:-1px;pointer-events:none;position:absolute;right:-1px;top:-1px;--tw-border-opacity:1;border-bottom-color:rgba(var(--color-border-rgb),var(--tw-border-opacity,1));--tw-content:"";border-top-left-radius:inherit;border-top-right-radius:inherit;content:var(--tw-content)}.nav-tabs>.nav-item>.active:after{--tw-border-opacity:1;border-color:rgba(var(--color-border-rgb),var(--tw-border-opacity,1));border-bottom-color:transparent}.nav-tabs>.nav-divider{margin:0 0 0 -1px}.nav-pills>.nav-item>a{border-radius:var(--radius-full)}.nav-pills>.nav-item>.active{--tw-text-opacity:1;background:var(--nav-active-color);border-color:var(--nav-active-color);color:rgba(var(--color-canvas-rgb),var(--tw-text-opacity,1))}.nav-steps{--nav-item-bg:var(--color-canvas);--nav-active-bg:var(--color-primary-500);--nav-active-color:var(--color-canvas);--nav-selected-bg:var(--color-secondary-500);--nav-selected-color:var(--color-canvas)}.nav-steps>.nav-item+.nav-item>a{padding-left:calc(var(--nav-item-padding) + var(--nav-item-height)/3)}.nav-steps>.nav-item>a:after,.nav-steps>.nav-item>a:before{border-style:solid;height:0;left:100%;position:absolute;width:0;z-index:2;--tw-content:"";border-color:transparent;border-left-color:var(--nav-item-bg,var(--color-canvas));border-width:calc(var(--nav-item-height)/2);border-left-width:calc(var(--nav-item-height)/3);border-right-width:0;content:var(--tw-content)}.nav-steps>.nav-item>a:before{background-color:transparent!important;border-left-color:var(--color-border);bottom:auto;left:calc(100% + 5.5px);opacity:1!important;right:auto;top:.4rem;transform:none;z-index:1;--nav-item-height:1.2rem}.nav-steps>.nav-item:has(+.nav-item>.active)>.selected:before,.nav-steps>.nav-item:has(+.nav-item>.active,+.nav-item>.selected)>a:not(.active,.selected):before,.nav-steps>.nav-item:has(+.nav-item>.selected)>.active:before,.nav-steps>.nav-item:last-child>a:after,.nav-steps>.nav-item:last-child>a:before{display:none}.nav-steps>.nav-item>a:hover{--nav-item-bg:var(--color-gray-100)}.nav-steps>.nav-item>.active:hover{--nav-item-bg:var(--color-primary-600)}.nav-steps>.nav-item>.selected:hover{--nav-item-bg:var(--color-secondary-600)}.nav-stacked{flex-direction:column}.nav-stacked>.nav-item{width:100%}.nav-stacked>.nav-heading,.nav-stacked>.nav-item>a{justify-content:flex-start;width:100%}.nav-stacked>.nav-divider{height:1px;margin:.5rem 0;width:100%}.nav-primary.nav-stacked>.nav-item>a{height:2.5rem}.nav-primary.nav-stacked>.nav-item+.nav-item{margin-left:0;margin-top:-1px}.nav-primary.nav-stacked>.nav-item:first-child>a{border-bottom-left-radius:0;border-top-left-radius:var(--nav-radius);border-top-right-radius:var(--nav-radius)}.nav-primary.nav-stacked>.nav-item:last-child>a{border-bottom-left-radius:var(--nav-radius);border-bottom-right-radius:var(--nav-radius);border-top-right-radius:0}.nav-secondary.nav-stacked>.nav-item>a:after{bottom:0;height:100%;left:auto;right:0;top:0;width:2px;--tw-bg-opacity:1;background-color:rgba(var(--color-border-rgb),var(--tw-bg-opacity,1))}.nav-secondary.nav-stacked>.nav-item>.active:after{background-color:currentColor}.nav-secondary.nav-stacked>.nav-divider{margin:0}.nav-tabs.nav-stacked>.nav-item>a{border-bottom-left-radius:var(--nav-radius);border-bottom-right-radius:var(--radius-none);border-top-right-radius:var(--radius-none);position:relative}.nav-tabs.nav-stacked>.nav-item>a:after{--tw-border-opacity:1;border-bottom-color:transparent;border-bottom-left-radius:inherit;border-right-color:rgba(var(--color-border-rgb),var(--tw-border-opacity,1));border-top-left-radius:inherit}.nav-tabs.nav-stacked>.nav-item>a.active:after{--tw-border-opacity:1;border-color:rgba(var(--color-border-rgb),var(--tw-border-opacity,1));border-right-color:transparent}.nav-tabs.nav-stacked>.nav-divider{margin:0}.nav-pills.nav-stacked>.nav-item+.nav-item{margin-top:.25rem}.nav-justified>.nav-item:not(.flex-none,.nav-divider){flex:1 1 auto}.nav-justified>.nav-item>a{width:100%}.arrow,.arrow:before{background:inherit;height:calc(var(--arrow-size)*1.4142);position:absolute;width:calc(var(--arrow-size)*1.4142)}.arrow{visibility:hidden;--arrow-size:5px}.arrow:before{border:inherit;content:"";visibility:visible;--tw-rotate:45deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.arrow-top,.arrow-up{border-bottom:inherit;border-right:inherit;border-width:1px 0 0 1px;top:calc(1px - var(--arrow-size))}.white>.arrow-top,.white>.arrow-up{top:calc(0px - var(--arrow-size))}.arrow-bottom,.arrow-down{border-left:inherit;border-top:inherit;border-width:0 1px 1px 0;bottom:calc(1px - var(--arrow-size))}.white>.arrow-bottom,.white>.arrow-down{bottom:calc(0px - var(--arrow-size))}.arrow-left{border-right:inherit;border-top:inherit;border-width:0 0 1px 1px;left:calc(1px - var(--arrow-size))}.white>.arrow-left{left:calc(0px - var(--arrow-size))}.arrow-right{border-bottom:inherit;border-left:inherit;border-width:1px 1px 0 0;right:calc(1px - var(--arrow-size))}.white>.arrow-right{right:calc(0px - var(--arrow-size))}.popover{display:none;left:0;position:absolute;top:0;width:-moz-max-content;width:max-content}.popover.show{display:block}.popover-heading{align-items:center;border-top-left-radius:inherit;border-top-right-radius:inherit;display:flex;gap:1rem;height:2.5rem;justify-content:space-between;position:relative;z-index:1;--tw-bg-opacity:1;background-color:rgba(var(--color-surface-rgb),var(--tw-bg-opacity,1));padding-left:.75rem;padding-right:.5rem}.popover-title{flex:1 1 auto;font-weight:700}.popover-content{padding:.75rem;position:relative;z-index:1}.popover-arrow{z-index:0}.has-heading>.popover-arrow.arrow-top,.has-heading>.popover-arrow.arrow-up{--tw-bg-opacity:1;background-color:rgba(var(--color-surface-rgb),var(--tw-bg-opacity,1))}.popover>.btn-close{position:absolute;right:.5rem;top:.625rem;z-index:2}.btn-close+.popover-content{padding-right:3rem}.btn.with-popover-show{--tw-shadow:inset 0 2px 4px 0 rgba(0,0,0,.05);--tw-shadow-colored:inset 0 2px 4px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.with-popover-show[data-pop-placement=top]>.caret{--tw-rotate:180deg}.with-popover-show[data-pop-placement=left]>.caret,.with-popover-show[data-pop-placement=top]>.caret{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.with-popover-show[data-pop-placement=left]>.caret{--tw-rotate:90deg}.with-popover-show[data-pop-placement=right]>.caret{--tw-rotate:-90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.pager{align-items:center;display:flex;gap:.25rem;white-space:nowrap}.menu.pager-size-menu{display:grid!important;grid-template-columns:repeat(3,minmax(0,1fr));text-align:center}.menu.pager-size-menu>.menu-item>a{margin:.125rem}.pager .pager-goto-group>.form-control{width:3rem}.pager .pager-goto-group>.input-group-addon{border-width:1px;--tw-border-opacity:1;border-color:rgba(var(--color-gray-300-rgb),var(--tw-border-opacity,1));--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1))}.pager>.pager-nav.active{--tw-text-opacity:1;box-shadow:0 0 0 1px var(--color-primary-500);color:rgba(var(--color-primary-500-rgb),var(--tw-text-opacity,1))}.panel{border-radius:var(--radius);overflow:hidden;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:rgba(var(--color-inverse-rgb),var(--tw-ring-opacity,1));--tw-ring-opacity:0.05}.panel-heading{background-color:var(--panel-heading-bg);flex-wrap:nowrap;gap:1rem;justify-content:space-between;padding:.5rem 1rem}.panel-heading,.panel-title{align-items:center;display:flex}.panel-title{font-weight:700;gap:.5rem;margin:0}.panel-actions{align-items:center;display:flex;margin-right:-.5rem}.panel-body{padding:.75rem 1rem}.panel-footer{align-items:center;background-color:var(--panel-footer-bg);display:flex;gap:.5rem;padding:.5rem 1rem}.size-sm .panel-body,.size-sm .panel-footer,.size-sm .panel-heading{padding:.375rem .75rem}.size-lg .panel-body,.size-lg .panel-footer,.size-lg .panel-heading{padding:1rem 1.25rem}.picker{position:relative}.picker-select{align-items:center;gap:.25rem;justify-content:space-between}.picker-select,.picker-select.form-control{display:flex}.picker-select-placeholder{flex:1 1 auto;--tw-text-opacity:1;color:rgba(var(--color-placeholder-rgb),var(--tw-text-opacity,1))}.picker-select-multi .picker-select-placeholder{padding-left:.25rem;padding-right:.25rem}.picker-single-selection{flex:1 1 auto;min-width:0;overflow:hidden;white-space:nowrap}.picker-deselect-btn{border-radius:var(--radius-full);padding:.25rem}.picker-deselect-btn:not(:hover){opacity:.7}.picker-select-multi.form-control{height:auto;min-height:32px;padding-left:.25rem}.picker-multi-selections{display:flex;flex:1 1 auto;flex-wrap:wrap;gap:.25rem;min-width:0}.picker-multi-selection{align-items:center;border-radius:var(--radius-full);border-width:1px;display:flex;max-width:100%;--tw-bg-opacity:1;background-color:rgba(var(--color-surface-rgb),var(--tw-bg-opacity,1));padding-left:.5rem}.readonly .picker-multi-selection{padding-right:.5rem}.picker-multi-selection>.text{max-width:180px;min-width:0;overflow:clip;white-space:nowrap}.picker-no-search{cursor:default}.picker-menu-list{border-style:none;flex:1 1 auto;min-height:0;overflow-y:auto;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.picker-menu-search+.picker-menu-list.menu{margin-top:-.125rem;padding-top:0}.picker-menu-list.tree{padding:.5rem}.picker-menu-list .tree-item>.selected .item-content{font-weight:400}.picker-menu .search-menu-footer{border-top-width:1px;padding-bottom:.25rem;padding-top:.25rem}.picker-search-input{border-color:transparent;height:1.75rem;outline-width:0!important;padding-left:0;padding-right:2rem;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)!important;--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color)!important;box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)!important}.picker-search{flex:none;position:relative;width:100%}.picker-search>.magnifier{opacity:.5;position:absolute;right:0;top:.5rem}.picker-search-clear.btn{cursor:pointer;height:1.25rem;position:absolute;right:0;top:.25rem;width:1.25rem}.picker-search.is-inline{min-width:64px;width:4rem}.is-inline>.picker-search-input{height:1.25rem;min-width:64px;padding-left:.25rem;padding-right:.25rem}.picker-search-measure{height:0;left:0;overflow:hidden;position:absolute;top:0;white-space:nowrap}.sidebar{flex:none!important;position:relative;--gutter-width:1px;--sidebar-duration:200ms}.has-sidebar-animation .sidebar{transition-duration:.15s;transition-duration:var(--sidebar-duration);transition-property:width,margin;transition-timing-function:cubic-bezier(.4,0,.2,1)}.sidebar-left.is-collapsed{margin-left:calc(var(--gutter-width)*-1)}.sidebar-right.is-collapsed{margin-right:calc(var(--gutter-width)*-1)}.sidebar.is-collapsed>*,.sidebar.is-expanded.is-animating>*{display:none}.sidebar.is-collapsed>.sidebar-gutter{display:flex!important}.sidebar-gutter{bottom:0;left:100%;position:absolute;top:0;width:var(--gutter-width);z-index:10}.sidebar-right>.sidebar-gutter{left:auto;right:100%}.is-collapsed>.gutter>.gutter-toggle>span{--tw-rotate:-180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.sidebar-gutter:before{border-radius:var(--radius-full);opacity:0}.sidebar-gutter:hover:before{opacity:1;width:.5rem}.is-expanded .sidebar-gutter.gutter-border:before{opacity:1}.is-sidebar-resizing{cursor:col-resize}.table{--table-head-bg:var(--color-surface);--table-striped-color:var(--color-gray-50);--table-hover-color:rgba(var(--color-primary-500-rgb),.05);--table-border-color:var(--color-border)}.table{border-color:var(--table-border-color);width:100%}.table>thead{background-color:var(--table-head-bg)}.table>*>tr{border-bottom-width:1px}.table>*>tr>*{padding:.5rem 1rem}.table-striped>tbody>tr:nth-child(2n){background:var(--table-striped-color)}.table-hover>tbody>tr:hover>*{background:var(--table-hover-color)}.table.bordered>*>tr>*{border-width:1px}.table.borderless>*>tr,.table.borderless>*>tr>*{border-style:none}.condensed>*>tr>*{padding:.375rem .75rem}.table-fixed{table-layout:fixed}.table-fixed>*>tr>*{overflow:hidden;white-space:nowrap}.toolbar{align-items:center;display:flex;position:relative}.toolbar>.divider{margin:.5rem;width:1px;--tw-bg-opacity:1;background-color:rgba(var(--color-border-rgb),var(--tw-bg-opacity,1))}.toolbar-space{flex:1 1 auto;height:1px;width:1px}.toolbar>.dropdown.show{align-items:center;display:flex;position:relative}:root{--tooltip-bg:var(--skin-color,var(--color-inverse));--tooltip-text:var(--skin-text,var(--color-canvas));--tooltip-arrow:6px;--tooltip-delay:0.5s}.hint,[class*=" hint-"],[class^=hint-]{position:relative}.hint:before,[class*=" hint-"]:before,[class^=hint-]:before{border-style:solid;height:0;position:absolute;width:0;--tw-content:"";border-color:var(--tooltip-bg) transparent transparent transparent;border-width:var(--tooltip-arrow) var(--tooltip-arrow) 0 var(--tooltip-arrow);content:var(--tw-content);margin-bottom:calc(0px - var(--tooltip-arrow))}.hint:after,[class*=" hint-"]:after,[class^=hint-]:after{background-color:var(--tooltip-bg);border-color:var(--tooltip-color);border-radius:var(--radius);color:var(--tooltip-text);font-size:.75rem;line-height:1rem;max-width:28rem;overflow:hidden;padding:.25rem .5rem;position:absolute;white-space:nowrap;--tw-shadow:0 3px 8px 0 rgba(0,0,0,.04),0 1px 2px -1px rgba(0,0,0,.01);--tw-shadow-colored:0 3px 8px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-content:attr(data-hint);content:var(--tw-content);text-shadow:0 1px 0 var(--tooltip-bg)}.hint:after,.hint:before,[class*=" hint-"]:after,[class*=" hint-"]:before,[class^=hint-]:after,[class^=hint-]:before{bottom:100%;left:50%;opacity:0;pointer-events:none;transition-delay:0s;transition-duration:.15s;transition-property:opacity,visibility;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-timing-function:cubic-bezier(.4,0,1,1);visibility:hidden;z-index:1800;--tw-translate-x:-50%;--tw-translate-y:calc(var(--tooltip-arrow)*-1);transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hint:hover:after,.hint:hover:before,[class*=" hint-"]:hover:after,[class*=" hint-"]:hover:before,[class^=hint-]:hover:after,[class^=hint-]:hover:before{opacity:1;transition-delay:var(--tooltip-delay);visibility:visible}.hint-bottom:before{border-color:transparent transparent var(--tooltip-bg) transparent;border-width:0 var(--tooltip-arrow) var(--tooltip-arrow) var(--tooltip-arrow);margin-bottom:auto;margin-top:calc(0px - var(--tooltip-arrow))}.hint-bottom:after,.hint-bottom:before{bottom:auto;top:100%;--tw-translate-y:var(--tooltip-arrow);transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hint-left:before{border-color:transparent transparent transparent var(--tooltip-bg);border-width:var(--tooltip-arrow) 0 var(--tooltip-arrow) var(--tooltip-arrow);margin-bottom:auto;margin-right:calc(0px - var(--tooltip-arrow))}.hint-left:after,.hint-left:before{bottom:50%;left:auto;right:100%;--tw-translate-x:calc(var(--tooltip-arrow)*-1);--tw-translate-y:50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hint-right:before{border-color:transparent var(--tooltip-bg) transparent;border-width:var(--tooltip-arrow) var(--tooltip-arrow) var(--tooltip-arrow) 0;margin-bottom:auto;margin-left:calc(0px - var(--tooltip-arrow))}.hint-right:after,.hint-right:before{bottom:50%;left:100%;--tw-translate-x:var(--tooltip-arrow);--tw-translate-y:50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hint-lg:after,.hint-sm +.hint-md:after:after,.hint-xl:after{white-space:normal;word-break:break-all}.hint-sm:after{width:4rem}.hint-md:after{width:8rem}.hint-lg:after{width:16rem}.hint-xl:after{width:24rem}.hint-primary{--tooltip-bg:var(--color-primary-500)}.hint-success{--tooltip-bg:var(--color-success-500)}.hint-danger{--tooltip-bg:var(--color-danger-500)}.hint-warning{--tooltip-bg:var(--color-warning-500)}.hint-important{--tooltip-bg:var(--color-important-500)}.hint-special{--tooltip-bg:var(--color-special-500)}.tooltip{background-color:var(--tooltip-bg);border-color:var(--tooltip-color);border-radius:var(--radius);color:var(--tooltip-text);font-size:.75rem;line-height:1rem;max-width:28rem;padding:.25rem .5rem;white-space:pre-wrap;z-index:1800}.tooltip:not(.white)>.arrow{border-width:0}.tooltip.white>.arrow{border-color:inherit}.tooltip-has-title{--tw-bg-opacity:0.8;padding:.5rem .75rem .75rem;--tw-shadow:0 10px 25px -5px rgba(0,0,0,.2),0 4px 10px -6px rgba(0,0,0,.15);--tw-shadow-colored:0 10px 25px -5px var(--tw-shadow-color),0 4px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-backdrop-blur:blur(8px);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.tooltip-has-title>.arrow{opacity:.75}.tooltip-heading{align-items:center;display:flex;font-size:.8125rem;font-weight:700;gap:1rem;justify-content:space-between;line-height:1.25rem;padding:.25rem}.tooltip-heading>.btn-close{margin-right:-.25rem}.tooltip-content{padding:.25rem}.tree-item-inner{flex-direction:row;min-height:24px;padding-left:var(--list-nested-indent)}.tree-item-inner,.tree-toggle{align-items:center;display:flex}.tree-toggle{border-radius:var(--radius);flex:none;height:1rem;justify-content:center;margin-right:-.375rem;width:1rem;--caret-size:5px;--caret-opacity:.3}.tree-item-inner>.item-icon{opacity:.5;width:1rem}.tree-item-inner:hover>.item-icon{opacity:.8}.tree-item-inner.has-hover{border-radius:var(--radius)}.tree-item-inner .item-title:not(:hover),.tree-item-inner>a.item-title:not(:hover){color:inherit}.tree-item-inner>.toolbar{margin-left:1rem;opacity:.6}.tree-item-inner:hover>.toolbar{opacity:1}.tree-item>.active{background:var(--menu-active-bg);color:var(--menu-active-color)}.tree-item>.selected{background:var(--menu-selected-bg)}.tree-item>.selected .item-content{color:var(--menu-selected-color);font-weight:700}.tree.search-menu-on-top>.search-box{left:0;right:0}.tree-lines .tree{position:relative}.tree-lines .tree-item{--tree-line-indent:calc(var(--list-nested-indent) + 8px)}.tree-lines .tree:before{border-left-width:1px;bottom:.5rem;display:block;left:var(--tree-line-indent);position:absolute;top:-.5rem;--tw-content:"";content:var(--tw-content)}.upload .upload-tip{--tw-text-opacity:1;color:rgba(var(--color-gray-400-rgb),var(--tw-text-opacity,1))}.upload .draggable-area{background-color:rgba(var(--color-primary-50-rgb),.2);border:1px dashed var(--color-primary-300)}.upload .draggable-area.dragover{background-color:rgba(var(--color-primary-500-rgb),.1);border-style:solid}.upload .upload-tip{color:var(--color-slate-500)}.file-item>.img{height:120px;width:120px}.upload .file-item:hover .file-size{display:flex!important}.form-batch-container{overflow-y:auto}.form-batch-table{min-width:100%;table-layout:fixed;--table-head-bg:var(--color-canvas)}.form-batch-table>*>tr{--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1))}.form-batch-table>*>tr>*{padding-left:.375rem;padding-right:.375rem;vertical-align:top}.form-batch-table>*>tr>th{text-align:left;vertical-align:middle}.form-batch-head[data-name=ACTIONS]{width:5rem}.form-batch-head[data-name=ACTIONS][data-action-count="3"]{width:6rem}.form-batch-label{display:inline}.form-batch-control>textarea.form-control{height:2rem}.form-batch-btn+.btn{margin-left:.25rem}.form-batch-table>tbody[data-count="1"] .form-batch-btn[data-type=delete]{display:none}.form-batch-ditto{position:relative}.form-batch-ditto-btn{bottom:0;height:auto;opacity:.5;padding-left:.5rem;padding-right:.5rem;position:absolute!important;right:0;top:0}.form-batch-ditto-btn:after{bottom:.5rem;left:-1px;position:absolute;top:.5rem;width:1px;--tw-bg-opacity:1;background-color:rgba(var(--color-border-rgb),var(--tw-bg-opacity,1));--tw-content:"";content:var(--tw-content)}[data-ditto=on] .form-batch-ditto-btn{--tw-text-opacity:1;color:rgba(var(--color-primary-500-rgb),var(--tw-text-opacity,1));opacity:1}td.form-batch-row-actions{padding-bottom:.75rem!important;padding-top:.75rem!important}.form-batch-ditto-wrapper{position:relative}.form-batch-ditto-control .form-control,.form-batch-ditto-control .pick-pri{padding-right:calc(var(--form-batch-ditto-width) + 8px)}.form-batch-ditto-control .input-control>.input-control-suffix{right:var(--form-batch-ditto-width)}.form-batch-ditto-control .input-control>.form-control{padding-right:calc(var(--form-batch-ditto-width) + var(--input-control-suffix))}.has-fixed-actions .form-batch-col-actions{position:sticky;right:0;z-index:1;--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1))}.form-batch-col-actions.is-pinned:before{background-image:linear-gradient(-90deg,transparent,transparent),linear-gradient(-90deg,transparent,transparent 50%);border-right-width:1px;bottom:0;content:" ";display:block;left:-1rem;position:absolute;top:0;transition-duration:.15s;transition-property:background;transition-timing-function:cubic-bezier(.4,0,.2,1);width:1rem;z-index:1}.form-batch:hover .form-batch-col-actions.is-pinned:before{background-image:linear-gradient(-90deg,rgba(0,0,0,.03),transparent),linear-gradient(-90deg,rgba(0,0,0,.03),transparent 50%)}.panel-form-batch .form-batch-container .form-batch-col-actions.is-pinned:after{bottom:0;display:block;position:absolute;right:-1rem;top:0;width:1rem;z-index:1;--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1));content:" "}.datalist{--datalist-label-width:68px}.datalist-item{display:flex;gap:.5rem;padding-bottom:.375rem;padding-top:.375rem}.datalist-item-label{align-items:center;display:flex;flex:none;justify-content:flex-end;overflow:hidden;white-space:nowrap;width:var(--datalist-label-width);--tw-text-opacity:1;color:rgba(var(--color-gray-500-rgb),var(--tw-text-opacity,1))}.datalist-item-content{align-items:center;display:flex;flex:1 1 0%;gap:.5rem}.deliverable-items{border-radius:var(--radius);border-width:1px}.deliverable-category{align-items:stretch;-moz-column-gap:1rem;column-gap:1rem;display:flex;min-height:3rem}.deliverable-category+.deliverable-category{border-top-width:1px}.deliverable-category-name{align-items:center;border-right-width:1px;display:flex;flex:none;justify-content:center;padding:.25rem .5rem;width:var(--deliverable-category-width,100px)}.required .deliverable-category-name>.text{display:block;position:relative;text-align:center}.required .deliverable-category-name>.text:after{font-size:1rem;line-height:1.5rem;position:absolute;right:-.75rem;top:0;--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity,1));--tw-content:"*";content:var(--tw-content)}.deliverable-item-row{align-items:center;-moz-column-gap:1rem;column-gap:1rem;display:flex;min-height:3rem;padding:.25rem .5rem}.deliverable-item-doc,.deliverable-item-file{align-items:center;display:flex;gap:.25rem;min-width:200px}.deliverable-item-actions{flex:1 1 auto}.deliverable-item-avatar{align-items:center;display:flex;gap:.25rem;white-space:nowrap}.deliverable-item-info{flex:1 1 auto;overflow:hidden;white-space:nowrap;--tw-text-opacity:1;color:rgba(var(--color-gray-500-rgb),var(--tw-text-opacity,1))}.deliverable-item-avatar+.deliverable-item-info{margin-left:-.75rem}.deliverable-item-doc-picker{width:14rem}.deliverable-item-rename{align-items:center;display:flex;gap:.5rem}.deliverable-item-rename .form-control{flex:1 1 auto;width:18rem}.deliverable-item .form-tip{line-height:28px;margin:0;padding-left:7rem;position:relative;top:-.5rem;width:100%}.affine-theme,.affine-theme [data-theme=dark],.affine-theme [data-theme=light]{--affine-brand-color:var(--color-primary-500);--affine-primary-color:var(--color-primary-500);--affine-text-primary-color:var(--color-fore);--affine-font-family:var(--font-family-sans);--affine-font-serif-family:var(--font-family-serif);--affine-font-mono-family:var(--font-family-mono)}.blocksuite-portal{position:absolute!important}.embed-card-modal-mask{z-index:12!important}.embed-card-modal-wrapper{z-index:13!important}.affine-code-block-container .line-number{opacity:.5}@-moz-document url-prefix(){.affine-code-block-container v-line{width:100%}}.affine-list-block__prefix{color:inherit!important}.embed-zui-iframe{border-radius:var(--radius-lg);border-width:1px}affine-bookmark .affine-block-component{border-width:0}.is-editor-empty.is-editing .affine-block-children-container>affine-paragraph:first-child .affine-paragraph-placeholder:not(.visible){display:block!important}database-datasource-note-renderer{display:none!important}.editor{--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1))}.editor-is-exporting audio,.editor-is-exporting canvas,.editor-is-exporting embed,.editor-is-exporting iframe,.editor-is-exporting img,.editor-is-exporting object,.editor-is-exporting svg,.editor-is-exporting video{display:initial!important}body>.affine-modal{align-items:center;background-color:var(--modal-bg);bottom:0!important;display:flex;justify-content:center;left:0!important;position:fixed!important;right:0!important;top:0!important}body>.affine-modal>center-peek{left:auto;max-width:1200px;position:relative;top:auto;--tw-shadow:0 0 #0000!important;--tw-shadow-colored:0 0 #0000!important;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)!important}body>.affine-modal affine-data-view-record-detail{border-radius:var(--radius);overflow:auto;--tw-shadow:0 10px 25px -5px rgba(0,0,0,.2),0 4px 10px -6px rgba(0,0,0,.15);--tw-shadow-colored:0 10px 25px -5px var(--tw-shadow-color),0 4px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);max-height:calc(100vh - 40px)}body>.affine-modal>center-peek>.close-modal{height:2rem;right:.75rem;top:.75rem;width:2rem;z-index:10}body>.affine-modal>center-peek>.close-modal>svg{height:1rem;width:1rem}.affine-database-column-stats{margin-left:0!important}.editor.is-readonly .database-header-bar+uni-lit,.editor.is-readonly .unsupported-content{display:none}.form-control .editor,.form-group .editor{border-radius:var(--form-control-radius);--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1));outline-color:transparent;outline-style:solid;outline-width:1px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:var(--form-control-border);transition-duration:.15s;transition-property:outline,box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1);--affine-editor-width:initial;--affine-editor-bottom-padding:24px!important;--affine-editor-side-padding:16px!important;min-height:200px}.detail-section .editor,.section .editor{--affine-editor-width:initial;--affine-editor-bottom-padding:0!important;--affine-editor-side-padding:0px!important}.form-control .has-pick-checks .affine-page-root-block-container,.form-group .has-pick-checks .affine-page-root-block-container{padding-left:40px!important;padding-right:calc(var(--affine-block-selection-side-width) + 12px)!important;--affine-block-selection-side-width:100px}.form-control .affine-page-viewport,.form-group .affine-page-viewport{overflow:visible}.editor page-editor{display:flex;flex-direction:column}.editor .affine-page-viewport,.editor .affine-page-viewport>editor-host{display:flex;flex:1 1 auto;flex-direction:column}.editor .affine-page-viewport>editor-host>affine-page-root{flex:1 1 auto;padding:1px}.form-control .editor page-editor,.form-group .editor page-editor{height:100%}.dtable .toggle-icon{margin-top:0;opacity:.5;position:static!important;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.editor-block-pick-options{display:none}affine-block-selection.is-last-picked .editor-block-pick-options{display:flex}.editor .toggle-icon{align-items:center}.affine-layout-block-container>affine-zui-layout-cell .affine-block-selection-side{left:0;top:32px}.affine-layout-block-container>affine-zui-layout-cell:last-child .affine-block-selection-side{left:calc(100% + 12px);top:0}.scrollbar,:root{--scrollbar-size:10px;--scrollbar-opacity:.6;--scrollbar-bg:rgba(var(--color-inverse-rgb),.15);--scrollbar-inset:inset 0 0 0 1px rgba(var(--color-inverse-rgb),.05);--scrollbar-bar-bg:rgba(var(--color-inverse-rgb),.3);--scrollbar-hover-bg:rgba(var(--color-inverse-rgb),.4);--scrollbar-drag-bg:rgba(var(--color-inverse-rgb),.5);--scrollbar-radius:var(--radius-sm);--scrollbar-duration:.7s}.scrollbar{background:var(--scrollbar-bg);box-shadow:var(--scrollbar-shadow);opacity:var(--scrollbar-opacity);position:absolute;transition-duration:.15s;transition-duration:var(--scrollbar-duration);transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1)}.scrollbar-hover .scrollbar{opacity:0}.scrollbar-hover:hover .scrollbar{opacity:var(--scrollbar-opacity)}.scrollbar.is-dragging,.scrollbar:hover{opacity:1!important}.scrollbar-bar{background:var(--scrollbar-bar-bg);border-radius:var(--scrollbar-radius);position:absolute}.scrollbar-bar:hover{background:var(--scrollbar-hover-bg)}.is-dragging>.scrollbar-bar{background:var(--scrollbar-drag-bg)}.is-horz>.scrollbar-bar{height:100%;z-index:20}.is-vert>.scrollbar-bar{width:100%;z-index:20}.htmldiff{--htmldiff-color-insert-rgb:var(--color-success-600-rgb);--htmldiff-color-delete-rgb:var(--color-danger-500-rgb)}.htmldiff ins[data-operation-index]{background:rgba(var(--htmldiff-color-insert-rgb),.1);border-left:2px solid rgba(var(--htmldiff-color-insert-rgb),.2);border-right:2px solid rgba(var(--htmldiff-color-insert-rgb),.2);color:rgba(var(--htmldiff-color-insert-rgb,1));text-decoration:none}.htmldiff del[data-operation-index]{color:rgba(var(--htmldiff-color-delete-rgb,1));text-decoration:line-through}.history-panel>.panel-heading+.panel-body{margin-top:-.75rem}.history-panel-action{position:relative}.history-panel-action:before{border-left-width:1px;bottom:-.375rem;left:.5rem;position:absolute;top:22px;--tw-border-opacity:1;border-color:rgba(var(--color-border-rgb),var(--tw-border-opacity,1));--tw-content:"";content:var(--tw-content)}.col-reverse>.history-panel-action:first-child:before,.col>.history-panel-action:last-child:before{display:none}.history-panel-action>.item-inner{padding-left:1.5rem}.history-panel-action>.item-inner>.avatar{left:0;position:absolute;top:.375rem}.history-panel-action .file-list-item .item-content{flex:none}.history-panel-action blockquote{margin-top:.25rem;--tw-bg-opacity:1;background-color:rgba(var(--color-surface-rgb),var(--tw-bg-opacity,1));padding:.25rem .25rem .25rem .5rem}.history-panel-action blockquote.original{display:none}.doc-app{--doc-view-max-width:unset;--doc-view-padding:24px 40px;--doc-view-side-width:240px;--affine-editor-side-padding:0}.doc-app{align-items:stretch;display:flex;flex-direction:column;min-height:120px}.doc-space-picker-menu .menu-item>.item-inner{padding-right:.25rem}.doc-app-search .form-control{border-radius:var(--radius-full)}.doc-app-search .input-control-prefix{cursor:pointer;opacity:.75}.doc-app-search.empty:not(.focus){transition-duration:.15s;transition-property:width;transition-timing-function:cubic-bezier(.4,0,.2,1);width:2rem}.doc-app-search.empty:not(.focus) .form-control{padding-left:.5rem;padding-right:.5rem;--tw-ring-color:transparent}.doc-app-search.empty:not(.focus) .form-control::-moz-placeholder{opacity:0}.doc-app-search.empty:not(.focus) .form-control::placeholder{opacity:0}.doc-app-search.empty:not(.focus) .form-control:hover{--tw-bg-opacity:1;background-color:rgba(var(--color-gray-100-rgb),var(--tw-bg-opacity,1))}.doc-app-search:not(.empty) .form-control{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-50-rgb),var(--tw-bg-opacity,1));--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-primary-300-rgb),var(--tw-ring-opacity,1))}.doc-app-header .divider{height:1rem!important;margin-left:.25rem!important;margin-right:.25rem!important}.doc-app .is-match-keys{--tw-bg-opacity:1;background-color:rgba(var(--color-warning-100-rgb),var(--tw-bg-opacity,1));font-weight:700;text-decoration-line:underline;text-underline-offset:2px}.doc-main .dtable-footer{border-bottom-width:1px;--tw-border-opacity:1;border-bottom-color:rgba(var(--color-border-rgb),var(--tw-border-opacity,1))}.doc-main.show-view>.doc-list{pointer-events:none;visibility:hidden;z-index:-10}.has-doc-app-fullscreen #mainNavbar,.has-doc-app-fullscreen .doc-app-header,.has-doc-app-fullscreen .doc-sidebar,.has-doc-app-fullscreen>#header{display:none!important}.has-doc-app-fullscreen #mainContainer{max-width:none!important;padding:0!important;width:100%!important}.has-doc-app-fullscreen #docApp{height:calc(100vh - 12px)!important}.doc-app doc-title,.editor-is-exporting .doc-editor-title{display:none}.editor-is-exporting doc-title{display:block}.doc-app .affine-page-root-block-container{margin:0;max-width:100%}.doc-app-nav .dropmenu-btn{max-width:200px}.doc-app-nav .dropmenu-btn>.text,.doc-app-nav .dropmenu-btn>.text>div{max-width:100%}.doc-app-nav .pick-diff .btn{--skin-hover-bg:var(--color-primary-100);--skin-hover-text:var(--color-primary-500)}.doc-app-nav .pick-diff .btn.gray-pale{border-radius:9px;gap:3px;height:18px;padding-left:5px;padding-right:3px}.doc-app-nav .pick-diff .btn.ghost{border-radius:2px;height:18px;min-width:auto;padding:0;width:18px}.doc-tree .item-inner{cursor:pointer;padding-right:0;position:relative}.doc-tree .item-inner>.item-icon{flex:none;opacity:1}.doc-tree .item-inner .item-title{overflow:hidden;text-overflow:clip;white-space:nowrap}.doc-tree .item-inner.selected .item-title{font-weight:700}.doc-tree .item-inner>.toolbar{top:.25rem!important}.doc-tree .item-inner>.toolbar>.btn.with-popover-show,.doc-tree .list-heading-inner>.toolbar{opacity:1!important}.doc-tree .item-inner:hover>.toolbar{margin-top:0!important}.doc-tree .with-hover-actions>.item>.item-inner .item-actions{right:0}.doc-sidebar .sortable-ghost{border-radius:var(--radius-sm);z-index:10;--tw-bg-opacity:1;background-color:rgba(var(--color-warning-100-rgb),var(--tw-bg-opacity,1));opacity:.3;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-warning-600-rgb),var(--tw-ring-opacity,1))}.doc-tree [z-key=project-files]{border-top:1px solid rgba(var(--color-border-rgb),var(--tw-border-opacity));margin-top:.25rem;padding-top:.25rem}.doc-list-item-title{overflow:hidden;text-overflow:clip}.doc-view{scroll-padding-top:16px;scrollbar-gutter:stable both-edges}.doc-view-content{max-width:var(--doc-view-max-width);padding:var(--doc-view-padding)}.doc-files .item-title{overflow:hidden;white-space:nowrap}.doc-files .file-list-item{border-radius:var(--radius-lg);transition-duration:.15s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1)}.doc-files .file-list-item:hover{background-color:rgba(var(--color-inverse-rgb),.05)}.doc-files .file-list-item .item-actions,.doc-files .file-list-item:hover .item-actions{margin-left:1rem;margin-top:0;position:relative}.doc-files .file-list-item .item-actions .btn{--tw-text-opacity:1;color:rgba(var(--color-link-rgb),var(--tw-text-opacity,1))}.doc-editor .affine-page-viewport{overflow:visible!important}.doc-editor .affine-page-root-block-container{max-width:100%;padding:0 0 2rem!important}.doc-editor-keywords,.doc-editor-title{flex:none;max-width:100%;min-width:0}.doc-editor-keywords:hover .form-control{--tw-bg-opacity:1;background-color:rgba(var(--color-gray-100-rgb),var(--tw-bg-opacity,1))}.doc-editor-keywords .form-control:focus{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-50-rgb),var(--tw-bg-opacity,1));--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);outline:2px solid transparent;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.doc-editor-control{z-index:2}.doc-view-sidebar{display:flex;flex-direction:column;max-height:calc(100% - 24px);overflow:visible;width:var(--doc-view-side-width)}.doc-view-sidebar-nav{--nav-item-padding:6px;--nav-item-color:var(--color-gray-500);--nav-active-bg:var(--color-primary-100);--nav-active-color:var(--color-fore);--nav-item-height:26px;--nav-divider-margin:8px;background-color:rgba(var(--color-surface-rgb),.2)}.doc-view-sidebar .datalist{--datalist-label-width:56px}.is-closed.doc-view-sidebar .doc-view-sidebar-content,.is-sidebar-closed .doc-view-sidebar-content{display:none}.is-closed.doc-view-sidebar,.is-sidebar-closed .doc-view-sidebar{--doc-view-side-width:0;opacity:0;transition-delay:1s;transition-duration:1s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1)}.is-outline.doc-view-sidebar{--doc-view-side-width:260px}.doc-view:hover .doc-view-sidebar{opacity:1;transition-delay:0s}.is-closed>.doc-view-sidebar-container,.is-sidebar-closed .doc-view-sidebar-container{position:absolute;right:0;top:0}.doc-view-sidebar-container{background-color:rgba(var(--color-canvas-rgb),.8);min-height:0;--tw-backdrop-blur:blur(8px);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.doc-outline .listitem{position:relative}.doc-outline .tree-toggle.is-empty:before{border-radius:var(--radius-full);height:.25rem;position:absolute;width:.25rem;--tw-bg-opacity:1;background-color:rgba(var(--color-gray-300-rgb),var(--tw-bg-opacity,1));--tw-content:"";content:var(--tw-content)}.doc-outline .is-nested-root.no-nested-items{padding-left:.375rem}.doc-view input{font-family:inherit}.doc-diff{font-size:15px;line-height:23px;--doc-diff-ins-color:rgba(0,255,0,.5);--doc-diff-del-color:rgba(255,0,0,.5)}.doc-diff .affine-paragraph-block-container{border-radius:0;margin:2px 0}.doc-diff p{min-height:23px}.doc-diff table{border-collapse:collapse;width:100%}.doc-diff table td,.doc-diff table th{border:1px solid #e3e2e4;padding:6px 12px}.doc-diff ins[data-operation-index]{background:rgba(208,246,232,.4);border-left:2px solid var(--doc-diff-ins-color);border-right:2px solid var(--doc-diff-ins-color);color:#0ca76f;text-decoration:none}.doc-diff ins[data-operation-index] img:only-child{border:2px solid var(--doc-diff-ins-color)}.doc-diff>[data-diff-node=ins]{border-left:2px solid var(--doc-diff-ins-color);padding-left:4px}.doc-diff del[data-operation-index]{color:#d91b1b;text-decoration:line-through}.doc-diff del[data-operation-index] img:only-child{border:2px solid var(--doc-diff-del-color)}.doc-diff>[data-diff-node=del]{border-left:2px solid var(--doc-diff-del-color);padding-left:4px}.doc-path-picker .picker-deselect-btn{display:none}.doc-path-picker-angle{margin-left:-.125rem;margin-right:-.125rem}.doc-path-picker,.doc-space-picker{outline:2px solid transparent!important;outline-offset:2px!important;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)!important;--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color)!important;box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)!important}.doc-path-picker-toggle.btn{flex:none;--btn-height:18px;--skin-hover-bg:var(--color-primary-100);--skin-hover-text:var(--color-primary-500)}.doc-path-picker-toggle>.icon{--tw-scale-x:1.25;--tw-scale-y:1.25;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.doc-toolbar-align-menu{align-items:center;display:flex!important;flex-direction:row;flex-wrap:nowrap}.doc-toolbar-align-menu>.menu-item>a>.item-icon{opacity:1}.doc-toolbar-align-menu>.menu-item>a>.item-content{display:none}.dropmenu-btn{gap:.25rem;padding-left:.5rem;padding-right:.5rem}.dropmenu-btn>.text{max-width:180px;overflow:hidden}.dropmenu-btn>.is-leading{left:-.625rem;opacity:.6;position:absolute}.dropmenu-btn>.is-caret{align-items:center;background-color:rgba(var(--color-canvas-rgb),.2);border-radius:var(--radius);display:flex;height:1rem;justify-content:center;width:1rem}.dropmenu-nav{border-bottom-width:1px;margin-left:.75rem;margin-right:.75rem;margin-top:.25rem}.has-search .dropmenu-nav{margin-top:-.5rem}.dropmenu-nav>.nav-secondary{gap:.5rem}.dropmenu-nav>.nav-secondary>.nav-item>a{border-radius:var(--radius);padding-left:.5rem;padding-right:.5rem}.dropmenu-nav>.nav-secondary>.nav-item>a:after{bottom:-1px;left:1rem;opacity:0;right:1rem}.dropmenu-nav>.nav-secondary>.nav-item>.active:after{left:.5rem;opacity:1;right:.5rem;transition-duration:.15s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1)}.dropmenu-title{font-size:.75rem;font-weight:700;line-height:1rem;margin-bottom:-.5rem;padding:.75rem;--tw-text-opacity:1;color:rgba(var(--color-gray-500-rgb),var(--tw-text-opacity,1))}.dropmenu-list{min-height:0;overflow-x:hidden;overflow-y:auto;padding:.5rem .75rem}.dropmenu.loading>*{opacity:0}.dropmenu-item .tree-item-inner{border-radius:var(--radius);cursor:pointer;transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1)}.dropmenu-item.is-item.active>.tree-item-inner{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-50-rgb),var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgba(var(--color-primary-500-rgb),var(--tw-text-opacity,1))}.tree-item-inner.is-link:hover{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-500-rgb),var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgba(var(--color-canvas-rgb),var(--tw-text-opacity,1))}.tree-item-inner.is-link:hover .item-content,.tree-item-inner.is-link:hover .item-trailing-icon,.tree-item-inner.is-link:hover .label{color:inherit}.tree-item-inner.is-toggle:hover{--tw-bg-opacity:1;background-color:rgba(var(--color-gray-100-rgb),var(--tw-bg-opacity,1))}.dropmenu-item+.tree-item{margin-top:.125rem}.dropmenu-item .is-match{font-weight:700;text-decoration-line:underline}.dropmenu-item .item-title,.dropmenu-item .label{overflow:hidden;white-space:nowrap}.dropmenu-item .item-content{padding-left:.375rem;padding-right:.375rem}.dropmenu-item *+.item-content{padding-left:0}.tree-item-inner.is-toggle .item-title{opacity:.6}.tree-item-inner.is-toggle:hover .item-title{opacity:1}.dropmenu-item-check{align-items:center;display:flex;flex:1 1 auto;justify-content:flex-end;padding-right:.5rem}.dropmenu-item .nested-toggle-icon.is-empty{width:.25rem}.dropmenu-item .item-icon{margin-right:-.25rem}.card-list{--list-gap:.625rem;--list-count-per-row:1}.card-list,.card-list-item{padding:calc(var(--list-gap)/2)}.card-list-item{width:calc(100%/var(--list-count-per-row))}.card-grid{display:flex;flex-wrap:wrap}.card-grid .card{height:100%}:root{--form-control-border:var(--color-border-strong)}.checkbox-primary.disabled,.checkbox-primary.disabled>label,.checkbox-primary>input[type=checkbox]:disabled,.checkbox-primary>input[type=checkbox]:disabled+label,.radio-primary.disabled,.radio-primary.disabled>label,.radio-primary>input[type=radio],.radio-primary>input[type=radio]:disabled+label{filter:none!important}.checkbox-primary.disabled>label,.radio-primary.disabled>label{opacity:1}.checkbox-primary.disabled>label:before,.radio-primary.disabled>label:before{background-color:rgba(var(--color-inverse-rgb),.05);opacity:.5}.form-actions{gap:1rem;justify-content:center}.form-actions .btn{min-width:96px}.form-control-static{min-height:32px;padding-bottom:.375rem;padding-top:.375rem}:root{--zt-panel-form-max-width:1000px}.size-sm{--zt-panel-form-max-width:800px}.size-lg{--zt-panel-form-max-width:1200px}.panel-body>.container,.panel-heading>.container{max-width:var(--panel-container-width);min-width:0;padding-left:var(--panel-container-padding);padding-right:var(--panel-container-padding)}.panel-heading>.container{align-items:center;display:flex;flex-direction:row;flex-wrap:nowrap;gap:1rem;justify-content:space-between;min-height:48px}.panel-form{border-radius:var(--radius-md);margin-bottom:1rem;margin-left:auto;margin-right:auto;max-width:var(--zt-panel-form-max-width);min-width:var(--zt-panel-form-min-width);overflow:visible;--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1));padding-bottom:1rem;padding-left:1rem;padding-right:1rem;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.panel-form .form-actions{background-color:rgba(var(--color-canvas-rgb),.8);bottom:0;padding-bottom:1rem;padding-top:1rem;position:sticky;z-index:3;--tw-backdrop-blur:blur(8px);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.panel-form .form-grid{margin-left:calc(0px - var(--form-grid-gap-y-half));margin-right:calc(0px - var(--form-grid-gap-y-half));padding-bottom:0}.panel-form-toolbar{padding-left:var(--form-grid-gap-x-half);padding-right:var(--form-grid-gap-x-half);width:100%}.panel-form-toolbar>.toolbar{gap:1rem;padding-bottom:.75rem;padding-top:.75rem}.panel-form-divider{margin-bottom:.75rem;margin-top:1rem;padding-left:var(--form-grid-gap-x-half);padding-right:var(--form-grid-gap-x-half);width:100%}.panel-form-divider:before{background-color:rgba(var(--color-border-rgb),.7);display:block;height:1px;--tw-content:"";content:var(--tw-content)}.is-full .btn-full-form,.is-lite .btn-lite-form{z-index:1;--tw-bg-opacity:1;background-color:rgba(var(--color-primary-50-rgb),var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgba(var(--color-primary-500-rgb),var(--tw-text-opacity,1));--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-primary-300-rgb),var(--tw-ring-opacity,1))}.btn-toggle-fold:after{content:attr(data-expand-text)}.show-fold-items .btn-toggle-fold:after{content:attr(data-collapse-text)}.is-foldable,.is-full .full\:hidden,.is-full .lite\:visible,.is-full .panel-form-divider,.is-full .panel-form-toolbar,.is-lite .full\:visible,.is-lite .lite\:hidden,.no-foldable-items .btn-toggle-fold{display:none}.is-foldable.is-pinned,.is-full .full\:visible,.is-full .is-foldable,.is-full .lite\:hidden,.is-lite .full\:hidden,.is-lite .lite\:visible,.show-fold-items .is-foldable{display:block}.is-full .full\:w-1\/2,.is-lite .lite\:w-1\/2{width:50%}.is-full .full\:w-1\/3,.is-lite .lite\:w-1\/3{width:33.333333%}.is-full .full\:w-2\/3,.is-lite .lite\:w-2\/3{width:66.666667%}.is-full .full\:w-1\/4,.is-lite .lite\:w-1\/4{width:25%}.is-full .full\:w-2\/4,.is-lite .lite\:w-2\/4{width:50%}.is-full .full\:w-3\/4,.is-lite .lite\:w-3\/4{width:75%}.is-full .full\:w-1\/5,.is-lite .lite\:w-1\/5{width:20%}.is-full .full\:w-2\/5,.is-lite .lite\:w-2\/5{width:40%}.is-full .full\:w-3\/5,.is-lite .lite\:w-3\/5{width:60%}.is-full .full\:w-4\/5,.is-lite .lite\:w-4\/5{width:80%}.is-full .full\:w-1\/6,.is-lite .lite\:w-1\/6{width:16.666667%}.is-full .full\:w-2\/6,.is-lite .lite\:w-2\/6{width:33.333333%}.is-full .full\:w-3\/6,.is-lite .lite\:w-3\/6{width:50%}.is-full .full\:w-4\/6,.is-lite .lite\:w-4\/6{width:66.666667%}.is-full .full\:w-5\/6,.is-lite .lite\:w-5\/6{width:83.333333%}.is-full .full\:w-full,.is-lite .lite\:w-full{width:100%}.page-form{--panel-container-width:960px;--panel-container-padding:20px;--zt-panel-form-max-width:1200px;--zt-panel-form-min-width:1040px;padding-left:0;padding-right:0;--tw-shadow:0 1px 2px 0 rgba(0,0,0,.04),0 0 2px -1px rgba(0,0,0,.01);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color),0 0 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.page-form .panel-heading{border-bottom-width:1px;--tw-border-opacity:0.7;padding:0}.page-form .panel-title{font-size:1rem;line-height:1.5rem}@media (max-width:1240px){.page-form{--zt-panel-form-max-width:1100px}}@media (max-width:1110px){.page-form{--zt-panel-form-max-width:1040px}}.modal-body>.page-form{margin:-1.5rem -2rem!important;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.modal-body>.page-form>.panel-heading{border-top-left-radius:var(--radius);border-top-right-radius:var(--radius);position:sticky;top:-1.25rem;z-index:2;--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1));padding-bottom:.375rem;padding-top:.375rem}.modal-body>.panel-form .form-actions{bottom:-1.5rem!important;padding-bottom:1.5rem;padding-top:1.5rem}.gantt-container .gantt_message_area{display:none}.gantt-container .gantt_grid_head_owner_id{text-align:left}.gantt-container .gantt_grid_head_cell.gantt_grid_head_text{overflow:visible}.gantt-container .gantt_grid_head_cell,.gantt_scale_cell{color:#000!important}.gantt-container .gantt_grid_scale,.gantt_task_scale,.gantt_task_vscroll{background-color:#f2f7ff}.gantt-container .gantt_row{cursor:pointer}.gantt-container .gantt_row>div:first-child .gantt_tree_content{color:#3c4353}.gantt-container .gantt_row_task:hover .submitBtn{display:inline-block}.gantt-container .gantt_link_arrow_right{border-left-color:#2196f3}.gantt-container .gantt_link_arrow_left{border-right-color:#2196f3}.gantt-container .gantt_tree_content table{width:100%}.gantt-container .gantt_tree_content table td{padding:0!important}.gantt-container .gantt_tree_content{color:#838a9d}.gantt-container .gantt_task_content .icon-seal,.gantt-container .gantt_task_content span.task-label,.gantt_task_content span.label-pri{display:none}.gantt-container .gantt_task_line{overflow:visible}.gantt-container .gantt_task_line.gantt_selected{box-shadow:0 1px 1px rgba(0,0,0,.05),0 2px 6px 0 rgba(0,0,0,.045)}.gantt-container .gantt_task_line.gantt_task_inline_color{border:0}.gantt-container .gantt_task_link .gantt_line_wrapper div{background-color:#2196f3}.gantt-container .gantt_task_link.start_to_start .gantt_line_wrapper div{background-color:#dd55ea}.gantt-container .gantt_task_link.start_to_start:hover .gantt_line_wrapper div{box-shadow:0 0 5px 0 #dd55ea}.gantt-container .gantt_task_link.start_to_start .gantt_link_arrow_right{border-left-color:#dd55ea}.gantt-container .gantt_task_link.finish_to_start .gantt_line_wrapper div{background-color:#7576ba}.gantt-container .gantt_task_link.finish_to_start:hover .gantt_line_wrapper div{box-shadow:0 0 5px 0 #7576ba}.gantt-container .gantt_task_link.finish_to_start .gantt_link_arrow_right{border-left-color:#7576ba}.gantt-container .gantt_task_link.finish_to_finish .gantt_line_wrapper div{background-color:#55d822}.gantt-container .gantt_task_link.finish_to_finish:hover .gantt_line_wrapper div{box-shadow:0 0 5px 0 #55d822}.gantt-container .gantt_task_link.finish_to_finish .gantt_link_arrow_left{border-right-color:#55d822}.gantt-container .gantt_task_link.start_to_finish .gantt_line_wrapper div{background-color:#975000}.gantt-container .gantt_task_link.start_to_finish:hover .gantt_line_wrapper div{box-shadow:0 0 5px 0 #975000}.gantt-container .gantt_task_link.start_to_finish .gantt_link_arrow_left{border-right-color:#975000}.gantt-container .gantt_critical_link .gantt_line_wrapper>div{background-color:#e63030!important}.gantt-container .gantt_critical_link.finish_to_start .gantt_link_arrow_right,.gantt-container .gantt_critical_link.start_to_start .gantt_link_arrow_right{border-left-color:#e63030!important}.gantt-container .gantt_critical_link.finish_to_finish .gantt_link_arrow_left,.gantt-container .gantt_critical_link.start_to_finish .gantt_link_arrow_left{border-right-color:#e63030!important}.gantt-container .gantt_critical_task{background:#e63030!important;border-color:#9d3a3a!important}.gantt-container .gantt_marker .gantt_marker_content{background-color:#f51e1e;left:-15px}.gantt-container .submitBtn{display:none}.gantt-container .editDeadline{color:#fff!important;display:none;line-height:normal!important;padding:2px 6px}.gantt-container td:hover>.editDeadline{display:inline-block!important}.gantt-container .icon-confirm{color:#18a6fd;font-size:18px}.gantt-container .icon-seal{font-size:18px}.gantt-container div.delayed{background:#ffebeb;color:#fb2b2b}.gantt-container [class*=" pri-"]{max-width:unset}.dropdown.popover{display:flex;flex-direction:column;position:absolute;z-index:1200}.dropdown.show{display:flex}.dropdown-menu{display:none;--menu-min-width:7rem;--menu-max-width:20rem}.dropdown-menu.show,.menu-wrapper>.dropdown-menu,.show>.dropdown-menu{display:block}.dropdown>.dropdown-menu,.menu-wrapper .dropdown-menu{position:relative}.popup .popup.search-menu{background-color:var(--menu-bg)}.show>.menu-wrapper{display:flex}.dropdown>.menu-wrapper{height:100%}.dropdown>.menu-wrapper .menu-wrapper{position:absolute}.dropdown>.menu-wrapper.is-tree .menu-wrapper{position:relative}.is-contextmenu .is-nested-show>a:not(:hover){--tw-bg-opacity:1;background-color:rgba(var(--color-primary-100-rgb),var(--tw-bg-opacity,1))}.is-contextmenu .menu-item.is-nested>.item-inner>.nested-toggle-icon{position:absolute;right:.25rem;top:.375rem}.is-contextmenu .menu-nested .menu-item>.item-inner{padding-left:.5rem;padding-right:1.25rem}.is-contextmenu .menu-nested .menu-item>.item-inner>.item-content{overflow:hidden}.dropdown>.arrow{--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1))}.global-search-panel li:not(.order-first):hover{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-500-rgb),var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgba(var(--color-canvas-rgb),var(--tw-text-opacity,1))}.global-search-panel li a{width:100%}.global-search-panel li{cursor:pointer}.img-cutter{background:var(--color-gray-100);border:1px solid #ddd;margin-bottom:20px;padding:10px}.img-cutter .canvas{margin:0 auto;max-width:100%;min-width:50px;position:relative}.img-cutter .cover{bottom:0;left:0;position:absolute;right:0;top:0;z-index:1}.img-cutter .controller{background:none;border:1px dashed hsla(0,0%,100%,.7);cursor:move;position:absolute;z-index:5}.img-cutter .control{background:#000;background:rgba(0,0,0,.6);border:1px solid hsla(0,0%,100%,.6);height:6px;position:absolute;width:6px}.img-cutter .control[data-type=left]{cursor:w-resize;left:-4px;margin-top:-3px;top:50%}.img-cutter .control[data-type=top]{cursor:n-resize;left:50%;margin-left:-3px;top:-4px}.img-cutter .control[data-type=right]{cursor:e-resize;margin-top:-3px;right:-4px;top:50%}.img-cutter .control[data-type=bottom]{bottom:-4px;cursor:s-resize;left:50%;margin-left:-3px}.img-cutter .control[data-type=top-left]{cursor:nw-resize;left:-4px;top:-4px}.img-cutter .control[data-type=top-right]{cursor:ne-resize;right:-4px;top:-4px}.img-cutter .control[data-type=bottom-left]{bottom:-4px;cursor:sw-resize;left:-4px}.img-cutter .control[data-type=bottom-right]{bottom:-4px;cursor:se-resize;right:-4px}.img-cutter .cliper{bottom:0;left:0;position:absolute;right:0;top:0;z-index:2}.messager-lite{border-radius:var(--radius-lg);min-width:160px;--tw-bg-opacity:1!important;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1))!important;padding:1rem 1.5rem;--tw-text-opacity:1!important;color:rgba(var(--color-fore-rgb),var(--tw-text-opacity,1))!important;--skin-ring:transparent!important;--skin-text:inherit!important;--skin-color:var(--color-gray-500)}.messager-lite .alert-icon{color:var(--skin-color);font-size:1.5rem;line-height:2rem}.messager-lite .alert-text{font-size:.875rem;font-weight:700;line-height:1.3rem}.messager-lite .toolbar{gap:.5rem;margin-left:2rem}.messager-lite .alert-content+.alert-close{margin-left:1.5rem}.messager-lite .toolbar .btn.ghost{--tw-text-opacity:1;color:rgba(var(--color-primary-500-rgb),var(--tw-text-opacity,1))}.modal-reconfirm .modal-body{font-size:14px;font-weight:700;padding:24px 32px}.modal-reconfirm .modal-footer{justify-content:center;padding:24px}.pick{align-items:center;display:flex;flex-direction:row;justify-content:flex-start;position:relative}.color-picker{justify-content:center}.pick>.text{align-items:center;display:flex;flex:1 1 auto;min-width:0;overflow:hidden;white-space:nowrap}.pick>.text>.placeholder{--tw-text-opacity:1;color:rgba(var(--color-placeholder-rgb),var(--tw-text-opacity,1))}.picker-deselect-btn{opacity:.6;transition-duration:.15s;transition-property:opacity,transform;transition-timing-function:cubic-bezier(.4,0,.2,1)}.picker-multi-selection{cursor:pointer;padding-right:.5rem;position:relative}.picker-multi-selection .picker-deselect-btn{bottom:0;left:0;position:absolute;right:0;top:0;--tw-scale-x:0;--tw-scale-y:0;background-color:rgba(var(--color-surface-rgb),.8);opacity:0}.picker-deselect-btn:hover,.picker-multi-selection .picker-deselect-btn,.picker-multi-selection:hover .picker-deselect-btn{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.picker-deselect-btn:hover,.picker-multi-selection:hover .picker-deselect-btn{--tw-scale-x:1;--tw-scale-y:1;opacity:1;--state-color:rgba(var(--color-surface-rgb),.9)}.pick-pri{flex-direction:row;justify-content:flex-start;position:relative}.pick-pri,.pick-pri>.text{align-items:center;display:flex}.pick-pri>.text{flex:1 1 auto;min-width:0;overflow:hidden;white-space:nowrap}.pick-pri .placeholder{--tw-text-opacity:1;color:rgba(var(--color-placeholder-rgb),var(--tw-text-opacity,1))}.pick-pri-list>.btn{justify-content:flex-start}.disabled.pick-pri,.disabled.pick-pri>*{filter:none}.pick-diff{border:none!important;box-shadow:none!important;outline:none!important;padding:0!important}.pick-diff .diff-picker-trigger{align-items:center;display:flex;gap:4px}.pick-diff .btn{gap:.25rem;min-width:32px;padding-left:.5rem;padding-right:.5rem}.pick-diff .switch-diff{padding:0}.pick-diff .switch-diff .icon{font-size:18px}.pick-diff-pop .diff-pop{display:flex;flex-direction:column;max-height:300px;min-width:136px;-webkit-user-select:none;-moz-user-select:none;user-select:none}.pick-diff-pop .diff-pop>menu{flex:1;overflow-y:auto}.pick-diff-pop .diff-pop-header{align-items:center;display:flex;justify-content:space-between;padding:8px 8px 2px}.pick-diff-pop .diff-pop-header>span{flex-shrink:0}.pick-diff-pop .diff-pop-footer{align-items:center;display:flex;justify-content:space-between;padding:2px 8px 8px}.pick-diff-pop .menu-item>a{justify-content:start}.pick-range-list{max-height:100%;overflow:auto;padding:.25rem .5rem}.pick-range-list-item,.pick-range-list-row{align-items:center;display:flex}.pick-range-list-item{height:1.75rem;justify-content:center;margin-bottom:.125rem;margin-top:.125rem;position:relative;width:1.75rem}.pick-range-list-item:hover{border-radius:var(--radius);outline-color:rgb(var(--color-border-strong-rgb));outline-style:solid;z-index:10}.pick-range-list-item.is-from,.pick-range-list-item.is-to{border-radius:var(--radius);--tw-bg-opacity:1;background-color:rgba(var(--color-primary-400-rgb),var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgba(var(--color-canvas-rgb),var(--tw-text-opacity,1))}.pick-range-list-item.is-in{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-100-rgb),var(--tw-bg-opacity,1))}.pick-range-list-item.has-small-text>.text{--tw-scale-x:.75;--tw-scale-y:.75}.pick-range-list-item.has-small-text:hover,.pick-range-list-item.has-small-text>.text{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.pick-range-list-item.has-small-text:hover{position:relative;z-index:10;--tw-scale-x:1.25;--tw-scale-y:1.25}.pick-range-list-item.is-col-end{margin-right:1rem}.pick-range-list-item.is-col-end:after{border-right-width:1px;bottom:-.125rem;display:block;position:absolute;right:-.5rem;top:-.125rem;--tw-content:"";content:var(--tw-content)}.search-form{--gutter-width:12px;padding-bottom:.5rem}.search-form-container{border-radius:var(--radius);min-height:116px;position:relative;--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1));--tw-shadow:0 3px 8px 0 rgba(0,0,0,.04),0 1px 2px -1px rgba(0,0,0,.01);--tw-shadow-colored:0 3px 8px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-border-rgb),var(--tw-ring-opacity,1))}.is-simple .search-form-container{min-height:56px}.search-form-field td{padding:.375rem}.search-form-field td.is-andOr,.search-form-field td.is-operator{width:5rem}.search-form-field td.is-condition{width:7rem}.search-form-field td.is-operator{width:5rem}[lang=en] .search-form-field td.is-operator{width:6rem}.search-form .sidebar-right.is-collapsed{margin-right:-.375rem}.is-simple .search-form-wrapper{display:flex}.is-simple .search-form-wrapper>.row{flex:1 1 auto}.is-simple .search-form-wrapper>.toolbar{flex:none;margin-top:0}zen-editor-menu-item,zen-editor-menu-item>.menu-item{align-items:center;color:#64758b!important;display:flex;height:26px;justify-content:center;margin:0!important;min-width:24px;padding-left:2px;padding-right:2px}zen-editor-menu-item>.menu-item:hover{background-color:var(--color-gray-200)!important;color:var(--color-primary-400)!important}zen-editor-menu-item>.menu-item.is-active{background-color:transparent!important;box-shadow:inset 0 0 0 1px var(--color-primary-300);color:var(--color-primary-400)!important}zen-editor-menu-item>.menu-item.is-active:hover{background-color:var(--color-gray-200)!important}zen-editor-menu-item>.menu-item.is-active:not(:hover){background-color:transparent!important}zen-editor-menu-item>.menu-item:has(.color).is-active,zen-editor-menu-item>.menu-item:has(.color):hover{background-color:transparent!important;box-shadow:inset 0 0 0 1px var(--color-primary-300)!important}.zen-editor-menu-submenu{background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1))!important;border-radius:var(--radius);border-style:none!important;--tw-bg-opacity:0.85;--tw-shadow:0 10px 25px -5px rgba(0,0,0,.2),0 4px 10px -6px rgba(0,0,0,.15);--tw-shadow-colored:0 10px 25px -5px var(--tw-shadow-color),0 4px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:rgba(var(--color-inverse-rgb),var(--tw-ring-opacity,1));--tw-ring-opacity:0.05;--tw-backdrop-blur:blur(16px);align-items:center;backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);display:flex;justify-content:center}.ci-bar_top,.ci-bold,.ci-code,.ci-combine_cells,.ci-font,.ci-heading,.ci-heading_h1,.ci-heading_h2,.ci-heading_h3,.ci-heading_h4,.ci-image_02,.ci-italic,.ci-link,.ci-list_ordered,.ci-list_unordered,.ci-paragraph,.ci-strikethrough,.ci-swatches_palette,.ci-table,.ci-text,.ci-underline,.ci-unlink,.ci-window_code_block{font-size:1em!important}.ci-swatches_palette:before{content:"\ea23";font-family:ZentaoIcon}.ci-font:before{content:"\ea20";font-family:ZentaoIcon}.ci-text:before{content:"\e929";font-family:ZentaoIcon}.ci-bold:before{content:"\e953";font-family:ZentaoIcon}.ci-italic:before{content:"\e955";font-family:ZentaoIcon}.ci-underline:before{content:"\ea2b";font-family:ZentaoIcon}.ci-strikethrough:before{content:"\ea2c";font-family:ZentaoIcon}.ci-link:before{content:"\e94d";font-family:ZentaoIcon}.ci-unlink:before{content:"\ea51";font-family:ZentaoIcon}.ci-heading:before{content:"\e954";font-family:ZentaoIcon}.ci-heading_h1:before{content:"\ea25";font-family:ZentaoIcon}.ci-heading_h2:before{content:"\ea26";font-family:ZentaoIcon}.ci-heading_h3:before{content:"\ea27";font-family:ZentaoIcon}.ci-heading_h4:before{content:"\ea28";font-family:ZentaoIcon}.ci-code:before{content:"\e990";font-family:ZentaoIcon}.ci-window_code_block:before{content:"\ea39";font-family:ZentaoIcon}.ci-list_unordered:before{content:"\e9a8";font-family:ZentaoIcon}.ci-list_ordered:before{content:"\e969";font-family:ZentaoIcon}.ci-image_02:before{content:"\e96c";font-family:ZentaoIcon}.ci-table:before{content:"\e96d";font-family:ZentaoIcon}.ci-combine_cells:before{content:"\ea48";font-family:ZentaoIcon}.is-active>.ci-combine_cells:before{content:"\ea47";font-family:ZentaoIcon}.ci-paragraph:before{content:"\ea50";font-family:ZentaoIcon}.ci-bar_top:before{content:"\e96b";font-family:ZentaoIcon}.is-active>.ci-bar_top:before{content:"\e972";font-family:ZentaoIcon}.zinbar [data-hint]{position:relative}.zinbar [data-hint]:after{background-color:rgba(var(--color-inverse-rgb),var(--tw-bg-opacity,1));border-top-left-radius:var(--radius-lg);border-top-right-radius:var(--radius-lg);bottom:100%;display:block;pointer-events:none;position:absolute;right:0;white-space:nowrap;z-index:50;--tw-bg-opacity:0.9;font-size:.75rem;line-height:1rem;padding:.125rem .25rem;--tw-text-opacity:1;color:rgba(var(--color-canvas-rgb),var(--tw-text-opacity,1));opacity:0;transition-duration:.15s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);--tw-content:attr(data-hint);content:var(--tw-content)}.zinbar [data-hint]:hover:after{opacity:1}.zin-perf-btn-list .text-danger{color:var(--color-danger-400)}.zinbar .state{transition-duration:.15s;transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1)}.zinbar .state:active{--tw-scale-x:1.05;--tw-scale-y:1.05}.zinbar .state:active,.zinbar.collapse{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.zinbar.collapse{--tw-translate-x:100%}.zinbar.collapse>div{pointer-events:none}.zinbar{--tw-translate-x:0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));transition-duration:.7s;transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1)}body[z-perf=danger]:before,body[z-perf=warning]:before{bottom:0;left:0;pointer-events:none;position:fixed;right:0;top:0;z-index:9990;--tw-border-opacity:1;border-color:rgba(var(--color-warning-600-rgb),var(--tw-border-opacity,1));font-size:.75rem;line-height:1rem;--tw-content:"";border-style:inset;border-width:12px 8px 8px;content:var(--tw-content)}body[z-perf=danger]:before{--tw-border-opacity:1;border-color:rgba(var(--color-danger-600-rgb),var(--tw-border-opacity,1))}body[z-perf=danger]:after,body[z-perf=warning]:after{font-size:.75rem;font-weight:700;left:0;line-height:1rem;line-height:1;pointer-events:none;position:fixed;right:0;text-align:center;top:0;z-index:9991;--tw-text-opacity:1;color:rgba(var(--color-white-rgb),var(--tw-text-opacity,1));--tw-content:attr(z-perf-message);content:var(--tw-content)}.card{border-radius:var(--radius);min-height:28px;position:relative;--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1));--tw-shadow:0 1px 2px 0 rgba(0,0,0,.04),0 0 2px -1px rgba(0,0,0,.01);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color),0 0 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:rgba(var(--color-border-rgb),var(--tw-ring-opacity,1));--tw-ring-opacity:0.05;transition-duration:.15s;transition-property:box-shadow,border,color,background-color;transition-timing-function:cubic-bezier(.4,0,.2,1)}.card:hover{--tw-shadow:0 2px 6px -1px rgba(0,0,0,.2),0 1px 4px -2px rgba(0,0,0,.15);--tw-shadow-colored:0 2px 6px -1px var(--tw-shadow-color),0 1px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.card-content,.card-footer,.card-header,.card-heading{padding:.25rem .5rem}.card-heading{align-items:center;display:flex;gap:.5rem}.card-icon{opacity:.5}.card-header{--tw-bg-opacity:1;background-color:rgba(var(--color-surface-rgb),var(--tw-bg-opacity,1))}.card-content{display:flex;flex-direction:column;gap:.25rem}.card-actions{position:absolute;right:.125rem;top:.125rem}.card-actions+.card-heading{padding-right:1.75rem}.card-subtitle{font-size:.75rem;line-height:1rem;--tw-text-opacity:1;color:rgba(var(--color-gray-500-rgb),var(--tw-text-opacity,1))}.card.selected{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-50-rgb),var(--tw-bg-opacity,1));--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-primary-400-rgb),var(--tw-ring-opacity,1))}.card-list{--list-gap:.625rem;--list-count-per-row:1}.card-list,.card-list-item{padding:calc(var(--list-gap)/2)}.card-list-item{width:calc(100%/var(--list-count-per-row))}.card-grid{display:flex;flex-wrap:wrap}.card-grid .card{height:100%}.contextmenu{display:none}.contextmenu.show{display:block}.contextmenu .popup .popup,.contextmenu.popup{position:absolute}.more,.more-vert{margin:.5rem;position:relative}.more,.more-vert,.more-vert:after,.more-vert:before,.more:after,.more:before{background-color:currentColor;border-radius:var(--radius-full);height:.125rem;width:.125rem}.more-vert:after,.more-vert:before,.more:after,.more:before{display:block;left:-5px;position:absolute;top:0;--tw-content:"";content:var(--tw-content)}.more-vert:after,.more:after{left:5px}.more-vert{--tw-rotate:90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.dashboard-blocks{position:relative}.dashboard-block-cell{position:absolute;transition-duration:.15s;transition-property:left,top;transition-timing-function:cubic-bezier(.4,0,.2,1)}.dashboard-block{border-radius:var(--radius);bottom:.5rem;left:.5rem;position:absolute;right:.5rem;top:.5rem;--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1));transition-duration:.15s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1)}.dashboard-block.is-dragging{opacity:0;z-index:1600}.dashboard-block-header{align-items:center;border-top-left-radius:var(--radius);border-top-right-radius:var(--radius);display:flex;flex-direction:row;justify-content:space-between;left:0;padding:.75rem;pointer-events:none;position:absolute;right:0;top:0;z-index:10}.dashboard-block-header>*{pointer-events:auto}.dashboard-block-title{font-size:.875rem;font-weight:700;line-height:1.3rem}.dashboard-block-body{bottom:0;left:0;position:absolute;right:0;top:0}.dashboard-block-body>.panel{display:flex;flex-direction:column;height:100%;width:100%;--tw-shadow:0px 6px 16px rgba(202,215,235,.25)}.dashboard-block-body .panel-heading{cursor:move;flex:none}.dashboard-block-body .panel-body{flex:1 1 auto;overflow-y:auto}.has-more-menu>.dashboard-block-body .panel-heading{padding-right:3rem}.dashboard-block-body .panel-title{font-size:.875rem;height:2rem;line-height:1.3rem}.dashboard-block-actions .btn{opacity:.6}.dashboard-block-actions .btn:hover{opacity:1}.dashboard-drop-shadow{position:absolute;transition-duration:.15s;transition-property:left,top;transition-timing-function:cubic-bezier(.4,0,.2,1)}.dashboard-drop-shadow:before{background-color:rgba(var(--color-inverse-rgb),.05);border-radius:var(--radius);bottom:.5rem;left:.5rem;position:absolute;right:.5rem;top:.5rem;--tw-shadow:inset 0 2px 4px 0 rgba(0,0,0,.05);--tw-shadow-colored:inset 0 2px 4px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-content:"";content:var(--tw-content)}:root{--dtable-checked-bg:var(--color-warning-50);--dtable-checked-bg-hover:var(--color-warning-100);--dtable-checked-border:var(--color-border-strong)}.dtable-cell.is-checked,.dtable-striped .dtable-cell.is-odd-row.is-checked{background-color:var(--dtable-checked-bg)}.checkbox-primary.dtable-checkbox{margin-right:-.375rem}.dtable-checkbox{order:-5}.dtable-hover-col .dtable-cell.is-hover-col.is-checked,.dtable-hover-row .dtable-cell.is-hover-row.is-checked{background-color:var(--dtable-checked-bg-hover)}.dtable-cell.is-checked{--dtable-border-color:var(--dtable-checked-border)}.dtable-check-info{flex-shrink:1;margin-right:.5rem;overflow:hidden;white-space:nowrap}:root{--toggle-icon-size:calc(var(--font-size-root)*3/4 + 1px)}.toggle-icon,.toggle-icon-collapse,.toggle-icon-expand{border-color:currentColor;border-width:1px;display:block;opacity:.5;position:relative}.toggle-icon-collapse:hover,.toggle-icon-expand:hover,.toggle-icon:hover{opacity:.9}.toggle-icon,.toggle-icon-collapse,.toggle-icon-expand{border-radius:inherit;height:var(--toggle-icon-size);width:var(--toggle-icon-size)}.is-collapsed .toggle-icon:after,.is-collapsed .toggle-icon:before,.is-expanded .toggle-icon:before,.toggle-icon-collapse:after,.toggle-icon-collapse:before,.toggle-icon-expand:before{background-color:currentColor;content:" ";display:block;height:1px;left:2px;position:absolute;right:2px;top:calc((var(--toggle-icon-size) - 3px)/2)}.is-collapsed .toggle-icon:after,.toggle-icon-collapse:after{--tw-rotate:90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}:root{--dtable-nt-size:calc(var(--font-size-root)*3/4 + 1px)}.dtable-nested-indent{flex:none;margin-right:-.25rem;order:-100}.dtable-nested-toggle{align-items:center;border-radius:var(--radius-sm);display:flex;flex:none;height:1.25rem;justify-content:center;margin-left:-.25rem;order:-6;width:1.25rem}.dtable-nested-toggle.is-no-child{margin-right:-.25rem;opacity:0;pointer-events:none}.dtable-child-label{order:-5}.dtable-header-group{align-items:center;background:var(--dtable-header-bg);cursor:default;display:flex;justify-content:center;left:0;position:absolute;top:1px;z-index:30}.dtable-bordered .dtable-header-group{border-bottom:1px solid var(--dtable-border-color);border-left:1px solid var(--dtable-border-color)}.dtable-header-as-group{contain:style;content-visibility:visible;overflow:visible!important}.dtable-sorting{cursor:move}.dtable-cell.is-sorting-from{background-color:var(--dtable-bg);z-index:20}.dtable-cell.is-sorting-from:before{border-top-width:1px}.dtable-sorting .dtable-cell.is-sorting-after{--tw-translate-y:-100%}.dtable-sorting .dtable-cell.is-sorting-after,.dtable-sorting .dtable-cell.is-sorting-before{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.dtable-sorting .dtable-cell.is-sorting-before{--tw-translate-y:100%}.dtable-cell.is-sorting-before:before,.dtable-cell.is-sorting-from:before{border-bottom-width:1px;border-top-width:1px}.dtable{--dtable-bg:var(--color-canvas);--dtable-striped-bg:var(--color-gray-50);--dtable-hover-bg:rgba(var(--color-primary-500-rgb),.05);--dtable-header-bg:var(--color-surface);--dtable-footer-bg:var(--color-surface);--dtable-border-color:var(--color-border);--dtable-sorter-size:0.3125rem}.dtable{position:relative;--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1))}.dtable.no-animation *{transition-property:none!important}.dtable-block{overflow:hidden;position:absolute;width:100%}.dtable-header{background-color:var(--dtable-header-bg);border-top-left-radius:inherit;border-top-right-radius:inherit}.dtable-body{overflow:hidden}.dtable-cells{background-color:var(--dtable-bg);height:100%;position:absolute;z-index:0}.dtable-cells-container{height:100%;position:absolute;width:100%}.dtable-header .dtable-cells{background-color:var(--dtable-header-bg)}.dtable-cells.dtable-fixed-left,.dtable-cells.dtable-fixed-right{z-index:10}.dtable-cell{position:absolute;transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,transform;transition-timing-function:cubic-bezier(.4,0,.2,1)}.dtable-cell:after,.dtable-cell:before{bottom:0;content:"";left:0;opacity:0;pointer-events:none;position:absolute;right:0;top:-1px;z-index:2}.dtable-cell:before{border-bottom-width:1px;border-color:var(--dtable-border-color);opacity:1}.dtable-header-cell{align-items:center;display:flex;font-weight:700}.dtable-header-cell:after,.dtable-header-cell:before{top:0}.dtable-cell-content{align-items:center;display:flex;gap:.25rem;height:100%;overflow:hidden;padding-left:.75rem;padding-right:.75rem;position:relative;white-space:nowrap;width:100%;z-index:5}.dtable-body .dtable-cell.is-last-row:before{border-bottom-width:0}.dtable-footer{align-items:center;background-color:var(--dtable-footer-bg);border-bottom-left-radius:inherit;border-bottom-right-radius:inherit;border-color:var(--dtable-border-color);border-top-width:1px;display:flex;padding-left:.75rem;padding-right:.75rem;position:absolute;width:100%;z-index:10}.dtable-empty-tip{align-items:center;display:flex;height:100%;justify-content:center}.dtable .scrollbar{z-index:20}.dtable-header{transition-duration:1s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1)}.dtable-scrolled-down .dtable-header{border-bottom-color:rgba(var(--color-inverse-rgb),.15);border-bottom-width:1px}.dtable-has-scroll-y:not(.dtable-scrolled-bottom) .dtable-footer{border-top-color:rgba(var(--color-inverse-rgb),.15);border-top-width:1px}.dtable-scroll-shadow{background-image:linear-gradient(90deg,rgba(0,0,0,.03),transparent),linear-gradient(90deg,rgba(0,0,0,.03),transparent 50%);opacity:0;pointer-events:none;position:absolute;top:0;transition-duration:1s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);width:8px;z-index:20}.dtable:hover .dtable-scroll-shadow{opacity:1}.dtable-scroll-shadow.is-right{margin-left:-7px;--tw-rotate:180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.dtable-scroll-shadow.is-left,.dtable-scrolled-end .dtable-scroll-shadow.is-right{visibility:hidden}.dtable-scroll-shadow.is-right,.dtable-scrolled-right .dtable-scroll-shadow.is-left{visibility:visible}.scrollbar-hover:hover .scrollbar{opacity:0}.scrollbar-hover .dtable-body:hover~.scrollbar{opacity:var(--scrollbar-opacity)}.dtable-sort{display:inline-flex;height:calc(var(--dtable-sorter-size)*12/5);margin-left:.25rem;opacity:.8;position:relative}.dtable-cell:hover .dtable-sort{opacity:1}.dtable-sort:after,.dtable-sort:before{border-color:transparent;border-style:solid;height:0;left:0;opacity:.4;position:absolute;width:0;--tw-content:"";border-width:var(--dtable-sorter-size);content:var(--tw-content)}.dtable-sort:before{border-bottom-color:currentColor;border-top-width:0;top:0}.dtable-sort:after{border-bottom-width:0;border-top-color:currentColor;bottom:0}.dtable-sort.dtable-sort-asc:before,.dtable-sort.dtable-sort-desc:after{opacity:.9}.dtable-sort-link{align-items:center;cursor:pointer;display:inline-flex}.dtable-cells.dtable-fixed-left:before,.dtable-cells.dtable-fixed-right:before{border-color:var(--dtable-border-color);content:"";height:100%;pointer-events:none;position:absolute;width:100%;z-index:5}.dtable-cells.dtable-fixed-left:before{border-right-width:1px;right:-1px}.dtable-cells.dtable-fixed-right:before{border-left-width:1px;left:0}.dtable-bordered:before{border-color:var(--dtable-border-color);border-radius:inherit;border-width:1px;bottom:0;content:"";display:block;left:0;pointer-events:none;position:absolute;right:0;top:0;z-index:15}.dtable-bordered .dtable-cell:before{border-width:1px;right:-1px}.dtable-cell.has-border-left:before{border-left-width:1px}.dtable-cell.has-border-right:before{border-right-width:1px;right:-1px}.dtable-striped .dtable-cell.is-odd-row{background-color:var(--dtable-striped-bg)}.dtable-hover-cell .dtable-cell:hover:after,.dtable-hover-col .dtable-cell.is-hover-col:before,.dtable-hover-row .dtable-body .dtable-cell.is-hover-row:before{background-color:var(--dtable-hover-bg)}.kanban,.kanban-list{--kanban-lane-name-width:20px;--kanban-col-width:280px;--kanban-cols-gap:8px;--kanban-lanes-gap:8px;--kanban-header-height:32px;--kanban-lane-height:auto;--kanban-lane-color:var(--color-primary-500);--kanban-link-color:var(--color-secondary-600)}.kanban{align-items:flex-start;display:flex;flex-direction:column;min-width:-moz-fit-content;min-width:fit-content;position:relative}.kanban-header{display:flex;flex-direction:row;height:var(--kanban-header-height)}.kanban.has-sub-cols .kanban-header{height:calc(var(--kanban-header-height)*2)}.kanban-header-lane-name{background-color:rgba(var(--color-fore-rgb),.05);flex:none;width:var(--kanban-lane-name-width)}.kanban-header-cols,.kanban-header-sub-cols{display:flex;flex:1 1 0%;flex-direction:row;gap:var(--kanban-cols-gap)}.kanban-header-sub-cols{border-top-width:2px;--tw-border-opacity:1;border-color:rgba(var(--color-canvas-rgb),var(--tw-border-opacity,1))}.kanban-header-col{align-items:center;border-bottom-width:1px;display:flex;flex:1 1 0%;flex-direction:column;height:100%;width:var(--kanban-col-width)}.kanban-header-col.has-subs{width:auto}.kanban-header-col-wrapper{align-items:center;display:flex;flex:1 1 0%;flex-direction:row;position:relative;width:100%;--tw-bg-opacity:1;background-color:rgba(var(--color-surface-rgb),var(--tw-bg-opacity,1));padding-left:3.5rem;padding-right:3.5rem}.kanban-header-col-wrapper.is-align-left{justify-content:flex-start;padding-left:.5rem}.kanban-header-col-wrapper.is-align-left>.kanban-header-title{justify-content:flex-start}.kanban-header-title{align-items:center;display:flex;flex:1 1 auto;flex-direction:row;justify-content:center;overflow:hidden}.kanban-header-title>.as-title{color:var(--kanban-col-color);font-weight:700;overflow:hidden;white-space:nowrap}.kanban-header-col-actions{bottom:.25rem;position:absolute;right:.25rem;top:.25rem}.kanban-header-col-actions>.btn{opacity:.6}.kanban-header-col-actions>.btn:hover{opacity:1}.kanban-body{display:flex;flex-direction:column;gap:var(--kanban-lanes-gap)}.kanban-lane{display:flex;flex-direction:row;height:var(--kanban-lane-height);min-height:96px}.kanban-lane-name{align-items:center;background-color:var(--kanban-lane-color);display:flex;justify-content:center;width:var(--kanban-lane-name-width);--tw-text-opacity:1;color:rgba(var(--color-white-rgb),var(--tw-text-opacity,1));writing-mode:vertical-rl}.kanban-lane-actions,.kanban-lane-name{flex:none;position:relative}.kanban-lane.is-first .kanban-lane-actions{margin-top:calc(4px - var(--kanban-header-height))}.has-sub-cols .kanban-lane.is-first .kanban-lane-actions{margin-top:calc(4px - var(--kanban-header-height)*2)}.kanban-lane-actions>.btn.square{width:var(--kanban-lane-name-width)}.kanban-lane-title{align-items:center;display:flex;flex:1 1 auto;justify-content:center;overflow:hidden;white-space:nowrap}.kanban-lane-cols{display:flex;flex-direction:row;gap:var(--kanban-cols-gap)}.kanban-lane-col{background-color:rgba(var(--color-inverse-rgb),.05);display:flex;flex-direction:column;height:100%;width:var(--kanban-col-width)}.kanban-header-col,.kanban-lane-col{margin-left:calc(var(--kanban-col-gap-left) - var(--kanban-cols-gap));margin-right:calc(var(--kanban-col-gap-right) - var(--kanban-cols-gap))}.kanban-col-content{position:relative;z-index:5}.kanban-lane.is-first>.kanban-lane-name:before{background-color:var(--kanban-lane-color);bottom:100%;display:block;height:var(--kanban-header-height);left:0;position:absolute;right:0;--tw-content:"";content:var(--tw-content)}.kanban.has-sub-cols .kanban-lane.is-first>.kanban-lane-name:before{height:calc(var(--kanban-header-height)*2)}.kanban-lane{margin-bottom:calc(var(--kanban-col-gap-bottom) - var(--kanban-lanes-gap));margin-top:calc(var(--kanban-col-gap-top) - var(--kanban-lanes-gap))}.kanban-items{flex:1 1 auto;overflow:auto;scrollbar-gutter:both-edges stable}.kanban-lane.is-auto-height .kanban-items{scrollbar-gutter:auto}.kanban-item{cursor:default}.kanban-item .card-actions{z-index:5}.kanban-heading{width:100%}.kanban-heading .listitem{height:2.25rem}.kanban-heading .item-title{font-weight:700}.kanban.has-dragging{cursor:move}.kanban-item.is-dragging{cursor:move;opacity:.1}.kanban-sticky .kanban-header{position:sticky;top:0;z-index:10;--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1))}.kanban-sticky .kanban-header.is-pinned{border-bottom-color:rgba(var(--color-inverse-rgb),.15);border-bottom-width:1px;z-index:20;--tw-shadow:0 1px 2px 0 rgba(0,0,0,.04),0 0 2px -1px rgba(0,0,0,.01);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color),0 0 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.kanban-sticky .kanban-lane-name{left:0;position:sticky;z-index:21}.kanban-region{border-radius:var(--radius);min-width:-moz-fit-content;min-width:fit-content;--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1));padding:.75rem;--tw-shadow:0 3px 8px 0 rgba(0,0,0,.04),0 1px 2px -1px rgba(0,0,0,.01);--tw-shadow-colored:0 3px 8px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.kanban-region>.kanban+.kanban{margin-top:.75rem}.kanban-region.has-heading{padding-top:0}.kanban-heading>.listitem{left:.75rem;position:sticky;width:calc(var(--kanban-list-width) - 24px)}.kanban-list{display:flex;flex-direction:column;gap:.75rem;height:100vh;overflow:auto;position:relative;scrollbar-gutter:stable}.kanban-list.is-moving{cursor:grabbing}.kanban-items.is-dropping{position:relative}.kanban-item.is-dropping{position:relative;transition-duration:.15s;transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1)}.kanban-item.is-dropping:after,.kanban-items.is-dropping>.card-list:after{background-color:rgba(var(--color-warning-500-rgb),.5);border-radius:var(--radius-full);display:block;height:.25rem;--tw-content:"";content:var(--tw-content)}.kanban-item.is-dropping:after{left:.25rem;position:absolute;right:.25rem;top:-.25rem}.kanban-item.is-dropping[z-drop-side=before]{--tw-translate-y:0.25rem}.kanban-item.is-dropping[z-drop-side=after],.kanban-item.is-dropping[z-drop-side=before]{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.kanban-item.is-dropping[z-drop-side=after]{--tw-translate-y:-0.25rem}.kanban-item.is-dropping[z-drop-side=after]:after{bottom:-.25rem;top:auto}.kanban-links{bottom:0;left:0;pointer-events:none;position:absolute;right:0;top:0;z-index:5}.kanban-list>.kanban-links{overflow:visible;z-index:11}.kanban-link{align-items:center;color:var(--kanban-link-color);display:flex;justify-content:center;position:absolute}.kanban-link>svg{position:absolute}.kanban-link-text{border-radius:var(--radius);height:1em;line-height:1;padding-left:.125rem;padding-right:.125rem;pointer-events:auto;position:relative;text-align:center;white-space:nowrap}.kanban-link-start-point{height:.5rem;width:.5rem;--tw-translate-x:-0.25rem;--tw-translate-y:-0.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.kanban-link-start-point,.kanban-link-start-point:before{background-color:currentColor;border-radius:var(--radius-full);position:absolute}.kanban-link-start-point:before{bottom:-.25rem;display:block;left:-.25rem;opacity:.2;right:-.25rem;top:-.25rem;--tw-content:"";content:var(--tw-content)}.kanban-link path{pointer-events:auto}.kanban-link path+path{opacity:.6}.kanban-link.is-hover path+path{opacity:1;stroke-width:calc(var(--kanban-link-weight)*1.5)}.kanban-link-delete-btn{pointer-events:auto;--tw-scale-x:.75;--tw-scale-y:.75;opacity:0;transition-duration:.15s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1)}.is-hover .kanban-link-delete-btn,.kanban-link-delete-btn{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.is-hover .kanban-link-delete-btn{--tw-scale-x:1;--tw-scale-y:1;opacity:1}.is-adding-link{cursor:crosshair;-webkit-user-select:none;-moz-user-select:none;user-select:none}.kanban-link-editor{bottom:0;left:0;pointer-events:none;position:absolute;right:0;top:0;z-index:20}.kanban-link-editor-from,.kanban-link-editor-to{border-radius:var(--radius);--tw-shadow-color:rgb(var(--color-primary-500-rgb));--tw-shadow:var(--tw-shadow-colored);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-primary-500-rgb),var(--tw-ring-opacity,1))}.kanban-link-editor-from,.kanban-link-editor-point,.kanban-link-editor-to{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);position:absolute}.kanban-link-editor-point{height:.5rem;pointer-events:auto;width:.5rem;--tw-translate-x:-0.25rem;--tw-translate-y:-0.25rem;border-radius:var(--radius-full);cursor:move;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-bg-opacity:1;background-color:rgba(var(--color-primary-500-rgb),var(--tw-bg-opacity,1));opacity:.5;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-color:rgba(var(--color-primary-500-rgb),0.1);transition-duration:.15s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1)}.kanban-link-editor-point.is-left{left:0;top:50%}.kanban-link-editor-point.is-right{right:0;top:50%;--tw-translate-x:0.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.kanban-link-editor-point.is-top{left:50%;top:0}.kanban-link-editor-point.is-bottom{bottom:0;left:50%;--tw-translate-y:0.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.kanban-link-editor-point:hover{opacity:1;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(8px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:rgba(var(--color-primary-500-rgb),0.5)}.tab-pane{display:none}.tab-pane.active{display:block}.has-sorting-col{cursor:move;--dtable-sorting-col-color:var(--color-primary-300);--dtable-hover-bg:transparent}.has-sorting-col .dtable-col-splitter{display:none}.dtable-cell.is-sorting-col-move{transition-duration:.15s;transition-property:left;transition-timing-function:cubic-bezier(.4,0,.2,1)}.dtable-cell.is-sorting-from-col{transition-duration:.1s}.dtable-cell.is-sorting-from-col:after{background-color:var(--dtable-sorting-col-color)!important;opacity:.1!important}.dtable-cell.is-sorting-from-col:before{border-left:1px solid var(--dtable-sorting-col-color);border-right:1px solid var(--dtable-sorting-col-color)}.dtable-header-cell.is-sortable-col{cursor:move}.has-sorting-col .scrollbar.is-horz{opacity:var(--scrollbar-opacity)!important}.has-sorting-col .dtable-scroll-shadow{visibility:visible}:root{--dtable-col-splitter-width:7px;--dtable-col-splitter-color:var(--color-primary-500)}.dtable-cell.has-col-resizing:after,.dtable-cell.has-col-splitter:hover:after{background:var(--dtable-col-splitter-color);opacity:.05}.dtable-col-splitter{background:var(--dtable-col-splitter-color);border-radius:var(--radius-full);bottom:0;cursor:ew-resize;opacity:0;position:absolute;right:calc(var(--dtable-col-splitter-width)/-2);top:0;transition-duration:.15s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);width:var(--dtable-col-splitter-width);z-index:20}.dtable-cell.has-col-splitter:hover .dtable-col-splitter{opacity:.3}.dtable-cell.has-col-resizing .dtable-col-splitter,.dtable-cell.has-col-splitter .dtable-col-splitter:hover{opacity:.5}.dtable.has-col-resizing .dtable-cell.has-col-splitter:not(.has-col-resizing) .dtable-col-splitter,.dtable.has-col-resizing .dtable-cell.has-col-splitter:not(.has-col-resizing):after{opacity:0}.dtable-col-splitter:after,.dtable-col-splitter:before{content:" ";display:block;height:.5rem;left:50%;margin-top:-.25rem;position:absolute;top:50%;width:1px;--tw-bg-opacity:1;background-color:rgba(var(--color-white-rgb),var(--tw-bg-opacity,1))}.dtable-col-splitter:before{margin-left:-1px}.dtable-col-splitter:after{margin-left:1px}.dtable.has-col-resizing{--dtable-hover-bg:transparent}.dtable.has-col-resizing,.has-col-resizing .dtable-header-cell{cursor:ew-resize!important}.dtable-cell.is-col-resizing:before{border-right:1px solid var(--dtable-col-splitter-color)}.dtable-cell.is-col-resizing:after{background:var(--dtable-col-splitter-color);opacity:.05}.has-col-resizing .scrollbar.is-horz{opacity:var(--scrollbar-opacity)!important}.dtable-cell.has-contextmenu-show:after{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-500-rgb),var(--tw-bg-opacity,1));opacity:.1}.dtable{--dtable-header-bg:var(--color-surface-light);--dtable-footer-bg:var(--color-surface-light);--dtable-border-color:var(--color-border-light);--dtable-checked-border:var(--color-border);--dtable-checked-bg:var(--color-primary-50);--dtable-checked-bg-hover:var(--color-primary-100);--dtable-hover-bg:rgba(var(--color-gray-500-rgb),.05);--dtable-link-color:var(--color-link);--dtable-link-hover-color:var(--color-link-hover);--dtable-link-visited-color:var(--color-link-visited)}.dtable-cell-content[style*="--color-link"]{--dtable-link-hover-color:var(--color-link);--dtable-link-visited-color:var(--color-link)}.dtable-body .dtable-cell a{--dtable-link-color:var(--color-link)}.dtable-body .dtable-cell a:not(.btn){color:var(--dtable-link-color)}.dtable-body .dtable-cell a:not(.btn):visited{color:var(--dtable-link-visited-color)}.dtable-body .dtable-cell a:not(.btn):hover{color:var(--dtable-link-hover-color)}.dtable .btn-avatar{border-radius:var(--radius-full);gap:.25rem;height:1.25rem;--tw-bg-opacity:1;background-color:rgba(var(--color-gray-100-rgb),var(--tw-bg-opacity,1));padding-left:0;padding-right:.5rem;--tw-ring-color:transparent}.dtable .btn-avatar:hover{--tw-shadow:0 3px 8px 0 rgba(0,0,0,.04),0 1px 2px -1px rgba(0,0,0,.01);--tw-shadow-colored:0 3px 8px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.dtable-nested-toggle{width:1rem}.dtable .toggle-icon{--toggle-icon-size:11px;border-radius:var(--radius);--tw-border-opacity:1;border-color:rgba(var(--color-gray-400-rgb),var(--tw-border-opacity,1))}.dtable .toggle-icon:after,.dtable .toggle-icon:before{--tw-bg-opacity:1;background-color:rgba(var(--color-gray-700-rgb),var(--tw-bg-opacity,1))}.dtable-footer>.toolbar{margin-right:.5rem}.dtable-header .dtable-cell[data-sort]>.dtable-cell-content>a:not(:hover){color:inherit}.dtable-assign-btn{align-items:center;border-radius:var(--radius-full);display:flex;flex-direction:row;height:1.25rem;padding-left:.375rem;padding-right:.375rem;--dtable-link-color:var(--color-fore)}.dtable-assign-btn:not(:hover){color:inherit}.dtable-assign-btn.is-me{--dtable-link-color:var(--color-warning-500)!important}.dtable-assign-btn:hover{--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1));--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-border-strong-rgb),var(--tw-ring-opacity,1))}.dtable-assign-btn>span{border-radius:var(--radius-full);line-height:20px;padding-left:.375rem;padding-right:.375rem}.dtable-assign-btn.is-unassigned>span{--tw-text-opacity:1;color:rgba(var(--color-gray-500-rgb),var(--tw-text-opacity,1));--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-border-strong-rgb),var(--tw-ring-opacity,1))}.dtable-assign-btn.is-unassigned:hover>span{background-color:inherit;color:inherit;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.dtable-assign-btn>.icon{opacity:0;transition-duration:.15s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1)}.dtable-assign-btn:not(.disabled):hover>.icon{opacity:1}.dtable-header .dtable-cell[data-type=assign]{padding-left:1.5rem}.dtable-cell-icon{order:-5}.dtable-custom-cell[data-type=control]{align-items:center;display:flex;justify-content:center;padding-left:.125rem;padding-right:.125rem;z-index:1}:root{--dtable-editing-color:var(--color-success-600)}.dtable-cell.is-editing:after{border-color:var(--dtable-editing-color);border-width:2px!important;opacity:1;z-index:20}.dtable-editing-input{height:100%;outline:2px solid transparent;outline-offset:2px;padding-left:.75rem;padding-right:.75rem;width:100%}:root{--dtable-selected-color:var(--color-success-500);--dtable-selected-bg:var(--color-success-50);--dtable-selecting-bg:var(--color-success-100);--dtable-highlight-color:var(--color-success-700)}.dtable-selectable{-webkit-user-select:none;-moz-user-select:none;user-select:none}.dtable-cell.is-select:after{border-color:var(--dtable-selected-color);border-width:1px;opacity:1;z-index:10}.dtable-cell.is-selecting{background:var(--dtable-selecting-bg)}.dtable-cell.is-selected{background:var(--dtable-selected-bg)}.dtable-cell.is-col-selected:after,.dtable-cell.is-row-selected[data-col=INDEX]:after{background-color:rgba(var(--color-inverse-rgb),.05);opacity:1}.dtable-cell.has-cell-selected{color:var(--dtable-highlight-color)}.dtable-cell.is-first-row.is-select:after{top:0}.dtable-cell.is-last-row.is-select:after{bottom:1px}.dtable-cell.is-first-in-row.is-select:after{left:1px}.dtable-cell.is-last-in-row.is-select:after{right:1px}.dtable-datagrid .dtable-cell[data-col=INDEX]{background:var(--dtable-header-bg)}.dtable-empty-tip{min-height:212px}.dtable-cell[data-type=actions] .btn>.icon{font-size:1rem;line-height:1.5rem}.menu.menu-dtable-actions.has-icons{align-items:center;display:flex;gap:.25rem;min-width:auto;--menu-icon-opacity:1}.menu.menu-dtable-actions.has-icons>.menu-item>a{padding-left:.25rem;padding-right:.25rem}.menu.menu-dtable-actions.has-icons>.menu-item>a>.icon-EMPTY,.menu.menu-dtable-actions.has-icons>.menu-item>a>.item-content{display:none}.menu.menu-dtable-actions.has-icons>.menu-item>a>.icon-EMPTY+.item-content,.menu.menu-dtable-actions.has-icons>.menu-item>a>.item-content:first-child{display:block}:root{--state-color:rgba(0,0,0,.03);--zt-page-bg:#f8f9fa;--zt-header-height:3rem;--zt-header-bg:var(--color-canvas);--zt-header-color:var(--color-fore);--zt-sidebar-width:160px;--zt-navbar-active-color:var(--color-primary-500)}body{background-color:var(--zt-page-bg)}.page-app{overflow:overlay}.container{min-width:1200px}#header{height:var(--zt-header-height);--tw-shadow:0 3px 8px 0 rgba(0,0,0,.04),0 1px 2px -1px rgba(0,0,0,.01);--tw-shadow-colored:0 3px 8px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color);background:var(--zt-header-bg);border-bottom:1px solid var(--zt-header-border,rgba(var(--color-inverse-rgb),.05));box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);color:var(--zt-header-color)}#header>.container{height:100%;position:relative}#heading{align-items:center;bottom:0;display:flex;gap:.25rem;left:1rem;position:absolute;top:0}#heading>.toolbar{margin-left:-.75rem}#heading .dropmenu-btn>.text{max-width:142px}#heading>[data-zui-dropmenu]+div .dropmenu-btn>.text,#heading>[data-zui-dropmenu]+div+div .dropmenu-btn>.text{max-width:78px}#navbar{align-items:center;display:flex;font-size:.875rem;height:100%;justify-content:center;line-height:1.3rem;--state-color:rgba(var(--color-primary-500-rgb),.05);--state-active-opacity:1;--state-active-color:rgba(var(--color-primary-500-rgb),.08)}#navbar>.nav{--nav-active-color:var(--zt-navbar-active-color,var(--color-current));--nav-item-padding:12px;--nav-divider-margin:8px;margin-left:var(--nav-offset-left)}#navbar>.nav>.nav-item>a{height:3rem;padding-left:var(--nav-item-padding);padding-right:var(--nav-item-padding)}#navbar>.nav>.nav-item>a:before{--tw-scale-x:1!important;--tw-scale-y:1!important;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)!important;--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color)!important;box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)!important}#navbar>.nav>.nav-item>a.active:before{background:var(--state-active-color)!important;opacity:1!important}#navbar>.nav>.divider{align-self:center;height:1.25rem;margin-left:var(--nav-divider-margin);margin-right:var(--nav-divider-margin);opacity:.2}#navbar>.nav.compact{font-size:.8125rem;line-height:1.25rem}#navbar>.nav.compact-extra{font-size:.75rem;line-height:1rem}#toolbar{align-items:center;bottom:0;display:flex;gap:.25rem;position:absolute;right:1rem;top:0}#main{min-height:100vh}#header+#main{min-height:calc(100vh - 3rem)}#main>.container{padding-left:1rem;padding-right:1rem;position:relative}@media (min-width:1400px){#header>.container,#main>.container,#mainNavbar>.container{padding-left:2.5rem;padding-right:2.5rem}#heading{left:2.5rem}#toolbar{right:2.5rem}}#mainNavbar{height:2.75rem;--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1))}#mainNavbar>.container{position:relative}#mainNavbar .nav{bottom:0;height:2.75rem;justify-content:center;left:0;position:absolute;right:0;top:0}#mainNavbar .nav-item{font-size:.875rem;line-height:1.3rem}#mainNavbar .nav-item>a{border-radius:var(--radius)}#mainMenu{gap:1rem;justify-content:space-between;padding-bottom:.75rem;padding-top:.75rem}#featureBar,#mainMenu{align-items:center;display:flex}#featureBar{flex:1 1 auto;gap:.5rem}#actionBar{gap:.5rem}#actionBar>.nav-divider{margin-left:-.25rem;margin-right:-.25rem}#mainContent{padding-top:.75rem}#mainMenu+#mainContent{padding-top:0}#mainContent.row{align-items:stretch;display:flex;gap:1rem;justify-content:space-between}#mainContent.row>*{flex:1 1 auto;min-width:0}#mainContainer.has-sidebar-left{--gutter-left-size:16px}#mainContainer.is-sidebar-left-collapsed{--gutter-left-size:0}.has-sidebar-animation.has-sidebar-left #mainMenu{transition-duration:.15s;transition-property:padding-left;transition-timing-function:cubic-bezier(.4,0,.2,1)}:root{--modal-radius:var(--radius);--avatar-bg:var(--color-gray-200)}.modal-alert .modal-footer{justify-content:center}.modal-dialog{--tw-bg-opacity:1}.modal-content,.modal-dialog{max-height:calc(100vh - 4rem)}.modal-body,.modal-footer,.modal-header{padding:1.5rem 2rem}.modal-header{padding-right:3rem}.modal-body+.modal-footer,.modal-header+.modal-actions+.modal-body,.modal-header+.modal-body{padding-top:1px}.modal-condensed .modal-body,.modal-condensed .modal-header{padding:1rem 1.25rem}.modal-condensed .modal-actions{top:.75rem}:root{--label-bg:var(--color-gray-100);--label-color:var(--color-gray-800)}.label[class$=-pale],.label[class*="-pale "]{--tw-bg-opacity:0.4;--tw-ring-opacity:0.4}.body-modal .panel-form,.modal-body>.panel-form{margin:0;padding:0}.modal-body>.panel-form>.panel-heading{padding-left:1px;padding-right:1px;padding-top:1px}.modal-body>.panel-form>.panel-body{padding:1px}.modal-body>.form{padding-top:1px}.modal .history,.modal .panel-body>.form{padding:0}:root{--article-p-space:0}.lane-col-join-with-above{position:relative}.lane-col-join-with-above:before{background-color:inherit;left:0;position:absolute;right:0;--tw-content:"";content:var(--tw-content);height:var(--kanban-col-gap-top,var(--kanban-lanes-gap));top:calc(0px - var(--kanban-col-gap-top, var(--kanban-lanes-gap)))}:root{--state-color:rgba(0,0,0,.05);--state-scale:.9;--opacity-disabled:.7;--opacity-muted:.5;--load-indicator-duration:300ms;--load-indicator-delay:.5s}.btn,.item>a,.state{cursor:pointer;position:relative}.btn:before,.item>a:before,.state:before{background:var(--state-color);border-radius:inherit;bottom:0;content:" ";display:block;left:0;opacity:0;pointer-events:none;position:absolute;right:0;top:0;transform:scale(var(--state-scale));transition-duration:.2s;transition-property:opacity,transform,box-shadow,background-color;transition-timing-function:cubic-bezier(.4,0,.2,1)}.btn.active:not(:hover,:focus-visible,:focus-within,:active):before,.item>a.active:not(:hover,:focus-visible,:focus-within,:active):before,.state.active:not(:hover,:focus-visible,:focus-within,:active):before{background:var(--state-active-color,var(--state-color));opacity:var(--state-active-opacity,0);--tw-scale-x:1;--tw-scale-y:1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-shadow:inset 0 2px 4px 0 rgba(0,0,0,.05);--tw-shadow-colored:inset 0 2px 4px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);transition-duration:.7s}.btn.selected:not(:hover,:focus-visible,:focus-within,:active):before,.item>a.selected:not(:hover,:focus-visible,:focus-within,:active):before,.state.selected:not(:hover,:focus-visible,:focus-within,:active):before{background:var(--state-selected-color,var(--state-scale));opacity:var(--state-selected-opacity,.1);--tw-scale-x:1;--tw-scale-y:1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.btn:focus-visible,.item>a:focus-visible,.state:focus-visible{outline:2px solid transparent;outline-offset:2px}.btn:active:before,.btn:focus-visible:before,.btn:hover:before,.item>a:active:before,.item>a:focus-visible:before,.item>a:hover:before,.state:active:before,.state:focus-visible:before,.state:hover:before{--tw-scale-x:1;--tw-scale-y:1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.btn:hover:before,.item>a:hover:before,.state:hover:before{opacity:var(--state-hover-opacity,1)}.btn:active:before,.item>a:active:before,.state:active:before{background:var(--state-pressed-color,var(--state-color));opacity:var(--state-pressed-opacity,.6);--tw-ring-color:var(--state-ring-color,currentColor);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);transition-duration:.7s}.btn:focus-visible:before,.item>a:focus-visible:before,.state:focus-visible:before{background:var(--state-focus-color,var(--state-color));opacity:var(--state-focus-opacity,1);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-focus-rgb),var(--tw-ring-opacity,1))}.btn.disabled:before,.btn[disabled]:before,.item>a.disabled:before,.item>a[disabled]:before,.state.disabled:before,.state[disabled]:before{display:none}.btn{--state-active-opacity:1}@-moz-document url-prefix(){.btn,:root{--state-active-opacity:0;--state-focus-opacity:0}}.disabled,.disabled *,[disabled],[disabled] *{cursor:not-allowed!important;opacity:var(--opacity-disabled);--tw-grayscale:grayscale(100%);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.load-indicator:after,.load-indicator:before{display:block;opacity:0;position:absolute;transition-delay:0s;transition-duration:.15s;transition-duration:var(--load-indicator-duration);transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);visibility:hidden}.load-indicator:before{align-items:center;background-color:rgba(var(--color-canvas-rgb),.7);border-radius:inherit;bottom:0;display:flex;font-size:.75rem;justify-content:center;left:0;line-height:1rem;right:0;top:0;z-index:99;--tw-content:attr(data-loading);content:var(--tw-content)}.load-indicator[data-loading]:before{padding-top:3.5rem}.load-indicator:after{border-color:transparent currentcolor currentcolor;border-radius:var(--radius-full);border-style:dotted;border-width:4px 3px 4px 4px;height:2rem;left:50%;margin-left:-1rem;margin-top:-1rem;top:50%;width:2rem;z-index:100;--tw-content:"";content:var(--tw-content)}.load-indicator.loading:after,.load-indicator.loading:before{opacity:1;transition-delay:var(--load-indicator-delay);visibility:visible}@keyframes -spin{to{transform:rotate(1turn)}}.load-indicator.loading:after{animation:-spin 1s linear infinite;opacity:.5}.events-none,.pointer-events-none{pointer-events:none}.events-auto,.pointer-events-auto{pointer-events:auto}.scroll-auto{scroll-behavior:auto}.scroll-smooth{scroll-behavior:smooth}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.select-text{-webkit-user-select:text;-moz-user-select:text;user-select:text}.select-all{-webkit-user-select:all;-moz-user-select:all;user-select:all}.select-auto{-webkit-user-select:auto;-moz-user-select:auto;user-select:auto}.cursor-auto{cursor:auto}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.cursor-wait{cursor:wait}.cursor-text{cursor:text}.cursor-move{cursor:move}.cursor-help{cursor:help}.cursor-not-allowed{cursor:not-allowed}.active\:opacity-100.active,.active\:opacity-100:active,.group.active .group-active\:opacity-100,.group:active .group-active\:opacity-100,.group:hover .group-hover\:opacity-100,.hover\:opacity-100:hover{opacity:1}.active\:opacity-0.active,.active\:opacity-0:active,.group.active .group-active\:opacity-0,.group:active .group-active\:opacity-0,.group:hover .group-hover\:opacity-0,.hover\:opacity-0:hover{opacity:0}.active\:text-primary.active,.active\:text-primary:active,.group.active .group-active\:text-primary,.group:active .group-active\:text-primary,.group:hover .group-hover\:text-primary,.hover\:text-primary:hover{--tw-text-opacity:1;color:rgba(var(--color-primary-500-rgb),var(--tw-text-opacity,1))}.active\:border-primary.active,.active\:border-primary:active,.group.active .group-active\:border-primary,.group:active .group-active\:border-primary,.group:hover .group-hover\:border-primary,.hover\:border-primary:hover{--tw-border-opacity:1;border-color:rgba(var(--color-primary-500-rgb),var(--tw-border-opacity,1))}.active\:primary-pale.active,.active\:primary-pale:active,.group.active .group-active\:primary-pale,.group:active .group-active\:primary-pale,.group:hover .group-hover\:primary-pale,.hover\:primary-pale:hover{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-50-rgb),var(--tw-bg-opacity,1))}.active\:primary.active,.active\:primary:active,.group.active .group-active\:primary,.group:active .group-active\:primary,.group:hover .group-hover\:primary,.hover\:primary:hover{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-500-rgb),var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgba(var(--color-canvas-rgb),var(--tw-text-opacity,1))}.active\:canvas.active,.active\:canvas:active,.group.active .group-active\:canvas,.group:active .group-active\:canvas,.group:hover .group-hover\:canvas,.hover\:canvas:hover{--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1))}.active\:font-bold.active,.active\:font-bold:active,.group.active .group-active\:font-bold,.group:active .group-active\:font-bold,.group:hover .group-hover\:font-bold,.hover\:font-bold:hover{font-weight:700}.active\:shadow.active,.active\:shadow:active,.group.active .group-active\:shadow,.group:active .group-active\:shadow,.group:hover .group-hover\:shadow,.hover\:shadow:hover{--tw-shadow:0 3px 8px 0 rgba(0,0,0,.04),0 1px 2px -1px rgba(0,0,0,.01);--tw-shadow-colored:0 3px 8px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.active\:shadow-lg.active,.active\:shadow-lg:active,.group.active .group-active\:shadow-lg,.group:active .group-active\:shadow-lg,.group:hover .group-hover\:shadow-lg,.hover\:shadow-lg:hover{--tw-shadow:0 5px 15px -3px rgba(0,0,0,.2),0 2px 6px -4px rgba(0,0,0,.15);--tw-shadow-colored:0 5px 15px -3px var(--tw-shadow-color),0 2px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.group:hover .group-hover\:block,.hover\:block:hover{display:block!important}.group:hover .group-hover\:flex,.hover\:flex:hover{display:flex!important}.group:hover .group-hover\:inline-flex,.hover\:inline-flex:hover{display:inline-flex!important}.group:hover .group-hover\:scale-110,.hover\:scale-110:hover{--tw-scale-x:1.1!important;--tw-scale-y:1.1!important}.group:hover .group-hover\:scale-110,.group:hover .group-hover\:scale-125,.hover\:scale-110:hover,.hover\:scale-125:hover{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.group:hover .group-hover\:scale-125,.hover\:scale-125:hover{--tw-scale-x:1.25!important;--tw-scale-y:1.25!important}.aspect-auto{aspect-ratio:auto}.aspect-square{aspect-ratio:1/1}.aspect-video{aspect-ratio:16/9}.container{width:100%}@media (min-width:1720px){.container{max-width:1720px}}.container{margin-left:auto;margin-right:auto}.popup{background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1));border-radius:var(--radius);--tw-bg-opacity:0.85;--tw-shadow:0 10px 25px -5px rgba(0,0,0,.2),0 4px 10px -6px rgba(0,0,0,.15);--tw-shadow-colored:0 10px 25px -5px var(--tw-shadow-color),0 4px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:rgba(var(--color-inverse-rgb),var(--tw-ring-opacity,1));--tw-ring-opacity:0.05;--tw-backdrop-blur:blur(16px);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.table-cell{display:table-cell}.table-row{display:table-row}.hidden{display:none!important}.pull-right{float:right}.pull-left{float:left}.clearfix:after{clear:both;content:"";display:block}.object-contain{-o-object-fit:contain;object-fit:contain}.object-cover{-o-object-fit:cover;object-fit:cover}.object-fill{-o-object-fit:fill;object-fit:fill}.object-none{-o-object-fit:none;object-fit:none}.object-scale-down{-o-object-fit:scale-down;object-fit:scale-down}.object-bottom{-o-object-position:bottom;object-position:bottom}.object-center{-o-object-position:center;object-position:center}.object-left{-o-object-position:left;object-position:left}.object-left-bottom{-o-object-position:left bottom;object-position:left bottom}.object-left-top{-o-object-position:left top;object-position:left top}.object-right{-o-object-position:right;object-position:right}.object-right-bottom{-o-object-position:right bottom;object-position:right bottom}.object-right-top{-o-object-position:right top;object-position:right top}.object-top{-o-object-position:top;object-position:top}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-clip{overflow:clip}.overflow-visible{overflow:visible}.overflow-scroll{overflow:scroll}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-hidden{overflow-y:hidden}.overflow-x-clip{overflow-x:clip}.overflow-y-clip{overflow-y:clip}.overflow-x-visible{overflow-x:visible}.overflow-y-visible{overflow-y:visible}.overflow-x-scroll{overflow-x:scroll}.overflow-y-scroll{overflow-y:scroll}.overflow-overlay{overflow:overlay}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{bottom:0;left:0;right:0;top:0}.inset-auto{bottom:auto;left:auto;right:auto;top:auto}.inset-x-0{left:0;right:0}.inset-y-0{bottom:0;top:0}.top-0{top:0}.right-0{right:0}.bottom-0{bottom:0}.left-0{left:0}.top-full{top:100%}.right-full{right:100%}.bottom-full{bottom:100%}.left-full{left:100%}.top-auto{top:auto}.right-auto{right:auto}.bottom-auto{bottom:auto}.left-auto{left:auto}.top-px{top:1px}.right-px{right:1px}.bottom-px{bottom:1px}.left-px{left:1px}.top-0\.5{top:.125rem}.right-0\.5{right:.125rem}.bottom-0\.5{bottom:.125rem}.left-0\.5{left:.125rem}.top-1{top:.25rem}.right-1{right:.25rem}.bottom-1{bottom:.25rem}.left-1{left:.25rem}.top-1\.5{top:.375rem}.right-1\.5{right:.375rem}.bottom-1\.5{bottom:.375rem}.left-1\.5{left:.375rem}.top-2{top:.5rem}.right-2{right:.5rem}.bottom-2{bottom:.5rem}.left-2{left:.5rem}.top-2\.5{top:.625rem}.right-2\.5{right:.625rem}.bottom-2\.5{bottom:.625rem}.left-2\.5{left:.625rem}.top-3{top:.75rem}.right-3{right:.75rem}.bottom-3{bottom:.75rem}.left-3{left:.75rem}.top-3\.5{top:.875rem}.right-3\.5{right:.875rem}.bottom-3\.5{bottom:.875rem}.left-3\.5{left:.875rem}.top-4{top:1rem}.right-4{right:1rem}.bottom-4{bottom:1rem}.left-4{left:1rem}.top-5{top:1.25rem}.right-5{right:1.25rem}.bottom-5{bottom:1.25rem}.left-5{left:1.25rem}.top-6{top:1.5rem}.right-6{right:1.5rem}.bottom-6{bottom:1.5rem}.left-6{left:1.5rem}.top-7{top:1.75rem}.right-7{right:1.75rem}.bottom-7{bottom:1.75rem}.left-7{left:1.75rem}.top-8{top:2rem}.right-8{right:2rem}.bottom-8{bottom:2rem}.left-8{left:2rem}.visible{visibility:visible!important}.invisible{visibility:hidden!important}.z-0{z-index:0}.z-1{z-index:1}.z-5{z-index:5}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-40{z-index:40}.z-50{z-index:50}.z-auto{z-index:auto}.z-base{z-index:1100}.z-above{z-index:50}.z-below{z-index:-50}.z-dropdown{z-index:1200}.z-sticky{z-index:1300}.z-fixed{z-index:1400}.z-modal{z-index:1500}.z-overlay{z-index:1600}.z-popover{z-index:1700}.z-tooltip{z-index:1800}.z-messager{z-index:1900}.m-0{margin:0}.m-auto{margin:auto}.m-px{margin:1px}.m-0\.5{margin:.125rem}.m-1{margin:.25rem}.m-1\.5{margin:.375rem}.m-2{margin:.5rem}.m-2\.5{margin:.625rem}.m-3{margin:.75rem}.m-3\.5{margin:.875rem}.m-4{margin:1rem}.m-5{margin:1.25rem}.m-6{margin:1.5rem}.m-7{margin:1.75rem}.m-8{margin:2rem}.m-9{margin:2.25rem}.m-10{margin:2.5rem}.mx-0{margin-left:0;margin-right:0}.my-0{margin-bottom:0}.mt-0,.my-0{margin-top:0}.mr-0{margin-right:0}.mb-0{margin-bottom:0}.ml-0{margin-left:0}.mx-auto{margin-left:auto;margin-right:auto}.my-auto{margin-bottom:auto}.mt-auto,.my-auto{margin-top:auto}.mr-auto{margin-right:auto}.mb-auto{margin-bottom:auto}.ml-auto{margin-left:auto}.mx-px{margin-left:1px;margin-right:1px}.my-px{margin-bottom:1px}.mt-px,.my-px{margin-top:1px}.mr-px{margin-right:1px}.mb-px{margin-bottom:1px}.ml-px{margin-left:1px}.mx-0\.5{margin-left:.125rem;margin-right:.125rem}.my-0\.5{margin-bottom:.125rem}.mt-0\.5,.my-0\.5{margin-top:.125rem}.mr-0\.5{margin-right:.125rem}.mb-0\.5{margin-bottom:.125rem}.ml-0\.5{margin-left:.125rem}.mx-1{margin-left:.25rem;margin-right:.25rem}.my-1{margin-bottom:.25rem}.mt-1,.my-1{margin-top:.25rem}.mr-1{margin-right:.25rem}.mb-1{margin-bottom:.25rem}.ml-1{margin-left:.25rem}.mx-1\.5{margin-left:.375rem;margin-right:.375rem}.my-1\.5{margin-bottom:.375rem}.mt-1\.5,.my-1\.5{margin-top:.375rem}.mr-1\.5{margin-right:.375rem}.mb-1\.5{margin-bottom:.375rem}.ml-1\.5{margin-left:.375rem}.mx-2{margin-left:.5rem;margin-right:.5rem}.my-2{margin-bottom:.5rem}.mt-2,.my-2{margin-top:.5rem}.mr-2{margin-right:.5rem}.mb-2{margin-bottom:.5rem}.ml-2{margin-left:.5rem}.mx-2\.5{margin-left:.625rem;margin-right:.625rem}.my-2\.5{margin-bottom:.625rem}.mt-2\.5,.my-2\.5{margin-top:.625rem}.mr-2\.5{margin-right:.625rem}.mb-2\.5{margin-bottom:.625rem}.ml-2\.5{margin-left:.625rem}.mx-3{margin-left:.75rem;margin-right:.75rem}.my-3{margin-bottom:.75rem}.mt-3,.my-3{margin-top:.75rem}.mr-3{margin-right:.75rem}.mb-3{margin-bottom:.75rem}.ml-3{margin-left:.75rem}.mx-3\.5{margin-left:.875rem;margin-right:.875rem}.my-3\.5{margin-bottom:.875rem}.mt-3\.5,.my-3\.5{margin-top:.875rem}.mr-3\.5{margin-right:.875rem}.mb-3\.5{margin-bottom:.875rem}.ml-3\.5{margin-left:.875rem}.mx-4{margin-left:1rem;margin-right:1rem}.my-4{margin-bottom:1rem}.mt-4,.my-4{margin-top:1rem}.mr-4{margin-right:1rem}.mb-4{margin-bottom:1rem}.ml-4{margin-left:1rem}.mx-5{margin-left:1.25rem;margin-right:1.25rem}.my-5{margin-bottom:1.25rem}.mt-5,.my-5{margin-top:1.25rem}.mr-5{margin-right:1.25rem}.mb-5{margin-bottom:1.25rem}.ml-5{margin-left:1.25rem}.mx-6{margin-left:1.5rem;margin-right:1.5rem}.my-6{margin-bottom:1.5rem}.mt-6,.my-6{margin-top:1.5rem}.mr-6{margin-right:1.5rem}.mb-6{margin-bottom:1.5rem}.ml-6{margin-left:1.5rem}.mx-7{margin-left:1.75rem;margin-right:1.75rem}.my-7{margin-bottom:1.75rem}.mt-7,.my-7{margin-top:1.75rem}.mr-7{margin-right:1.75rem}.mb-7{margin-bottom:1.75rem}.ml-7{margin-left:1.75rem}.mx-8{margin-left:2rem;margin-right:2rem}.my-8{margin-bottom:2rem}.mt-8,.my-8{margin-top:2rem}.mr-8{margin-right:2rem}.mb-8{margin-bottom:2rem}.ml-8{margin-left:2rem}.mx-9{margin-left:2.25rem;margin-right:2.25rem}.my-9{margin-bottom:2.25rem}.mt-9,.my-9{margin-top:2.25rem}.mr-9{margin-right:2.25rem}.mb-9{margin-bottom:2.25rem}.ml-9{margin-left:2.25rem}.mx-10{margin-left:2.5rem;margin-right:2.5rem}.my-10{margin-bottom:2.5rem}.mt-10,.my-10{margin-top:2.5rem}.mr-10{margin-right:2.5rem}.mb-10{margin-bottom:2.5rem}.ml-10{margin-left:2.5rem}.p-0{padding:0}.p-px{padding:1px}.p-0\.5{padding:.125rem}.p-1{padding:.25rem}.p-1\.5{padding:.375rem}.p-2{padding:.5rem}.p-2\.5{padding:.625rem}.p-3{padding:.75rem}.p-3\.5{padding:.875rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.p-7{padding:1.75rem}.p-8{padding:2rem}.p-9{padding:2.25rem}.p-10{padding:2.5rem}.px-0{padding-left:0;padding-right:0}.py-0{padding-bottom:0}.pt-0,.py-0{padding-top:0}.pr-0{padding-right:0}.pb-0{padding-bottom:0}.pl-0{padding-left:0}.px-px{padding-left:1px;padding-right:1px}.py-px{padding-bottom:1px}.pt-px,.py-px{padding-top:1px}.pr-px{padding-right:1px}.pb-px{padding-bottom:1px}.pl-px{padding-left:1px}.px-0\.5{padding-left:.125rem;padding-right:.125rem}.py-0\.5{padding-bottom:.125rem}.pt-0\.5,.py-0\.5{padding-top:.125rem}.pr-0\.5{padding-right:.125rem}.pb-0\.5{padding-bottom:.125rem}.pl-0\.5{padding-left:.125rem}.px-1{padding-left:.25rem;padding-right:.25rem}.py-1{padding-bottom:.25rem}.pt-1,.py-1{padding-top:.25rem}.pr-1{padding-right:.25rem}.pb-1{padding-bottom:.25rem}.pl-1{padding-left:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.py-1\.5{padding-bottom:.375rem}.pt-1\.5,.py-1\.5{padding-top:.375rem}.pr-1\.5{padding-right:.375rem}.pb-1\.5{padding-bottom:.375rem}.pl-1\.5{padding-left:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.py-2{padding-bottom:.5rem}.pt-2,.py-2{padding-top:.5rem}.pr-2{padding-right:.5rem}.pb-2{padding-bottom:.5rem}.pl-2{padding-left:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.py-2\.5{padding-bottom:.625rem}.pt-2\.5,.py-2\.5{padding-top:.625rem}.pr-2\.5{padding-right:.625rem}.pb-2\.5{padding-bottom:.625rem}.pl-2\.5{padding-left:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.py-3{padding-bottom:.75rem}.pt-3,.py-3{padding-top:.75rem}.pr-3{padding-right:.75rem}.pb-3{padding-bottom:.75rem}.pl-3{padding-left:.75rem}.px-3\.5{padding-left:.875rem;padding-right:.875rem}.py-3\.5{padding-bottom:.875rem}.pt-3\.5,.py-3\.5{padding-top:.875rem}.pr-3\.5{padding-right:.875rem}.pb-3\.5{padding-bottom:.875rem}.pl-3\.5{padding-left:.875rem}.px-4{padding-left:1rem;padding-right:1rem}.py-4{padding-bottom:1rem}.pt-4,.py-4{padding-top:1rem}.pr-4{padding-right:1rem}.pb-4{padding-bottom:1rem}.pl-4{padding-left:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.py-5{padding-bottom:1.25rem}.pt-5,.py-5{padding-top:1.25rem}.pr-5{padding-right:1.25rem}.pb-5{padding-bottom:1.25rem}.pl-5{padding-left:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-6{padding-bottom:1.5rem}.pt-6,.py-6{padding-top:1.5rem}.pr-6{padding-right:1.5rem}.pb-6{padding-bottom:1.5rem}.pl-6{padding-left:1.5rem}.px-7{padding-left:1.75rem;padding-right:1.75rem}.py-7{padding-bottom:1.75rem}.pt-7,.py-7{padding-top:1.75rem}.pr-7{padding-right:1.75rem}.pb-7{padding-bottom:1.75rem}.pl-7{padding-left:1.75rem}.px-8{padding-left:2rem;padding-right:2rem}.py-8{padding-bottom:2rem}.pt-8,.py-8{padding-top:2rem}.pr-8{padding-right:2rem}.pb-8{padding-bottom:2rem}.pl-8{padding-left:2rem}.px-9{padding-left:2.25rem;padding-right:2.25rem}.py-9{padding-bottom:2.25rem}.pt-9,.py-9{padding-top:2.25rem}.pr-9{padding-right:2.25rem}.pb-9{padding-bottom:2.25rem}.pl-9{padding-left:2.25rem}.px-10{padding-left:2.5rem;padding-right:2.5rem}.py-10{padding-bottom:2.5rem}.pt-10,.py-10{padding-top:2.5rem}.pr-10{padding-right:2.5rem}.pb-10{padding-bottom:2.5rem}.pl-10{padding-left:2.5rem}.space-x-0>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(0px*(1 - var(--tw-space-x-reverse)));margin-right:calc(0px*var(--tw-space-x-reverse))}.space-y-0>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(0px*var(--tw-space-y-reverse));margin-top:calc(0px*(1 - var(--tw-space-y-reverse)))}.space-x-0\.5>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.125rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.125rem*var(--tw-space-x-reverse))}.space-y-0\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.125rem*var(--tw-space-y-reverse));margin-top:calc(.125rem*(1 - var(--tw-space-y-reverse)))}.space-x-1>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.25rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.25rem*var(--tw-space-x-reverse))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.25rem*var(--tw-space-y-reverse));margin-top:calc(.25rem*(1 - var(--tw-space-y-reverse)))}.space-x-1\.5>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.375rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.375rem*var(--tw-space-x-reverse))}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.375rem*var(--tw-space-y-reverse));margin-top:calc(.375rem*(1 - var(--tw-space-y-reverse)))}.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.5rem*var(--tw-space-x-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.5rem*var(--tw-space-y-reverse));margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)))}.space-x-2\.5>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.625rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.625rem*var(--tw-space-x-reverse))}.space-y-2\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.625rem*var(--tw-space-y-reverse));margin-top:calc(.625rem*(1 - var(--tw-space-y-reverse)))}.space-x-3>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.75rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.75rem*var(--tw-space-x-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.75rem*var(--tw-space-y-reverse));margin-top:calc(.75rem*(1 - var(--tw-space-y-reverse)))}.space-x-3\.5>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.875rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.875rem*var(--tw-space-x-reverse))}.space-y-3\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.875rem*var(--tw-space-y-reverse));margin-top:calc(.875rem*(1 - var(--tw-space-y-reverse)))}.space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1rem*var(--tw-space-x-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1rem*var(--tw-space-y-reverse));margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)))}.space-x-5>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1.25rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1.25rem*var(--tw-space-x-reverse))}.space-y-5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1.25rem*var(--tw-space-y-reverse));margin-top:calc(1.25rem*(1 - var(--tw-space-y-reverse)))}.space-x-6>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1.5rem*var(--tw-space-x-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1.5rem*var(--tw-space-y-reverse));margin-top:calc(1.5rem*(1 - var(--tw-space-y-reverse)))}.space-x-7>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1.75rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1.75rem*var(--tw-space-x-reverse))}.space-y-7>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1.75rem*var(--tw-space-y-reverse));margin-top:calc(1.75rem*(1 - var(--tw-space-y-reverse)))}.space-x-8>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(2rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(2rem*var(--tw-space-x-reverse))}.space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(2rem*var(--tw-space-y-reverse));margin-top:calc(2rem*(1 - var(--tw-space-y-reverse)))}.space-x-9>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(2.25rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(2.25rem*var(--tw-space-x-reverse))}.space-y-9>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(2.25rem*var(--tw-space-y-reverse));margin-top:calc(2.25rem*(1 - var(--tw-space-y-reverse)))}.space-x-10>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(2.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(2.5rem*var(--tw-space-x-reverse))}.space-y-10>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(2.5rem*var(--tw-space-y-reverse));margin-top:calc(2.5rem*(1 - var(--tw-space-y-reverse)))}.space-x-px>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1px*(1 - var(--tw-space-x-reverse)));margin-right:calc(1px*var(--tw-space-x-reverse))}.space-y-px>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1px*var(--tw-space-y-reverse));margin-top:calc(1px*(1 - var(--tw-space-y-reverse)))}.w-0{width:0}.w-px{width:1px}.w-0\.5{width:.125rem}.w-1{width:.25rem}.w-1\.5{width:.375rem}.w-2{width:.5rem}.w-2\.5{width:.625rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-7{width:1.75rem}.w-8{width:2rem}.w-9{width:2.25rem}.w-10{width:2.5rem}.w-11{width:2.75rem}.w-12{width:3rem}.w-14{width:3.5rem}.w-16{width:4rem}.w-20{width:5rem}.w-24{width:6rem}.w-28{width:7rem}.w-32{width:8rem}.w-36{width:9rem}.w-40{width:10rem}.w-44{width:11rem}.w-48{width:12rem}.w-52{width:13rem}.w-56{width:14rem}.w-60{width:15rem}.w-64{width:16rem}.w-72{width:18rem}.w-80{width:20rem}.w-96{width:24rem}.w-1\/2{width:50%}.w-1\/3{width:33.333333%}.w-2\/3{width:66.666667%}.w-1\/4{width:25%}.w-2\/4{width:50%}.w-3\/4{width:75%}.w-1\/5{width:20%}.w-2\/5{width:40%}.w-3\/5{width:60%}.w-4\/5{width:80%}.w-1\/6{width:16.666667%}.w-2\/6{width:33.333333%}.w-3\/6{width:50%}.w-4\/6{width:66.666667%}.w-5\/6{width:83.333333%}.w-auto{width:auto}.w-full{width:100%}.w-screen{width:100vw}.w-min{width:-moz-min-content;width:min-content}.w-max{width:-moz-max-content;width:max-content}.w-fit{width:-moz-fit-content;width:fit-content}.min-w-0{min-width:0}.min-w-full{min-width:100%}.min-w-min{min-width:-moz-min-content;min-width:min-content}.min-w-max{min-width:-moz-max-content;min-width:max-content}.min-w-fit{min-width:-moz-fit-content;min-width:fit-content}.max-w-0{max-width:0}.max-w-none{max-width:none}.max-w-xs{max-width:20rem}.max-w-sm{max-width:24rem}.max-w-md{max-width:28rem}.max-w-lg{max-width:32rem}.max-w-xl{max-width:36rem}.max-w-2xl{max-width:42rem}.max-w-3xl{max-width:48rem}.max-w-4xl{max-width:56rem}.max-w-5xl{max-width:64rem}.max-w-6xl{max-width:72rem}.max-w-7xl{max-width:80rem}.max-w-full{max-width:100%}.max-w-min{max-width:-moz-min-content;max-width:min-content}.max-w-max{max-width:-moz-max-content;max-width:max-content}.max-w-fit{max-width:-moz-fit-content;max-width:fit-content}.h-0{height:0}.h-px{height:1px}.h-0\.5{height:.125rem}.h-1{height:.25rem}.h-1\.5{height:.375rem}.h-2{height:.5rem}.h-2\.5{height:.625rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-10{height:2.5rem}.h-11{height:2.75rem}.h-12{height:3rem}.h-14{height:3.5rem}.h-16{height:4rem}.h-20{height:5rem}.h-24{height:6rem}.h-28{height:7rem}.h-32{height:8rem}.h-36{height:9rem}.h-40{height:10rem}.h-44{height:11rem}.h-48{height:12rem}.h-52{height:13rem}.h-56{height:14rem}.h-60{height:15rem}.h-64{height:16rem}.h-72{height:18rem}.h-80{height:20rem}.h-96{height:24rem}.h-1\/2{height:50%}.h-1\/3{height:33.333333%}.h-2\/3{height:66.666667%}.h-1\/4{height:25%}.h-2\/4{height:50%}.h-3\/4{height:75%}.h-1\/5{height:20%}.h-2\/5{height:40%}.h-3\/5{height:60%}.h-4\/5{height:80%}.h-1\/6{height:16.666667%}.h-2\/6{height:33.333333%}.h-3\/6{height:50%}.h-4\/6{height:66.666667%}.h-5\/6{height:83.333333%}.h-auto{height:auto}.h-full{height:100%}.h-screen{height:100vh}.h-min{height:-moz-min-content;height:min-content}.h-max{height:-moz-max-content;height:max-content}.h-fit{height:-moz-fit-content;height:fit-content}.min-h-0{min-height:0}.min-h-full{min-height:100%}.min-h-min{min-height:-moz-min-content;min-height:min-content}.min-h-max{min-height:-moz-max-content;min-height:max-content}.min-h-fit{min-height:-moz-fit-content;min-height:fit-content}.max-h-0{max-height:0}.max-h-px{max-height:1px}.max-h-none{max-height:none}.max-h-full{max-height:100%}.max-h-min{max-height:-moz-min-content;max-height:min-content}.max-h-screen{max-height:100vh}.max-h-max{max-height:-moz-max-content;max-height:max-content}.max-h-fit{max-height:-moz-fit-content;max-height:fit-content}.canvas,.surface,.surface-light,.surface-strong{--tw-text-opacity:1;color:rgba(var(--color-fore-rgb),var(--tw-text-opacity,1))}.canvas{--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1))}.surface-light{--tw-bg-opacity:1;background-color:rgba(var(--color-surface-light-rgb),var(--tw-bg-opacity,1));--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-surface-light-rgb),var(--tw-ring-opacity,1))}.surface{--tw-bg-opacity:1;background-color:rgba(var(--color-surface-rgb),var(--tw-bg-opacity,1));--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-surface-rgb),var(--tw-ring-opacity,1))}.surface-strong{--tw-bg-opacity:1;background-color:rgba(var(--color-surface-strong-rgb),var(--tw-bg-opacity,1));--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-surface-strong-rgb),var(--tw-ring-opacity,1))}.inverse{background-color:rgba(var(--color-inverse-rgb),var(--tw-bg-opacity,1));color:rgba(var(--color-canvas-rgb),var(--tw-text-opacity,1))}.inverse,.white{--tw-bg-opacity:1;--tw-text-opacity:1}.white{background-color:rgba(var(--color-white-rgb),var(--tw-bg-opacity,1));color:rgba(var(--color-fore-in-light-rgb),var(--tw-text-opacity,1));--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-white-rgb),var(--tw-ring-opacity,1))}.black{--tw-bg-opacity:1;background-color:rgba(var(--color-black-rgb),var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgba(var(--color-fore-in-dark-rgb),var(--tw-text-opacity,1));--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-black-rgb),var(--tw-ring-opacity,1))}.transparent{background-color:transparent;--tw-ring-color:transparent}.skin{--skin-bg:var(--skin-color);--skin-ring:var(--skin-color);--skin-border:var(--skin-color);--skin-hover-text:var(--skin-text);--skin-hover-bg:var(--skin-bg);--tw-ring-color:var(--skin-ring);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);--color-link-hover:var(--skin-text);background-color:var(--skin-bg);border-color:var(--skin-border);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);color:var(--skin-text)}.skin:hover{background-color:var(--skin-hover-bg);color:var(--skin-hover-text)}.danger,.darken,.darker,.darkest,.gray,.gray-100,.gray-200,.gray-300,.gray-400,.gray-50,.gray-500,.gray-600,.gray-700,.gray-800,.gray-900,.gray-950,.important,.lighten,.lighter,.lightest,.primary,.secondary,.special,.success,.warning{--skin-bg:var(--skin-color);--skin-ring:var(--skin-color);--skin-border:var(--skin-color);--skin-hover-text:var(--skin-text);--skin-hover-bg:var(--skin-bg);--tw-ring-color:var(--skin-ring);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);--color-link-hover:var(--skin-text);background-color:var(--skin-bg);border-color:var(--skin-border);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);color:var(--skin-text)}.danger:hover,.darken:hover,.darker:hover,.darkest:hover,.gray-100:hover,.gray-200:hover,.gray-300:hover,.gray-400:hover,.gray-500:hover,.gray-50:hover,.gray-600:hover,.gray-700:hover,.gray-800:hover,.gray-900:hover,.gray-950:hover,.gray:hover,.important:hover,.lighten:hover,.lighter:hover,.lightest:hover,.primary:hover,.secondary:hover,.special:hover,.success:hover,.warning:hover{background-color:var(--skin-hover-bg);color:var(--skin-hover-text)}.danger,.darken,.darker,.darkest,.gray,.gray-100,.gray-200,.gray-300,.gray-400,.gray-50,.gray-500,.gray-600,.gray-700,.gray-800,.gray-900,.gray-950,.important,.lighten,.lighter,.lightest,.primary,.secondary,.special,.success,.warning{--skin-text:rgba(var(--color-fore-in-dark-rgb),var(--tw-text-opacity));--skin-color:rgba(var(--skin-solid-rgb),1);--state-ring-color:var(--skin-color);--state-active-color:rgba(0,0,0,.1);--state-pressed-color:rgba(0,0,0,.1);--state-color:hsla(0,0%,100%,.1);--state-focus-color:rgba(0,0,0,.1)}.primary{--skin-solid-rgb:var(--color-primary-500-rgb)}.secondary{--skin-solid-rgb:var(--color-secondary-500-rgb)}.success{--skin-solid-rgb:var(--color-success-500-rgb)}.warning{--skin-solid-rgb:var(--color-warning-500-rgb)}.danger{--skin-solid-rgb:var(--color-danger-500-rgb)}.important{--skin-solid-rgb:var(--color-important-500-rgb)}.special{--skin-solid-rgb:var(--color-special-500-rgb)}.gray-50{--skin-bg:rgba(var(--color-gray-50-rgb),var(--tw-bg-opacity));--skin-text:rgba(var(--color-fore),var(--tw-text-opacity))}.gray-100{--skin-solid-rgb:var(--color-gray-100-rgb);--skin-text:rgba(var(--color-fore),var(--tw-text-opacity))}.gray-200,.lightest{--skin-solid-rgb:var(--color-gray-200-rgb);--skin-text:rgba(var(--color-fore),var(--tw-text-opacity))}.gray-300,.lighter{--skin-solid-rgb:var(--color-gray-300-rgb);--skin-text:rgba(var(--color-fore),var(--tw-text-opacity))}.gray-400,.lighten{--skin-solid-rgb:var(--color-gray-400-rgb)}.gray,.gray-500{--skin-solid-rgb:var(--color-gray-500-rgb)}.darken,.gray-600{--skin-solid-rgb:var(--color-gray-600-rgb)}.darker,.gray-700{--skin-solid-rgb:var(--color-gray-700-rgb)}.darkest,.gray-800{--skin-solid-rgb:var(--color-gray-800-rgb)}.gray-900{--skin-solid-rgb:var(--color-gray-900-rgb)}.gray-950{--skin-solid-rgb:var(--color-gray-950-rgb)}.danger-pale,.gray-100-pale,.gray-200-pale,.gray-300-pale,.gray-400-pale,.gray-50-pale,.gray-500-pale,.gray-600-pale,.gray-700-pale,.gray-800-pale,.gray-900-pale,.gray-950-pale,.gray-pale,.important-pale,.pale,.primary-pale,.secondary-pale,.special-pale,.success-pale,.warning-pale{--skin-bg:var(--skin-color);--skin-ring:var(--skin-color);--skin-border:var(--skin-color);--skin-hover-text:var(--skin-text);--skin-hover-bg:var(--skin-bg);--tw-ring-color:var(--skin-ring);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);--color-link-hover:var(--skin-text);background-color:var(--skin-bg);border-color:var(--skin-border);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);color:var(--skin-text)}.danger-pale:hover,.gray-100-pale:hover,.gray-200-pale:hover,.gray-300-pale:hover,.gray-400-pale:hover,.gray-50-pale:hover,.gray-500-pale:hover,.gray-600-pale:hover,.gray-700-pale:hover,.gray-800-pale:hover,.gray-900-pale:hover,.gray-950-pale:hover,.gray-pale:hover,.important-pale:hover,.pale:hover,.primary-pale:hover,.secondary-pale:hover,.special-pale:hover,.success-pale:hover,.warning-pale:hover{background-color:var(--skin-hover-bg);color:var(--skin-hover-text)}.danger-pale,.gray-100-pale,.gray-200-pale,.gray-300-pale,.gray-400-pale,.gray-50-pale,.gray-500-pale,.gray-600-pale,.gray-700-pale,.gray-800-pale,.gray-900-pale,.gray-950-pale,.gray-pale,.important-pale,.pale,.primary-pale,.secondary-pale,.special-pale,.success-pale,.warning-pale{--skin-color:rgba(var(--skin-pale-rgb),.1);--skin-text:rgba(var(--skin-pale-rgb),1);--state-color:rgba(var(--skin-pale-rgb),.1)}.pale{--skin-pale-rgb:var(--color-gray-500-rgb)}.primary-pale{--skin-pale-rgb:var(--color-primary-500-rgb)}.secondary-pale{--skin-pale-rgb:var(--color-secondary-500-rgb)}.success-pale{--skin-pale-rgb:var(--color-success-500-rgb)}.warning-pale{--skin-pale-rgb:var(--color-warning-500-rgb)}.danger-pale{--skin-pale-rgb:var(--color-danger-500-rgb)}.important-pale{--skin-pale-rgb:var(--color-important-500-rgb)}.special-pale{--skin-pale-rgb:var(--color-special-500-rgb)}.gray-50-pale{--skin-pale-rgb:var(--color-gray-50-rgb);--skin-text:var(--color-gray-400)}.gray-100-pale{--skin-pale-rgb:var(--color-gray-100-rgb);--skin-text:var(--color-gray-400)}.gray-200-pale{--skin-pale-rgb:var(--color-gray-200-rgb);--skin-text:var(--color-gray-400)}.gray-300-pale{--skin-pale-rgb:var(--color-gray-300-rgb);--skin-text:var(--color-gray-500)}.gray-400-pale{--skin-pale-rgb:var(--color-gray-400-rgb);--skin-text:var(--color-gray-500)}.gray-500-pale,.gray-pale{--skin-pale-rgb:var(--color-gray-500-rgb)}.gray-600-pale{--skin-pale-rgb:var(--color-gray-600-rgb)}.gray-700-pale{--skin-pale-rgb:var(--color-gray-700-rgb)}.gray-800-pale{--skin-pale-rgb:var(--color-gray-800-rgb)}.gray-900-pale{--skin-pale-rgb:var(--color-gray-900-rgb)}.gray-950-pale{--skin-pale-rgb:var(--color-gray-950-rgb)}.danger-outline,.dark-outline,.gray-300-outline,.gray-400-outline,.gray-600-outline,.gray-outline,.important-outline,.light-outline,.outline,.primary-outline,.secondary-outline,.special-outline,.success-outline,.warning-outline{--skin-bg:var(--skin-color);--skin-ring:var(--skin-color);--skin-border:var(--skin-color);--skin-hover-text:var(--skin-text);--skin-hover-bg:var(--skin-bg);--tw-ring-color:var(--skin-ring);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);--color-link-hover:var(--skin-text);background-color:var(--skin-bg);border-color:var(--skin-border);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);color:var(--skin-text)}.danger-outline:hover,.dark-outline:hover,.gray-300-outline:hover,.gray-400-outline:hover,.gray-600-outline:hover,.gray-outline:hover,.important-outline:hover,.light-outline:hover,.outline:hover,.primary-outline:hover,.secondary-outline:hover,.special-outline:hover,.success-outline:hover,.warning-outline:hover{background-color:var(--skin-hover-bg);color:var(--skin-hover-text)}.danger-outline,.dark-outline,.gray-300-outline,.gray-400-outline,.gray-600-outline,.gray-outline,.important-outline,.light-outline,.outline,.primary-outline,.secondary-outline,.special-outline,.success-outline,.warning-outline{--skin-text:var(--skin-color,inherit);--skin-bg:transparent;--skin-color:rgba(var(--skin-outline-rgb),1);--state-color:rgba(var(--skin-outline-rgb),.1)}.outline{--skin-outline-rgb:var(--color-fore-rgb)}.primary-outline{--skin-outline-rgb:var(--color-primary-500-rgb)}.secondary-outline{--skin-outline-rgb:var(--color-secondary-500-rgb)}.success-outline{--skin-outline-rgb:var(--color-success-500-rgb)}.warning-outline{--skin-outline-rgb:var(--color-warning-500-rgb)}.danger-outline{--skin-outline-rgb:var(--color-danger-500-rgb)}.important-outline{--skin-outline-rgb:var(--color-important-500-rgb)}.special-outline{--skin-outline-rgb:var(--color-special-500-rgb)}.gray-300-outline{--skin-text:var(--color-gray-500);--skin-outline-rgb:var(--color-gray-300-rgb)}.gray-400-outline{--skin-text:var(--color-gray-500);--skin-outline-rgb:var(--color-gray-400-rgb)}.gray-outline{--skin-outline-rgb:var(--color-gray-500-rgb)}.gray-600-outline{--skin-outline-rgb:var(--color-gray-600-rgb)}.dark-outline{--skin-outline-rgb:var(--color-inverse-rgb)}.light-outline{--skin-outline-rgb:var(--color-canvas-rgb)}.danger-ghost,.ghost,.important-ghost,.primary-ghost,.secondary-ghost,.special-ghost,.success-ghost,.warning-ghost{--skin-bg:var(--skin-color);--skin-ring:var(--skin-color);--skin-border:var(--skin-color);--skin-hover-text:var(--skin-text);--skin-hover-bg:var(--skin-bg);--tw-ring-color:var(--skin-ring);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);--color-link-hover:var(--skin-text);background-color:var(--skin-bg);border-color:var(--skin-border);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);color:var(--skin-text)}.danger-ghost:hover,.ghost:hover,.important-ghost:hover,.primary-ghost:hover,.secondary-ghost:hover,.special-ghost:hover,.success-ghost:hover,.warning-ghost:hover{background-color:var(--skin-hover-bg);color:var(--skin-hover-text)}.danger-ghost,.ghost,.important-ghost,.primary-ghost,.secondary-ghost,.special-ghost,.success-ghost,.warning-ghost{--tw-ring-opacity:0;--tw-bg-opacity:0;--skin-text:var(--skin-color,inherit);--skin-bg:transparent;--skin-ring:transparent;--skin-color:rgba(var(--skin-ghost-rgb),1);--state-color:rgba(var(--skin-ghost-rgb),.1)}.ghost{--skin-ghost-rgb:var(--color-fore-rgb);--skin-text:inherit}.primary-ghost{--skin-ghost-rgb:var(--color-primary-500-rgb)}.secondary-ghost{--skin-ghost-rgb:var(--color-secondary-500-rgb)}.success-ghost{--skin-ghost-rgb:var(--color-success-500-rgb)}.warning-ghost{--skin-ghost-rgb:var(--color-warning-500-rgb)}.danger-ghost{--skin-ghost-rgb:var(--color-danger-500-rgb)}.important-ghost{--skin-ghost-rgb:var(--color-important-500-rgb)}.special-ghost{--skin-ghost-rgb:var(--color-special-500-rgb)}.font-sans{font-family:-apple-system,Noto Sans,Helvetica Neue,Helvetica,Nimbus Sans L,Arial,Liberation Sans,PingFang SC,Hiragino Sans GB,Noto Sans CJK SC,Source Han Sans SC,Source Han Sans CN,Microsoft YaHei,Wenquanyi Micro Hei,WenQuanYi Zen Hei,ST Heiti,SimHei,WenQuanYi Zen Hei Sharp,sans-serif}.font-serif{font-family:Nimbus Roman No9 L,Songti SC,Noto Serif CJK SC,Source Han Serif SC,Source Han Serif CN,STSong,AR PL New Sung,AR PL SungtiL GB,NSimSun,SimSun,TW-Sung,WenQuanYi Bitmap Song,AR PL UMing CN,AR PL UMing HK,AR PL UMing TW,AR PL UMing TW MBE,PMingLiU,MingLiU,serif}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-root{font-size:16px}.text-sm{font-size:.75rem;line-height:1rem}.text-base{font-size:.8125rem;line-height:1.25rem}.text-md{font-size:.875rem;line-height:1.3rem}.text-lg{font-size:1rem;line-height:1.5rem}.text-xl{font-size:1.125rem;line-height:1.75rem}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-4xl{font-size:2.25rem;line-height:2.5rem}.font-thin{font-weight:100}.font-light{font-weight:300}.font-normal{font-weight:400}.font-medium{font-weight:500}.font-semibold{font-weight:600}.font-bold{font-weight:700}.font-black{font-weight:900}.leading-3{line-height:.75rem}.leading-4{line-height:1rem}.leading-5{line-height:1.25rem}.leading-6{line-height:1.5rem}.leading-7{line-height:1.75rem}.leading-8{line-height:2rem}.leading-9{line-height:2.25rem}.leading-10{line-height:2.5rem}.leading-none{line-height:1}.leading-tight{line-height:1.25}.leading-snug{line-height:1.375}.leading-normal{line-height:1.5}.leading-relaxed{line-height:1.625}.leading-loose{line-height:2}.line-clamp-1{-webkit-line-clamp:1}.line-clamp-1,.line-clamp-2{display:-webkit-box;overflow:hidden;-webkit-box-orient:vertical}.line-clamp-2{-webkit-line-clamp:2}.line-clamp-3{-webkit-line-clamp:3}.line-clamp-3,.line-clamp-4{display:-webkit-box;overflow:hidden;-webkit-box-orient:vertical}.line-clamp-4{-webkit-line-clamp:4}.line-clamp-5{-webkit-line-clamp:5}.line-clamp-5,.line-clamp-6{display:-webkit-box;overflow:hidden;-webkit-box-orient:vertical}.line-clamp-6{-webkit-line-clamp:6}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.text-justify{text-align:justify}.align-middle{vertical-align:middle}.align-top{vertical-align:top}.align-bottom{vertical-align:bottom}.align-sub{vertical-align:sub}.align-super{vertical-align:super}.text-primary{--tw-text-opacity:1;color:rgba(var(--color-primary-500-rgb),var(--tw-text-opacity,1))}.text-secondary{--tw-text-opacity:1;color:rgba(var(--color-secondary-500-rgb),var(--tw-text-opacity,1))}.text-success{--tw-text-opacity:1;color:rgba(var(--color-success-500-rgb),var(--tw-text-opacity,1))}.text-warning{--tw-text-opacity:1;color:rgba(var(--color-warning-500-rgb),var(--tw-text-opacity,1))}.text-danger{--tw-text-opacity:1;color:rgba(var(--color-danger-500-rgb),var(--tw-text-opacity,1))}.text-important{--tw-text-opacity:1;color:rgba(var(--color-important-500-rgb),var(--tw-text-opacity,1))}.text-special{--tw-text-opacity:1;color:rgba(var(--color-special-500-rgb),var(--tw-text-opacity,1))}.text-primary-50{--tw-text-opacity:1;color:rgba(var(--color-primary-50-rgb),var(--tw-text-opacity,1))}.text-primary-100{--tw-text-opacity:1;color:rgba(var(--color-primary-100-rgb),var(--tw-text-opacity,1))}.text-primary-200{--tw-text-opacity:1;color:rgba(var(--color-primary-200-rgb),var(--tw-text-opacity,1))}.text-primary-300{--tw-text-opacity:1;color:rgba(var(--color-primary-300-rgb),var(--tw-text-opacity,1))}.text-primary-400{--tw-text-opacity:1;color:rgba(var(--color-primary-400-rgb),var(--tw-text-opacity,1))}.text-primary-500{--tw-text-opacity:1;color:rgba(var(--color-primary-500-rgb),var(--tw-text-opacity,1))}.text-primary-600{--tw-text-opacity:1;color:rgba(var(--color-primary-600-rgb),var(--tw-text-opacity,1))}.text-primary-700{--tw-text-opacity:1;color:rgba(var(--color-primary-700-rgb),var(--tw-text-opacity,1))}.text-primary-800{--tw-text-opacity:1;color:rgba(var(--color-primary-800-rgb),var(--tw-text-opacity,1))}.text-primary-900{--tw-text-opacity:1;color:rgba(var(--color-primary-900-rgb),var(--tw-text-opacity,1))}.text-primary-950{--tw-text-opacity:1;color:rgba(var(--color-primary-950-rgb),var(--tw-text-opacity,1))}.text-secondary-50{--tw-text-opacity:1;color:rgba(var(--color-secondary-50-rgb),var(--tw-text-opacity,1))}.text-secondary-100{--tw-text-opacity:1;color:rgba(var(--color-secondary-100-rgb),var(--tw-text-opacity,1))}.text-secondary-200{--tw-text-opacity:1;color:rgba(var(--color-secondary-200-rgb),var(--tw-text-opacity,1))}.text-secondary-300{--tw-text-opacity:1;color:rgba(var(--color-secondary-300-rgb),var(--tw-text-opacity,1))}.text-secondary-400{--tw-text-opacity:1;color:rgba(var(--color-secondary-400-rgb),var(--tw-text-opacity,1))}.text-secondary-500{--tw-text-opacity:1;color:rgba(var(--color-secondary-500-rgb),var(--tw-text-opacity,1))}.text-secondary-600{--tw-text-opacity:1;color:rgba(var(--color-secondary-600-rgb),var(--tw-text-opacity,1))}.text-secondary-700{--tw-text-opacity:1;color:rgba(var(--color-secondary-700-rgb),var(--tw-text-opacity,1))}.text-secondary-800{--tw-text-opacity:1;color:rgba(var(--color-secondary-800-rgb),var(--tw-text-opacity,1))}.text-secondary-900{--tw-text-opacity:1;color:rgba(var(--color-secondary-900-rgb),var(--tw-text-opacity,1))}.text-secondary-950{--tw-text-opacity:1;color:rgba(var(--color-secondary-950-rgb),var(--tw-text-opacity,1))}.text-gray-50{--tw-text-opacity:1;color:rgba(var(--color-gray-50-rgb),var(--tw-text-opacity,1))}.text-gray-100{--tw-text-opacity:1;color:rgba(var(--color-gray-100-rgb),var(--tw-text-opacity,1))}.text-gray-200,.text-lightest{--tw-text-opacity:1;color:rgba(var(--color-gray-200-rgb),var(--tw-text-opacity,1))}.text-gray-300,.text-lighter{--tw-text-opacity:1;color:rgba(var(--color-gray-300-rgb),var(--tw-text-opacity,1))}.text-gray-400,.text-lighten{--tw-text-opacity:1;color:rgba(var(--color-gray-400-rgb),var(--tw-text-opacity,1))}.text-gray,.text-gray-500{--tw-text-opacity:1;color:rgba(var(--color-gray-500-rgb),var(--tw-text-opacity,1))}.text-darken,.text-gray-600{--tw-text-opacity:1;color:rgba(var(--color-gray-600-rgb),var(--tw-text-opacity,1))}.text-darker,.text-gray-700{--tw-text-opacity:1;color:rgba(var(--color-gray-700-rgb),var(--tw-text-opacity,1))}.text-darkest,.text-gray-800{--tw-text-opacity:1;color:rgba(var(--color-gray-800-rgb),var(--tw-text-opacity,1))}.text-gray-900{--tw-text-opacity:1;color:rgba(var(--color-gray-900-rgb),var(--tw-text-opacity,1))}.text-gray-950{--tw-text-opacity:1;color:rgba(var(--color-gray-950-rgb),var(--tw-text-opacity,1))}.text-white{--tw-text-opacity:1;color:rgba(var(--color-white-rgb),var(--tw-text-opacity,1))}.text-black{--tw-text-opacity:1;color:rgba(var(--color-black-rgb),var(--tw-text-opacity,1))}.text-transparent{color:transparent}.text-canvas{--tw-text-opacity:1;color:rgba(var(--color-canvas-rgb),var(--tw-text-opacity,1))}.text-surface-light{--tw-text-opacity:1;color:rgba(var(--color-surface-light-rgb),var(--tw-text-opacity,1))}.text-surface{--tw-text-opacity:1;color:rgba(var(--color-surface-rgb),var(--tw-text-opacity,1))}.text-surface-strong{--tw-text-opacity:1;color:rgba(var(--color-surface-strong-rgb),var(--tw-text-opacity,1))}.text-inverse{--tw-text-opacity:1;color:rgba(var(--color-inverse-rgb),var(--tw-text-opacity,1))}.text-fore-in-light{--tw-text-opacity:1;color:rgba(var(--color-fore-in-light-rgb),var(--tw-text-opacity,1))}.text-fore-in-dark{--tw-text-opacity:1;color:rgba(var(--color-fore-in-dark-rgb),var(--tw-text-opacity,1))}.text-fore{--tw-text-opacity:1;color:rgba(var(--color-fore-rgb),var(--tw-text-opacity,1))}.text-focus{--tw-text-opacity:1;color:rgba(var(--color-focus-rgb),var(--tw-text-opacity,1))}.text-link{--tw-text-opacity:1;color:rgba(var(--color-link-rgb),var(--tw-text-opacity,1))}.text-link-hover{--tw-text-opacity:1;color:rgba(var(--color-link-hover-rgb),var(--tw-text-opacity,1))}.text-current{color:currentColor}.text-inherit{color:inherit}.clip,.ellipsis,.text-clip,.text-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.clip,.text-clip{text-overflow:clip}.whitespace-normal{white-space:normal}.nowrap,.whitespace-nowrap{white-space:nowrap}.pre,.whitespace-pre{white-space:pre}.pre-line,.whitespace-pre-line{white-space:pre-line}.pre-wrap,.whitespace-pre-wrap{white-space:pre-wrap}.break-normal{overflow-wrap:normal;word-break:normal}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.text-opacity-0{--tw-text-opacity:0}.text-opacity-5{--tw-text-opacity:.05}.text-opacity-10{--tw-text-opacity:.1}.text-opacity-20{--tw-text-opacity:.2}.text-opacity-25{--tw-text-opacity:.25}.text-opacity-30{--tw-text-opacity:.3}.text-opacity-40{--tw-text-opacity:.4}.text-opacity-50{--tw-text-opacity:.5}.text-opacity-60{--tw-text-opacity:.6}.text-opacity-70{--tw-text-opacity:.7}.text-opacity-80{--tw-text-opacity:.8}.text-opacity-90{--tw-text-opacity:.9}.text-opacity-95{--tw-text-opacity:.95}.text-opacity-100{--tw-text-opacity:1}.uppercase{text-transform:uppercase}.lowercase{text-transform:lowercase}.capitalize{text-transform:capitalize}.normal-case{text-transform:none}.list-none{list-style-type:none}.list-disc{list-style-type:disc}.list-decimal{list-style-type:decimal}.list-unstyled{list-style-type:none;padding-left:0}.underline{text-decoration-line:underline}.overline{text-decoration-line:overline}.line-through{text-decoration-line:line-through}.no-underline{text-decoration-line:none}.bg-primary{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-500-rgb),var(--tw-bg-opacity,1))}.bg-secondary{--tw-bg-opacity:1;background-color:rgba(var(--color-secondary-500-rgb),var(--tw-bg-opacity,1))}.bg-success{--tw-bg-opacity:1;background-color:rgba(var(--color-success-500-rgb),var(--tw-bg-opacity,1))}.bg-warning{--tw-bg-opacity:1;background-color:rgba(var(--color-warning-500-rgb),var(--tw-bg-opacity,1))}.bg-danger{--tw-bg-opacity:1;background-color:rgba(var(--color-danger-500-rgb),var(--tw-bg-opacity,1))}.bg-important{--tw-bg-opacity:1;background-color:rgba(var(--color-important-500-rgb),var(--tw-bg-opacity,1))}.bg-special{--tw-bg-opacity:1;background-color:rgba(var(--color-special-500-rgb),var(--tw-bg-opacity,1))}.bg-primary-50{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-50-rgb),var(--tw-bg-opacity,1))}.bg-primary-100{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-100-rgb),var(--tw-bg-opacity,1))}.bg-primary-200{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-200-rgb),var(--tw-bg-opacity,1))}.bg-primary-300{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-300-rgb),var(--tw-bg-opacity,1))}.bg-primary-400{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-400-rgb),var(--tw-bg-opacity,1))}.bg-primary-500{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-500-rgb),var(--tw-bg-opacity,1))}.bg-primary-600{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-600-rgb),var(--tw-bg-opacity,1))}.bg-primary-700{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-700-rgb),var(--tw-bg-opacity,1))}.bg-primary-800{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-800-rgb),var(--tw-bg-opacity,1))}.bg-primary-900{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-900-rgb),var(--tw-bg-opacity,1))}.bg-primary-950{--tw-bg-opacity:1;background-color:rgba(var(--color-primary-950-rgb),var(--tw-bg-opacity,1))}.bg-secondary-50{--tw-bg-opacity:1;background-color:rgba(var(--color-secondary-50-rgb),var(--tw-bg-opacity,1))}.bg-secondary-100{--tw-bg-opacity:1;background-color:rgba(var(--color-secondary-100-rgb),var(--tw-bg-opacity,1))}.bg-secondary-200{--tw-bg-opacity:1;background-color:rgba(var(--color-secondary-200-rgb),var(--tw-bg-opacity,1))}.bg-secondary-300{--tw-bg-opacity:1;background-color:rgba(var(--color-secondary-300-rgb),var(--tw-bg-opacity,1))}.bg-secondary-400{--tw-bg-opacity:1;background-color:rgba(var(--color-secondary-400-rgb),var(--tw-bg-opacity,1))}.bg-secondary-500{--tw-bg-opacity:1;background-color:rgba(var(--color-secondary-500-rgb),var(--tw-bg-opacity,1))}.bg-secondary-600{--tw-bg-opacity:1;background-color:rgba(var(--color-secondary-600-rgb),var(--tw-bg-opacity,1))}.bg-secondary-700{--tw-bg-opacity:1;background-color:rgba(var(--color-secondary-700-rgb),var(--tw-bg-opacity,1))}.bg-secondary-800{--tw-bg-opacity:1;background-color:rgba(var(--color-secondary-800-rgb),var(--tw-bg-opacity,1))}.bg-secondary-900{--tw-bg-opacity:1;background-color:rgba(var(--color-secondary-900-rgb),var(--tw-bg-opacity,1))}.bg-secondary-950{--tw-bg-opacity:1;background-color:rgba(var(--color-secondary-950-rgb),var(--tw-bg-opacity,1))}.bg-gray-50{--tw-bg-opacity:1;background-color:rgba(var(--color-gray-50-rgb),var(--tw-bg-opacity,1))}.bg-gray-100{--tw-bg-opacity:1;background-color:rgba(var(--color-gray-100-rgb),var(--tw-bg-opacity,1))}.bg-gray-200,.bg-lightest{--tw-bg-opacity:1;background-color:rgba(var(--color-gray-200-rgb),var(--tw-bg-opacity,1))}.bg-gray-300,.bg-lighter{--tw-bg-opacity:1;background-color:rgba(var(--color-gray-300-rgb),var(--tw-bg-opacity,1))}.bg-gray-400,.bg-light{--tw-bg-opacity:1;background-color:rgba(var(--color-gray-400-rgb),var(--tw-bg-opacity,1))}.bg-gray,.bg-gray-500{--tw-bg-opacity:1;background-color:rgba(var(--color-gray-500-rgb),var(--tw-bg-opacity,1))}.bg-darken,.bg-gray-600{--tw-bg-opacity:1;background-color:rgba(var(--color-gray-600-rgb),var(--tw-bg-opacity,1))}.bg-darker,.bg-gray-700{--tw-bg-opacity:1;background-color:rgba(var(--color-gray-700-rgb),var(--tw-bg-opacity,1))}.bg-darkest,.bg-gray-800{--tw-bg-opacity:1;background-color:rgba(var(--color-gray-800-rgb),var(--tw-bg-opacity,1))}.bg-gray-900{--tw-bg-opacity:1;background-color:rgba(var(--color-gray-900-rgb),var(--tw-bg-opacity,1))}.bg-gray-950{--tw-bg-opacity:1;background-color:rgba(var(--color-gray-950-rgb),var(--tw-bg-opacity,1))}.bg-canvas{--tw-bg-opacity:1;background-color:rgba(var(--color-canvas-rgb),var(--tw-bg-opacity,1))}.bg-surface-light{--tw-bg-opacity:1;background-color:rgba(var(--color-surface-light-rgb),var(--tw-bg-opacity,1))}.bg-surface{--tw-bg-opacity:1;background-color:rgba(var(--color-surface-rgb),var(--tw-bg-opacity,1))}.bg-surface-strong{--tw-bg-opacity:1;background-color:rgba(var(--color-surface-strong-rgb),var(--tw-bg-opacity,1))}.bg-inverse{--tw-bg-opacity:1;background-color:rgba(var(--color-inverse-rgb),var(--tw-bg-opacity,1))}.bg-fore-in-light{--tw-bg-opacity:1;background-color:rgba(var(--color-fore-in-light-rgb),var(--tw-bg-opacity,1))}.bg-fore-in-dark{--tw-bg-opacity:1;background-color:rgba(var(--color-fore-in-dark-rgb),var(--tw-bg-opacity,1))}.bg-fore{--tw-bg-opacity:1;background-color:rgba(var(--color-fore-rgb),var(--tw-bg-opacity,1))}.bg-focus{--tw-bg-opacity:1;background-color:rgba(var(--color-focus-rgb),var(--tw-bg-opacity,1))}.bg-white{--tw-bg-opacity:1;background-color:rgba(var(--color-white-rgb),var(--tw-bg-opacity,1))}.bg-black{--tw-bg-opacity:1;background-color:rgba(var(--color-black-rgb),var(--tw-bg-opacity,1))}.bg-transparent{background-color:transparent}.bg-current{background-color:currentColor}.bg-inherit{background-color:inherit}.bg-none{background-image:none}.bg-opacity-0{--tw-bg-opacity:0}.bg-opacity-5{--tw-bg-opacity:.05}.bg-opacity-10{--tw-bg-opacity:.1}.bg-opacity-20{--tw-bg-opacity:.2}.bg-opacity-25{--tw-bg-opacity:.25}.bg-opacity-30{--tw-bg-opacity:.3}.bg-opacity-40{--tw-bg-opacity:.4}.bg-opacity-50{--tw-bg-opacity:.5}.bg-opacity-60{--tw-bg-opacity:.6}.bg-opacity-70{--tw-bg-opacity:.7}.bg-opacity-80{--tw-bg-opacity:.8}.bg-opacity-90{--tw-bg-opacity:.9}.bg-opacity-100{--tw-bg-opacity:1}.bg-auto{background-size:auto}.bg-cover{background-size:cover}.bg-contain{background-size:contain}.bg-repeat{background-repeat:repeat}.bg-no-repeat{background-repeat:no-repeat}.bg-repeat-x{background-repeat:repeat-x}.bg-repeat-y{background-repeat:repeat-y}.bg-repeat-round{background-repeat:round}.bg-repeat-space{background-repeat:space}.bg-bottom{background-position:bottom}.bg-center{background-position:50%}.bg-left{background-position:0}.bg-left-bottom{background-position:0 100%}.bg-left-top{background-position:0 0}.bg-right{background-position:100%}.bg-right-bottom{background-position:100% 100%}.bg-right-top{background-position:100% 0}.bg-top{background-position:top}.bg-fixed{background-attachment:fixed}.bg-local{background-attachment:local}.bg-scroll{background-attachment:scroll}.divider{align-self:stretch;border-color:currentColor;border-left-width:1px;border-top-width:1px;opacity:.1}.border-0{border-width:0}.border{border-width:1px}.border-2{border-width:2px}.border-4{border-width:4px}.border-t{border-top-width:1px}.border-l{border-left-width:1px}.border-r{border-right-width:1px}.border-b{border-bottom-width:1px}.border-t-0{border-top-width:0}.border-r-0{border-right-width:0}.border-b-0{border-bottom-width:0}.border-l-0{border-left-width:0}.border-t-2{border-top-width:2px}.border-l-2{border-left-width:2px}.border-r-2{border-right-width:2px}.border-b-2{border-bottom-width:2px}.border-t-4{border-top-width:4px}.border-l-4{border-left-width:4px}.border-r-4{border-right-width:4px}.border-b-4{border-bottom-width:4px}.border-light{--tw-border-opacity:1;border-color:rgba(var(--color-border-light-rgb),var(--tw-border-opacity,1))}.border-strong{--tw-border-opacity:1;border-color:rgba(var(--color-border-strong-rgb),var(--tw-border-opacity,1))}.border-primary{--tw-border-opacity:1;border-color:rgba(var(--color-primary-500-rgb),var(--tw-border-opacity,1))}.border-secondary{--tw-border-opacity:1;border-color:rgba(var(--color-secondary-500-rgb),var(--tw-border-opacity,1))}.border-success{--tw-border-opacity:1;border-color:rgba(var(--color-success-500-rgb),var(--tw-border-opacity,1))}.border-warning{--tw-border-opacity:1;border-color:rgba(var(--color-warning-500-rgb),var(--tw-border-opacity,1))}.border-danger{--tw-border-opacity:1;border-color:rgba(var(--color-danger-500-rgb),var(--tw-border-opacity,1))}.border-important{--tw-border-opacity:1;border-color:rgba(var(--color-important-500-rgb),var(--tw-border-opacity,1))}.border-special{--tw-border-opacity:1;border-color:rgba(var(--color-special-500-rgb),var(--tw-border-opacity,1))}.border-gray-50{--tw-border-opacity:1;border-color:rgba(var(--color-gray-50-rgb),var(--tw-border-opacity,1))}.border-gray-100{--tw-border-opacity:1;border-color:rgba(var(--color-gray-100-rgb),var(--tw-border-opacity,1))}.border-gray-200{--tw-border-opacity:1;border-color:rgba(var(--color-gray-200-rgb),var(--tw-border-opacity,1))}.border-gray-300{--tw-border-opacity:1;border-color:rgba(var(--color-gray-300-rgb),var(--tw-border-opacity,1))}.border-gray-400{--tw-border-opacity:1;border-color:rgba(var(--color-gray-400-rgb),var(--tw-border-opacity,1))}.border-gray,.border-gray-500{--tw-border-opacity:1;border-color:rgba(var(--color-gray-500-rgb),var(--tw-border-opacity,1))}.border-gray-600{--tw-border-opacity:1;border-color:rgba(var(--color-gray-600-rgb),var(--tw-border-opacity,1))}.border-gray-700{--tw-border-opacity:1;border-color:rgba(var(--color-gray-700-rgb),var(--tw-border-opacity,1))}.border-gray-800{--tw-border-opacity:1;border-color:rgba(var(--color-gray-800-rgb),var(--tw-border-opacity,1))}.border-gray-900{--tw-border-opacity:1;border-color:rgba(var(--color-gray-900-rgb),var(--tw-border-opacity,1))}.border-gray-950{--tw-border-opacity:1;border-color:rgba(var(--color-gray-950-rgb),var(--tw-border-opacity,1))}.border-white{--tw-border-opacity:1;border-color:rgba(var(--color-white-rgb),var(--tw-border-opacity,1))}.border-black{--tw-border-opacity:1;border-color:rgba(var(--color-black-rgb),var(--tw-border-opacity,1))}.border-canvas{--tw-border-opacity:1;border-color:rgba(var(--color-canvas-rgb),var(--tw-border-opacity,1))}.border-surface-light{--tw-border-opacity:1;border-color:rgba(var(--color-surface-light-rgb),var(--tw-border-opacity,1))}.border-surface{--tw-border-opacity:1;border-color:rgba(var(--color-surface-rgb),var(--tw-border-opacity,1))}.border-surface-strong{--tw-border-opacity:1;border-color:rgba(var(--color-surface-strong-rgb),var(--tw-border-opacity,1))}.border-inverse{--tw-border-opacity:1;border-color:rgba(var(--color-inverse-rgb),var(--tw-border-opacity,1))}.border-fore-in-light{--tw-border-opacity:1;border-color:rgba(var(--color-fore-in-light-rgb),var(--tw-border-opacity,1))}.border-fore-in-dark{--tw-border-opacity:1;border-color:rgba(var(--color-fore-in-dark-rgb),var(--tw-border-opacity,1))}.border-fore{--tw-border-opacity:1;border-color:rgba(var(--color-fore-rgb),var(--tw-border-opacity,1))}.border-focus{--tw-border-opacity:1;border-color:rgba(var(--color-focus-rgb),var(--tw-border-opacity,1))}.border-link{--tw-border-opacity:1;border-color:rgba(var(--color-link-rgb),var(--tw-border-opacity,1))}.border-link-hover{--tw-border-opacity:1;border-color:rgba(var(--color-link-hover-rgb),var(--tw-border-opacity,1))}.border-transparent{border-color:transparent}.border-current{border-color:currentColor}.border-inherit{border-color:inherit}.border-solid{border-style:solid}.border-dashed{border-style:dashed}.border-dotted{border-style:dotted}.border-double{border-style:double}.border-hidden{border-style:hidden}.border-none{border-style:none}.border-opacity-0{--tw-border-opacity:0}.border-opacity-5{--tw-border-opacity:.05}.border-opacity-10{--tw-border-opacity:.1}.border-opacity-20{--tw-border-opacity:.2}.border-opacity-25{--tw-border-opacity:.25}.border-opacity-30{--tw-border-opacity:.3}.border-opacity-40{--tw-border-opacity:.4}.border-opacity-50{--tw-border-opacity:.5}.border-opacity-60{--tw-border-opacity:.6}.border-opacity-70{--tw-border-opacity:.7}.border-opacity-80{--tw-border-opacity:.8}.border-opacity-90{--tw-border-opacity:.9}.border-opacity-95{--tw-border-opacity:.95}.border-opacity-100{--tw-border-opacity:1}.rounded-none{border-radius:var(--radius-none)}.rounded-sm{border-radius:var(--radius-sm)}.rounded{border-radius:var(--radius)}.rounded-md{border-radius:var(--radius-md)}.rounded-lg{border-radius:var(--radius-lg)}.rounded-xl{border-radius:var(--radius-xl)}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-3xl{border-radius:var(--radius-3xl)}.circle,.rounded-full{border-radius:var(--radius-full)}.rounded-l-none{border-bottom-left-radius:var(--radius-none);border-top-left-radius:var(--radius-none)}.rounded-t-none{border-top-left-radius:var(--radius-none)}.rounded-r-none,.rounded-t-none{border-top-right-radius:var(--radius-none)}.rounded-b-none,.rounded-r-none{border-bottom-right-radius:var(--radius-none)}.rounded-b-none{border-bottom-left-radius:var(--radius-none)}.rounded-br-none{border-bottom-right-radius:var(--radius-none)}.rounded-bl-none{border-bottom-left-radius:var(--radius-none)}.rounded-tr-none{border-top-right-radius:var(--radius-none)}.rounded-tl-none{border-top-left-radius:var(--radius-none)}.ring{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-border-rgb),var(--tw-ring-opacity,1))}.ring-border-light{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-border-light-rgb),var(--tw-ring-opacity,1))}.ring-border{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-border-rgb),var(--tw-ring-opacity,1))}.ring-border-strong{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-border-strong-rgb),var(--tw-ring-opacity,1))}.ring-light{--tw-ring-color:rgba(var(--color-inverse-rgb),var(--tw-ring-opacity,1));--tw-ring-opacity:0.05}.ring-gray{--tw-ring-color:rgba(var(--color-inverse-rgb),var(--tw-ring-opacity,1));--tw-ring-opacity:0.1}.ring-dark{--tw-ring-color:rgba(var(--color-inverse-rgb),var(--tw-ring-opacity,1));--tw-ring-opacity:0.2}.ring-darker{--tw-ring-color:rgba(var(--color-inverse-rgb),var(--tw-ring-opacity,1));--tw-ring-opacity:0.3}.ring-darkest{--tw-ring-color:rgba(var(--color-inverse-rgb),var(--tw-ring-opacity,1));--tw-ring-opacity:0.5}.ring-primary{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-primary-500-rgb),var(--tw-ring-opacity,1))}.ring-secondary{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-secondary-500-rgb),var(--tw-ring-opacity,1))}.ring-warning{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-warning-500-rgb),var(--tw-ring-opacity,1))}.ring-success{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-success-500-rgb),var(--tw-ring-opacity,1))}.ring-danger{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-danger-500-rgb),var(--tw-ring-opacity,1))}.ring-important{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-important-500-rgb),var(--tw-ring-opacity,1))}.ring-special{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-special-500-rgb),var(--tw-ring-opacity,1))}.ring-gray-50{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-gray-50-rgb),var(--tw-ring-opacity,1))}.ring-gray-100{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-gray-100-rgb),var(--tw-ring-opacity,1))}.ring-gray-200{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-gray-200-rgb),var(--tw-ring-opacity,1))}.ring-gray-300{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-gray-300-rgb),var(--tw-ring-opacity,1))}.ring-gray-400{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-gray-400-rgb),var(--tw-ring-opacity,1))}.ring-gray-500{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-gray-500-rgb),var(--tw-ring-opacity,1))}.ring-gray-600{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-gray-600-rgb),var(--tw-ring-opacity,1))}.ring-gray-700{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-gray-700-rgb),var(--tw-ring-opacity,1))}.ring-gray-800{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-gray-800-rgb),var(--tw-ring-opacity,1))}.ring-gray-900{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-gray-900-rgb),var(--tw-ring-opacity,1))}.ring-gray-950{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-gray-950-rgb),var(--tw-ring-opacity,1))}.ring-inverse{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-inverse-rgb),var(--tw-ring-opacity,1))}.ring-canvas{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-canvas-rgb),var(--tw-ring-opacity,1))}.ring-surface{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-surface-rgb),var(--tw-ring-opacity,1))}.ring-fore{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-fore-rgb),var(--tw-ring-opacity,1))}.ring-transparent{--tw-ring-color:transparent}.ring-black{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-black-rgb),var(--tw-ring-opacity,1))}.ring-white{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--color-white-rgb),var(--tw-ring-opacity,1))}.ring-inherit{--tw-ring-color:inherit}.ring-current{--tw-ring-color:currentColor}.ring-opacity-0{--tw-ring-opacity:0}.ring-opacity-5{--tw-ring-opacity:.05}.ring-opacity-10{--tw-ring-opacity:.1}.ring-opacity-20{--tw-ring-opacity:.2}.ring-opacity-30{--tw-ring-opacity:.3}.ring-opacity-40{--tw-ring-opacity:.4}.ring-opacity-50{--tw-ring-opacity:.5}.ring-opacity-60{--tw-ring-opacity:.6}.ring-opacity-70{--tw-ring-opacity:.7}.ring-opacity-80{--tw-ring-opacity:.8}.ring-opacity-90{--tw-ring-opacity:.9}.ring-opacity-100{--tw-ring-opacity:1}.ring-0{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color)}.ring-0,.ring-2{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.ring-2{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color)}.ring-3{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color)}.ring-3,.ring-4{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.ring-4{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color)}.ring-8{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(8px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.ring-inset{--tw-ring-inset:inset}.ring-offset-0{--tw-ring-offset-width:0px}.ring-offset-1{--tw-ring-offset-width:1px}.ring-offset-2{--tw-ring-offset-width:2px}.ring-offset-4{--tw-ring-offset-width:4px}.ring-offset-8{--tw-ring-offset-width:8px}.shadow-sm{--tw-shadow:0 1px 2px 0 rgba(0,0,0,.04),0 0 2px -1px rgba(0,0,0,.01);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color),0 0 2px -1px var(--tw-shadow-color)}.shadow,.shadow-sm{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow{--tw-shadow:0 3px 8px 0 rgba(0,0,0,.04),0 1px 2px -1px rgba(0,0,0,.01);--tw-shadow-colored:0 3px 8px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color)}.shadow-md{--tw-shadow:0 2px 6px -1px rgba(0,0,0,.2),0 1px 4px -2px rgba(0,0,0,.15);--tw-shadow-colored:0 2px 6px -1px var(--tw-shadow-color),0 1px 4px -2px var(--tw-shadow-color)}.shadow-lg,.shadow-md{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 5px 15px -3px rgba(0,0,0,.2),0 2px 6px -4px rgba(0,0,0,.15);--tw-shadow-colored:0 5px 15px -3px var(--tw-shadow-color),0 2px 6px -4px var(--tw-shadow-color)}.shadow-xl{--tw-shadow:0 10px 25px -5px rgba(0,0,0,.2),0 4px 10px -6px rgba(0,0,0,.15);--tw-shadow-colored:0 10px 25px -5px var(--tw-shadow-color),0 4px 10px -6px var(--tw-shadow-color)}.shadow-2xl,.shadow-xl{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-2xl{--tw-shadow:0 10px 50px -10px rgba(0,0,0,.4),0 8px 20px -10px rgba(0,0,0,.3);--tw-shadow-colored:0 10px 50px -10px var(--tw-shadow-color),0 8px 20px -10px var(--tw-shadow-color)}.shadow-inner{--tw-shadow:inset 0 2px 4px 0 rgba(0,0,0,.05);--tw-shadow-colored:inset 0 2px 4px 0 var(--tw-shadow-color)}.shadow-inner,.shadow-none{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-none{--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000}.muted{opacity:var(--opacity-muted)}.opacity-0{opacity:0}.opacity-5{opacity:.05}.opacity-10{opacity:.1}.opacity-20{opacity:.2}.opacity-25{opacity:.25}.opacity-30{opacity:.3}.opacity-40{opacity:.4}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-75{opacity:.75}.opacity-80{opacity:.8}.opacity-90{opacity:.9}.opacity-95{opacity:.95}.opacity-100{opacity:1}.blur-none{--tw-blur: }.blur-none,.blur-sm{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.blur-sm{--tw-blur:blur(4px)}.blur{--tw-blur:blur(8px)}.blur,.blur-md{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.blur-md{--tw-blur:blur(12px)}.blur-lg{--tw-blur:blur(16px)}.blur-lg,.blur-xl{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.blur-xl{--tw-blur:blur(24px)}.grayscale{--tw-grayscale:grayscale(100%)}.grayscale,.invert{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.invert{--tw-invert:invert(100%)}.filter-none{filter:none!important}.drop-shadow-none{--tw-drop-shadow:drop-shadow(0 0 #0000)}.drop-shadow-none,.drop-shadow-sm{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.drop-shadow-sm{--tw-drop-shadow:drop-shadow(0 1px 1px rgba(0,0,0,.05))}.drop-shadow{--tw-drop-shadow:drop-shadow(0 1px 2px rgba(0,0,0,.1)) drop-shadow(0 1px 1px rgba(0,0,0,.06))}.drop-shadow,.drop-shadow-md{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.drop-shadow-md{--tw-drop-shadow:drop-shadow(0 4px 3px rgba(0,0,0,.07)) drop-shadow(0 2px 2px rgba(0,0,0,.06))}.drop-shadow-lg{--tw-drop-shadow:drop-shadow(0 10px 8px rgba(0,0,0,.04)) drop-shadow(0 4px 3px rgba(0,0,0,.1))}.drop-shadow-lg,.drop-shadow-xl{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.drop-shadow-xl{--tw-drop-shadow:drop-shadow(0 20px 13px rgba(0,0,0,.03)) drop-shadow(0 8px 5px rgba(0,0,0,.08))}.drop-shadow-2xl{--tw-drop-shadow:drop-shadow(0 25px 25px rgba(0,0,0,.15));filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-none{--tw-backdrop-blur: }.backdrop-blur-none,.backdrop-blur-sm{backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-sm{--tw-backdrop-blur:blur(4px)}.backdrop-blur{--tw-backdrop-blur:blur(8px)}.backdrop-blur,.backdrop-blur-md{backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-md{--tw-backdrop-blur:blur(12px)}.backdrop-blur-lg{--tw-backdrop-blur:blur(16px)}.backdrop-blur-lg,.backdrop-blur-xl{backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-xl{--tw-backdrop-blur:blur(24px)}.backdrop-blur-2xl{--tw-backdrop-blur:blur(40px)}.backdrop-blur-2xl,.backdrop-blur-3xl{backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-3xl{--tw-backdrop-blur:blur(64px)}.transition{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-all{transition-duration:.15s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-colors{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-opacity{transition-duration:.15s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-shadow{transition-duration:.15s;transition-property:box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-transform{transition-duration:.15s;transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-none{transition-property:none}.fade,.fade-from-bottom,.fade-from-center,.fade-from-left,.fade-from-right,.fade-from-top{opacity:0;transition-duration:.15s;transition-property:opacity,transform;transition-timing-function:cubic-bezier(.4,0,.2,1)}.fade-from-bottom,.fade-from-center,.fade-from-left,.fade-from-right,.fade-from-top{--tw-scale-x:.9;--tw-scale-y:.9}.fade-from-bottom,.fade-from-center,.fade-from-left,.fade-from-right,.fade-from-top{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.fade-from-bottom{--tw-translate-y:25%}.fade-from-top{--tw-translate-y:-25%}.fade-from-left,.fade-from-top{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.fade-from-left{--tw-translate-x:-25%}.fade-from-right{--tw-translate-x:25%}.fade-from-bottom.in,.fade-from-center.in,.fade-from-left.in,.fade-from-right,.fade-from-right.in,.fade-from-top.in,.fade.in{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.fade-from-bottom.in,.fade-from-center.in,.fade-from-left.in,.fade-from-right.in,.fade-from-top.in,.fade.in{--tw-translate-x:0px;--tw-translate-y:0px;--tw-scale-x:1;--tw-scale-y:1;opacity:1}.duration-75{transition-duration:75ms}.duration-100{transition-duration:.1s}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}.duration-500{transition-duration:.5s}.duration-1000{transition-duration:1s}@keyframes -spin{to{transform:rotate(1turn)}}.animate-spin,.spin{animation:-spin 1s linear infinite}@keyframes -ping{75%,to{opacity:0;transform:scale(2)}}.animate-ping,.ping{animation:-ping 1s cubic-bezier(0,0,.2,1) infinite}@keyframes -pulse{50%{opacity:.5}}.animate-pulse,.pulse{animation:-pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes -bounce{0%,to{animation-timing-function:cubic-bezier(.8,0,1,1);transform:translateY(-25%)}50%{animation-timing-function:cubic-bezier(0,0,.2,1);transform:none}}.animate-bounce,.bounce{animation:-bounce 1s infinite}.animate-highlight,.highlight{animation:-highlight 2s ease-in-out infinite;outline-color:#fde047;outline-offset:-1px;outline-style:solid;outline-width:1px}@keyframes -highlight{50%{--tw-bg-opacity:1;background-color:rgb(254 252 232/var(--tw-bg-opacity,1));outline-offset:-4px;outline-width:4px}}.scale-0{--tw-scale-x:0;--tw-scale-y:0}.scale-0,.scale-50{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-50{--tw-scale-x:.5;--tw-scale-y:.5}.scale-75{--tw-scale-x:.75;--tw-scale-y:.75}.scale-75,.scale-90{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-90{--tw-scale-x:.9;--tw-scale-y:.9}.scale-95{--tw-scale-x:.95;--tw-scale-y:.95}.scale-100,.scale-95{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-100{--tw-scale-x:1;--tw-scale-y:1}.scale-105{--tw-scale-x:1.05;--tw-scale-y:1.05}.scale-105,.scale-110{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-110{--tw-scale-x:1.1;--tw-scale-y:1.1}.scale-125{--tw-scale-x:1.25;--tw-scale-y:1.25}.scale-125,.scale-150{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-150{--tw-scale-x:1.5;--tw-scale-y:1.5}.flip-x{--tw-scale-x:-1}.flip-x,.flip-y{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.flip-y{--tw-scale-y:-1}.rotate-0{--tw-rotate:0deg}.rotate-0,.rotate-1{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-1{--tw-rotate:1deg}.rotate-2{--tw-rotate:2deg}.rotate-2,.rotate-3{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-3{--tw-rotate:3deg}.rotate-6{--tw-rotate:6deg}.rotate-12,.rotate-6{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-12{--tw-rotate:12deg}.rotate-45{--tw-rotate:45deg}.rotate-45,.rotate-90{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-90{--tw-rotate:90deg}.rotate-135{--tw-rotate:135deg}.rotate-135,.rotate-180{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-180{--tw-rotate:180deg}.rotate-270{--tw-rotate:270deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.basis-0{flex-basis:0px}.basis-1{flex-basis:0.25rem}.basis-2{flex-basis:0.5rem}.basis-3{flex-basis:0.75rem}.basis-4{flex-basis:1rem}.basis-5{flex-basis:1.25rem}.basis-6{flex-basis:1.5rem}.basis-7{flex-basis:1.75rem}.basis-8{flex-basis:2rem}.basis-9{flex-basis:2.25rem}.basis-10{flex-basis:2.5rem}.basis-11{flex-basis:2.75rem}.basis-12{flex-basis:3rem}.basis-14{flex-basis:3.5rem}.basis-16{flex-basis:4rem}.basis-20{flex-basis:5rem}.basis-24{flex-basis:6rem}.basis-28{flex-basis:7rem}.basis-32{flex-basis:8rem}.basis-36{flex-basis:9rem}.basis-40{flex-basis:10rem}.basis-44{flex-basis:11rem}.basis-48{flex-basis:12rem}.basis-52{flex-basis:13rem}.basis-56{flex-basis:14rem}.basis-60{flex-basis:15rem}.basis-64{flex-basis:16rem}.basis-72{flex-basis:18rem}.basis-80{flex-basis:20rem}.basis-96{flex-basis:24rem}.basis-auto{flex-basis:auto}.basis-px{flex-basis:1px}.basis-0\.5{flex-basis:0.125rem}.basis-1\.5{flex-basis:0.375rem}.basis-2\.5{flex-basis:0.625rem}.basis-3\.5{flex-basis:0.875rem}.basis-1\/2{flex-basis:50%}.basis-1\/3{flex-basis:33.333333%}.basis-2\/3{flex-basis:66.666667%}.basis-1\/4{flex-basis:25%}.basis-2\/4{flex-basis:50%}.basis-3\/4{flex-basis:75%}.basis-1\/5{flex-basis:20%}.basis-2\/5{flex-basis:40%}.basis-3\/5{flex-basis:60%}.basis-4\/5{flex-basis:80%}.basis-1\/6{flex-basis:16.666667%}.basis-2\/6{flex-basis:33.333333%}.basis-3\/6{flex-basis:50%}.basis-4\/6{flex-basis:66.666667%}.basis-5\/6{flex-basis:83.333333%}.basis-1\/12{flex-basis:8.333333%}.basis-2\/12{flex-basis:16.666667%}.basis-3\/12{flex-basis:25%}.basis-4\/12{flex-basis:33.333333%}.basis-5\/12{flex-basis:41.666667%}.basis-6\/12{flex-basis:50%}.basis-7\/12{flex-basis:58.333333%}.basis-8\/12{flex-basis:66.666667%}.basis-9\/12{flex-basis:75%}.basis-10\/12{flex-basis:83.333333%}.basis-11\/12{flex-basis:91.666667%}.basis-full{flex-basis:100%}.row{display:flex;flex-direction:row}.center,.col{display:flex;flex-direction:column}.center,.center-row{align-items:center;justify-content:center}.center-row{display:flex;flex-direction:row}.center-x,.center-y{align-items:center;display:flex}.center-y{flex-direction:column}.row-reverse{display:flex;flex-direction:row-reverse}.col-reverse{display:flex;flex-direction:column-reverse}.flex-wrap{flex-wrap:wrap}.flex-wrap-reverse{flex-wrap:wrap-reverse}.flex-nowrap{flex-wrap:nowrap}.flex-1{flex:1 1 0%}.flex-auto{flex:1 1 auto}.flex-initial{flex:0 1 auto}.flex-none{flex:none}.grow{flex-grow:1!important}.grow-0{flex-grow:0!important}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.order-1{order:1}.order-2{order:2}.order-3{order:3}.order-4{order:4}.order-5{order:5}.order-6{order:6}.order-7{order:7}.order-8{order:8}.order-9{order:9}.order-10{order:10}.order-11{order:11}.order-12{order:12}.order-first{order:-9999}.order-last{order:9999}.order-none{order:0}.gap-0{gap:0}.gap-x-0{-moz-column-gap:0;column-gap:0}.gap-y-0{row-gap:0}.gap-px{gap:1px}.gap-x-px{-moz-column-gap:1px;column-gap:1px}.gap-y-px{row-gap:1px}.gap-0\.5{gap:.125rem}.gap-x-0\.5{-moz-column-gap:.125rem;column-gap:.125rem}.gap-y-0\.5{row-gap:.125rem}.gap-3px{gap:3px}.gap-1{gap:.25rem}.gap-x-1{-moz-column-gap:.25rem;column-gap:.25rem}.gap-y-1{row-gap:.25rem}.gap-1\.5{gap:.375rem}.gap-x-1\.5{-moz-column-gap:.375rem;column-gap:.375rem}.gap-y-1\.5{row-gap:.375rem}.gap-2{gap:.5rem}.gap-x-2{-moz-column-gap:.5rem;column-gap:.5rem}.gap-y-2{row-gap:.5rem}.gap-2\.5{gap:.625rem}.gap-x-2\.5{-moz-column-gap:.625rem;column-gap:.625rem}.gap-y-2\.5{row-gap:.625rem}.gap-3{gap:.75rem}.gap-x-3{-moz-column-gap:.75rem;column-gap:.75rem}.gap-y-3{row-gap:.75rem}.gap-3\.5{gap:.875rem}.gap-x-3\.5{-moz-column-gap:.875rem;column-gap:.875rem}.gap-y-3\.5{row-gap:.875rem}.gap-4{gap:1rem}.gap-x-4{-moz-column-gap:1rem;column-gap:1rem}.gap-y-4{row-gap:1rem}.gap-5{gap:1.25rem}.gap-x-5{-moz-column-gap:1.25rem;column-gap:1.25rem}.gap-y-5{row-gap:1.25rem}.gap-6{gap:1.5rem}.gap-x-6{-moz-column-gap:1.5rem;column-gap:1.5rem}.gap-y-6{row-gap:1.5rem}.gap-7{gap:1.75rem}.gap-x-7{-moz-column-gap:1.75rem;column-gap:1.75rem}.gap-y-7{row-gap:1.75rem}.gap-8{gap:2rem}.gap-x-8{-moz-column-gap:2rem;column-gap:2rem}.gap-y-8{row-gap:2rem}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.justify-around{justify-content:space-around}.justify-evenly{justify-content:space-evenly}.self-auto{align-self:auto}.self-start{align-self:flex-start}.self-end{align-self:flex-end}.self-center{align-self:center}.self-stretch{align-self:stretch}.self-baseline{align-self:baseline}.content-center{align-content:center}.content-start{align-content:flex-start}.content-end{align-content:flex-end}.content-between{align-content:space-between}.content-around{align-content:space-around}.content-evenly{align-content:space-evenly}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-baseline{align-items:baseline}.items-stretch{align-items:stretch}@font-face{font-display:fallback;font-family:D-DIN-PRO;font-weight:400;src:url(./fonts/D-DIN-PRO-400-Regular.otf)}@font-face{font-display:fallback;font-family:D-DIN-PRO;font-weight:500;src:url(./fonts/D-DIN-PRO-700-Bold.otf)}.num{font-family:D-DIN-PRO}@font-face{font-display:fallback;font-family:Nunito;font-weight:400;src:url(./fonts/Nunito-Regular.ttf)}@font-face{font-display:fallback;font-family:Nunito;font-weight:700;src:url(./fonts/Nunito-Bold.ttf)}@font-face{font-display:fallback;font-family:Nunito;font-weight:300;src:url(./fonts/Nunito-Light.ttf)}.font-brand{font-family:Nunito;font-weight:400}@supports not (gap:4px){.gap-px>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1px*(1 - var(--tw-space-x-reverse)));margin-right:calc(1px*var(--tw-space-x-reverse))}.gap-0\.5>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(2px*(1 - var(--tw-space-x-reverse)));margin-right:calc(2px*var(--tw-space-x-reverse))}.gap-3px>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(3px*(1 - var(--tw-space-x-reverse)));margin-right:calc(3px*var(--tw-space-x-reverse))}.gap-1>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.25rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.25rem*var(--tw-space-x-reverse))}.gap-1\.5>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(6px*(1 - var(--tw-space-x-reverse)));margin-right:calc(6px*var(--tw-space-x-reverse))}.gap-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.5rem*var(--tw-space-x-reverse))}.gap-2\.5>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(10px*(1 - var(--tw-space-x-reverse)));margin-right:calc(10px*var(--tw-space-x-reverse))}.gap-3>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.75rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.75rem*var(--tw-space-x-reverse))}.gap-3\.5>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(14px*(1 - var(--tw-space-x-reverse)));margin-right:calc(14px*var(--tw-space-x-reverse))}.gap-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1rem*var(--tw-space-x-reverse))}.gap-5>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1.25rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1.25rem*var(--tw-space-x-reverse))}.gap-6>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1.5rem*var(--tw-space-x-reverse))}.gap-7>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1.75rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1.75rem*var(--tw-space-x-reverse))}.gap-8>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(2rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(2rem*var(--tw-space-x-reverse))}.col.gap-px>:not([hidden])~:not([hidden]),.gap-px.flex-row>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1px*var(--tw-space-y-reverse));margin-top:calc(1px*(1 - var(--tw-space-y-reverse)))}.col.gap-0\.5>:not([hidden])~:not([hidden]),.gap-0\.5.flex-row>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(2px*var(--tw-space-y-reverse));margin-top:calc(2px*(1 - var(--tw-space-y-reverse)))}.col.gap-3px>:not([hidden])~:not([hidden]),.gap-3px.flex-row>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(3px*var(--tw-space-y-reverse));margin-top:calc(3px*(1 - var(--tw-space-y-reverse)))}.col.gap-1>:not([hidden])~:not([hidden]),.gap-1.flex-row>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.25rem*var(--tw-space-y-reverse));margin-top:calc(.25rem*(1 - var(--tw-space-y-reverse)))}.col.gap-1\.5>:not([hidden])~:not([hidden]),.gap-1\.5.flex-row>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(6px*var(--tw-space-y-reverse));margin-top:calc(6px*(1 - var(--tw-space-y-reverse)))}.col.gap-2>:not([hidden])~:not([hidden]),.gap-2.flex-row>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.5rem*var(--tw-space-y-reverse));margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)))}.col.gap-2\.5>:not([hidden])~:not([hidden]),.gap-2\.5.flex-row>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(10px*var(--tw-space-y-reverse));margin-top:calc(10px*(1 - var(--tw-space-y-reverse)))}.col.gap-3>:not([hidden])~:not([hidden]),.gap-3.flex-row>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.75rem*var(--tw-space-y-reverse));margin-top:calc(.75rem*(1 - var(--tw-space-y-reverse)))}.col.gap-3\.5>:not([hidden])~:not([hidden]),.gap-3\.5.flex-row>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(14px*var(--tw-space-y-reverse));margin-top:calc(14px*(1 - var(--tw-space-y-reverse)))}.col.gap-4>:not([hidden])~:not([hidden]),.gap-4.flex-row>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1rem*var(--tw-space-y-reverse));margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)))}.col.gap-5>:not([hidden])~:not([hidden]),.gap-5.flex-row>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1.25rem*var(--tw-space-y-reverse));margin-top:calc(1.25rem*(1 - var(--tw-space-y-reverse)))}.col.gap-6>:not([hidden])~:not([hidden]),.gap-6.flex-row>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1.5rem*var(--tw-space-y-reverse));margin-top:calc(1.5rem*(1 - var(--tw-space-y-reverse)))}.col.gap-7>:not([hidden])~:not([hidden]),.gap-7.flex-row>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1.75rem*var(--tw-space-y-reverse));margin-top:calc(1.75rem*(1 - var(--tw-space-y-reverse)))}.col.gap-8>:not([hidden])~:not([hidden]),.gap-8.flex-row>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(2rem*var(--tw-space-y-reverse));margin-top:calc(2rem*(1 - var(--tw-space-y-reverse)))}.nav-item>a>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.25rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.25rem*var(--tw-space-x-reverse))}} \ No newline at end of file diff --git a/www/js/zui3/zui.zentao.js b/www/js/zui3/zui.zentao.js index f30499096c..c0d30a0eee 100644 --- a/www/js/zui3/zui.zentao.js +++ b/www/js/zui3/zui.zentao.js @@ -1,24 +1,25 @@ -var md=(N,ct,Ft)=>{if(!ct.has(N))throw TypeError("Cannot "+Ft)};var Ot=(N,ct,Ft)=>(md(N,ct,"read from private field"),Ft?Ft.call(N):ct.get(N)),Xt=(N,ct,Ft)=>{if(ct.has(N))throw TypeError("Cannot add the same private member more than once");ct instanceof WeakSet?ct.add(N):ct.set(N,Ft)},sn=(N,ct,Ft,Ml)=>(md(N,ct,"write to private field"),Ml?Ml.call(N,Ft):ct.set(N,Ft),Ft);var gd=(N,ct,Ft)=>(md(N,ct,"access private method"),Ft);(function(N,ct){typeof exports=="object"&&typeof module<"u"?ct(exports):typeof define=="function"&&define.amd?define(["exports"],ct):(N=typeof globalThis<"u"?globalThis:N||self,ct(N.zui={}))})(this,function(N){var nl,sl,jr,Br,Hr,Ur,Wr,Vr,il,ev,rl,tv,ps,ms,fy,py;"use strict";const ct="",Ft="",Ml="",zk="",Ok="",Fk="",jk="",Bk="",Hk="",Uk="",Wk="",Vk="",Al="3.0.0",lv="production",wd="27ba9ba8b0dee6fb0aedff94a30577f09d7e86fe",Mn=document,ao=window,Cd=Mn.documentElement,ks=Mn.createElement.bind(Mn),kd=ks("div"),Pl=ks("table"),cv=ks("tbody"),Sd=ks("tr"),{isArray:lo,prototype:xd}=Array,{concat:hv,filter:Ll,indexOf:Dd,map:Td,push:uv,slice:$d,some:Rl,splice:dv}=xd,fv=/^#(?:[\w-]|\\.|[^\x00-\xa0])*$/,pv=/^\.(?:[\w-]|\\.|[^\x00-\xa0])*$/,mv=/<.+>/,gv=/^\w+$/;function zl(s,e){const t=yv(e);return!s||!t&&!Ss(e)&&!dt(e)?[]:!t&&pv.test(s)?e.getElementsByClassName(s.slice(1).replace(/\\/g,"")):!t&&gv.test(s)?e.getElementsByTagName(s):e.querySelectorAll(s)}class co{constructor(e,t){if(!e)return;if(Ol(e))return e;let n=e;if(It(e)){const i=t||Mn;if(n=fv.test(e)&&Ss(i)?i.getElementById(e.slice(1).replace(/\\/g,"")):mv.test(e)?Pd(e):Ol(i)?i.find(e):It(i)?g(i).find(e):zl(e,i),!n)return}else if(xs(e))return this.ready(e);(n.nodeType||n===ao)&&(n=[n]),this.length=n.length;for(let i=0,r=this.length;i{for(;e.firstChild;)e.removeChild(e.firstChild)})};function ho(...s){const e=bv(s[0])?s.shift():!1,t=s.shift(),n=s.length;if(!t)return{};if(!n)return ho(e,g,t);for(let i=0;i{dt(r)&&_t(t,(o,a)=>{n?e?r.classList.add(a):r.classList.remove(a):r.classList.toggle(a)})})},ae.addClass=function(s){return this.toggleClass(s,!0)},ae.removeAttr=function(s){const e=uo(s);return this.each((t,n)=>{dt(n)&&_t(e,(i,r)=>{n.removeAttribute(r)})})};function wv(s,e){if(s){if(It(s)){if(arguments.length<2){if(!this[0]||!dt(this[0]))return;const t=this[0].getAttribute(s);return Wi(t)?void 0:t}return jt(e)?this:Wi(e)?this.removeAttr(s):this.each((t,n)=>{dt(n)&&n.setAttribute(s,e)})}for(const t in s)this.attr(t,s[t]);return this}}ae.attr=wv,ae.removeClass=function(s){return arguments.length?this.toggleClass(s,!1):this.attr("class","")},ae.hasClass=function(s){return!!s&&Rl.call(this,e=>dt(e)&&e.classList.contains(s))},ae.get=function(s){return jt(s)?$d.call(this):(s=Number(s),this[s<0?s+this.length:s])},ae.eq=function(s){return g(this.get(s))},ae.first=function(){return this.eq(0)},ae.last=function(){return this.eq(-1)};function Cv(s){return jt(s)?this.get().map(e=>dt(e)||vv(e)?e.textContent:"").join(""):this.each((e,t)=>{dt(t)&&(t.textContent=s)})}ae.text=Cv;function An(s,e,t){if(!dt(s))return;const n=ao.getComputedStyle(s,null);return t?n.getPropertyValue(e)||void 0:n[e]||s.style[e]}function yn(s,e){return parseInt(An(s,e),10)||0}function Nd(s,e){return yn(s,`border${e?"Left":"Top"}Width`)+yn(s,`padding${e?"Left":"Top"}`)+yn(s,`padding${e?"Right":"Bottom"}`)+yn(s,`border${e?"Right":"Bottom"}Width`)}const jl={};function kv(s){if(jl[s])return jl[s];const e=ks(s);Mn.body.insertBefore(e,null);const t=An(e,"display");return Mn.body.removeChild(e),jl[s]=t!=="none"?t:"block"}function Ed(s){return An(s,"display")==="none"}function Md(s,e){const t=s&&(s.matches||s.webkitMatchesSelector||s.msMatchesSelector);return!!t&&!!e&&t.call(s,e)}function fo(s){return It(s)?(e,t)=>Md(t,s):xs(s)?s:Ol(s)?(e,t)=>s.is(t):s?(e,t)=>t===s:()=>!1}ae.filter=function(s){const e=fo(s);return g(Ll.call(this,(t,n)=>e.call(t,n,t)))};function Gn(s,e){return e?s.filter(e):s}ae.detach=function(s){return Gn(this,s).each((e,t)=>{t.parentNode&&t.parentNode.removeChild(t)}),this};const Sv=/^\s*<(\w+)[^>]*>/,xv=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,Ad={"*":kd,tr:cv,td:Sd,th:Sd,thead:Pl,tbody:Pl,tfoot:Pl};function Pd(s){if(!It(s))return[];if(xv.test(s))return[ks(RegExp.$1)];const e=Sv.test(s)&&RegExp.$1,t=Ad[e]||Ad["*"];return t.innerHTML=s,g(t.childNodes).detach().get()}g.parseHTML=Pd,ae.has=function(s){const e=It(s)?(t,n)=>zl(s,n).length:(t,n)=>n.contains(s);return this.filter(e)},ae.not=function(s){const e=fo(s);return this.filter((t,n)=>(!It(s)||dt(n))&&!e.call(n,t,n))};function Pn(s,e,t,n){const i=[],r=xs(e),o=n&&fo(n);for(let a=0,l=s.length;ae.selected&&!e.disabled&&!e.parentNode.disabled),"value"):s.value||""}function Dv(s){return arguments.length?this.each((e,t)=>{const n=t.multiple&&t.options;if(n||Kd.test(t.type)){const i=lo(s)?Td.call(s,String):Wi(s)?[]:[String(s)];n?_t(t.options,(r,o)=>{o.selected=i.indexOf(o.value)>=0},!0):t.checked=i.indexOf(t.value)>=0}else t.value=jt(s)||Wi(s)?"":s}):this[0]&&Ld(this[0])}ae.val=Dv,ae.is=function(s){const e=fo(s);return Rl.call(this,(t,n)=>e.call(t,n,t))},g.guid=1;function vn(s){return s.length>1?Ll.call(s,(e,t,n)=>Dd.call(n,e)===t):s}g.unique=vn,ae.add=function(s,e){return g(vn(this.get().concat(g(s,e).get())))},ae.children=function(s){return Gn(g(vn(Pn(this,e=>e.children))),s)},ae.parent=function(s){return Gn(g(vn(Pn(this,"parentNode"))),s)},ae.index=function(s){const e=s?g(s)[0]:this[0],t=s?this:g(e).parent().children();return Dd.call(t,e)},ae.closest=function(s){const e=this.filter(s);if(e.length)return e;const t=this.parent();return t.length?t.closest(s):e},ae.siblings=function(s){return Gn(g(vn(Pn(this,e=>g(e).parent().children().not(e)))),s)},ae.find=function(s){return g(vn(Pn(this,e=>zl(s,e))))};const Tv=/^\s*\s*$/g,$v=/^$|^module$|\/(java|ecma)script/i,Iv=["type","src","nonce","noModule"];function Nv(s,e){const t=g(s);t.filter("script").add(t.find("script")).each((n,i)=>{if($v.test(i.type)&&Cd.contains(i)){const r=ks("script");r.text=i.textContent.replace(Tv,""),_t(Iv,(o,a)=>{i[a]&&(r[a]=i[a])}),e.head.insertBefore(r,null),e.head.removeChild(r)}})}function Ev(s,e,t,n,i){n?s.insertBefore(e,t?s.firstChild:null):s.nodeName==="HTML"?s.parentNode.replaceChild(e,s):s.parentNode.insertBefore(e,t?s:s.nextSibling),i&&Nv(e,s.ownerDocument)}function Yn(s,e,t,n,i,r,o,a){return _t(s,(l,c)=>{_t(g(c),(h,u)=>{_t(g(e),(f,m)=>{const b=t?u:m,C=t?m:u,w=t?h:f;Ev(b,w?C.cloneNode(!0):C,n,i,!w)},a)},o)},r),e}ae.after=function(){return Yn(arguments,this,!1,!1,!1,!0,!0)},ae.append=function(){return Yn(arguments,this,!1,!1,!0)};function Mv(s){if(!arguments.length)return this[0]&&this[0].innerHTML;if(jt(s))return this;const e=/]/.test(s);return this.each((t,n)=>{dt(n)&&(e?g(n).empty().append(s):n.innerHTML=s)})}ae.html=Mv,ae.appendTo=function(s){return Yn(arguments,this,!0,!1,!0)},ae.wrapInner=function(s){return this.each((e,t)=>{const n=g(t),i=n.contents();i.length?i.wrapAll(s):n.append(s)})},ae.before=function(){return Yn(arguments,this,!1,!0)},ae.wrapAll=function(s){let e=g(s),t=e[0];for(;t.children.length;)t=t.firstElementChild;return this.first().before(e),this.appendTo(t)},ae.wrap=function(s){return this.each((e,t)=>{const n=g(s)[0];g(t).wrapAll(e?n.cloneNode(!0):n)})},ae.insertAfter=function(s){return Yn(arguments,this,!0,!1,!1,!1,!1,!0)},ae.insertBefore=function(s){return Yn(arguments,this,!0,!0)},ae.prepend=function(){return Yn(arguments,this,!1,!0,!0,!0,!0)},ae.prependTo=function(s){return Yn(arguments,this,!0,!0,!0,!1,!1,!0)},ae.contents=function(){return g(vn(Pn(this,s=>s.tagName==="IFRAME"?[s.contentDocument]:s.tagName==="TEMPLATE"?s.content.childNodes:s.childNodes)))},ae.next=function(s,e,t){return Gn(g(vn(Pn(this,"nextElementSibling",e,t))),s)},ae.nextAll=function(s){return this.next(s,!0)},ae.nextUntil=function(s,e){return this.next(e,!0,s)},ae.parents=function(s,e){return Gn(g(vn(Pn(this,"parentElement",!0,e))),s)},ae.parentsUntil=function(s,e){return this.parents(e,s)},ae.prev=function(s,e,t){return Gn(g(vn(Pn(this,"previousElementSibling",e,t))),s)},ae.prevAll=function(s){return this.prev(s,!0)},ae.prevUntil=function(s,e){return this.prev(e,!0,s)},ae.map=function(s){return g(hv.apply([],Td.call(this,(e,t)=>s.call(e,t,e))))},ae.clone=function(){return this.map((s,e)=>e.cloneNode(!0))},ae.offsetParent=function(){return this.map((s,e)=>{let t=e.offsetParent;for(;t&&An(t,"position")==="static";)t=t.offsetParent;return t||Cd})},ae.slice=function(s,e){return g($d.call(this,s,e))};const Av=/-([a-z])/g;function Bl(s){return s.replace(Av,(e,t)=>t.toUpperCase())}ae.ready=function(s){const e=()=>setTimeout(s,0,g);return Mn.readyState!=="loading"?e():Mn.addEventListener("DOMContentLoaded",e),this},ae.unwrap=function(){return this.parent().each((s,e)=>{if(e.tagName==="BODY")return;const t=g(e);t.replaceWith(t.children())}),this},ae.offset=function(){const s=this[0];if(!s)return;const e=s.getBoundingClientRect();return{top:e.top+ao.pageYOffset,left:e.left+ao.pageXOffset}},ae.position=function(){const s=this[0];if(!s)return;const e=An(s,"position")==="fixed",t=e?s.getBoundingClientRect():this.offset();if(!e){const n=s.ownerDocument;let i=s.offsetParent||n.documentElement;for(;(i===n.body||i===n.documentElement)&&An(i,"position")==="static";)i=i.parentNode;if(i!==s&&dt(i)){const r=g(i).offset();t.top-=r.top+yn(i,"borderTopWidth"),t.left-=r.left+yn(i,"borderLeftWidth")}}return{top:t.top-yn(s,"marginTop"),left:t.left-yn(s,"marginLeft")}};const Rd={class:"className",contenteditable:"contentEditable",for:"htmlFor",readonly:"readOnly",maxlength:"maxLength",tabindex:"tabIndex",colspan:"colSpan",rowspan:"rowSpan",usemap:"useMap"};ae.prop=function(s,e){if(s){if(It(s))return s=Rd[s]||s,arguments.length<2?this[0]&&this[0][s]:this.each((t,n)=>{n[s]=e});for(const t in s)this.prop(t,s[t]);return this}},ae.removeProp=function(s){return this.each((e,t)=>{delete t[Rd[s]||s]})};const Pv=/^--/;function Hl(s){return Pv.test(s)}const Ul={},{style:Lv}=kd,Rv=["webkit","moz","ms"];function zv(s,e=Hl(s)){if(e)return s;if(!Ul[s]){const t=Bl(s),n=`${t[0].toUpperCase()}${t.slice(1)}`,i=`${t} ${Rv.join(`${n} `)}${n}`.split(" ");_t(i,(r,o)=>{if(o in Lv)return Ul[s]=o,!1})}return Ul[s]}const Ov={animationIterationCount:!0,columnCount:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0};function zd(s,e,t=Hl(s)){return!t&&!Ov[s]&&Id(e)?`${e}px`:e}function Fv(s,e){if(It(s)){const t=Hl(s);return s=zv(s,t),arguments.length<2?this[0]&&An(this[0],s,t):s?(e=zd(s,e,t),this.each((n,i)=>{dt(i)&&(t?i.style.setProperty(s,e):i.style[s]=e)})):this}for(const t in s)this.css(t,s[t]);return this}ae.css=Fv;function Od(s,e){try{return s(e)}catch{return e}}const jv=/^\s+|\s+$/;function Fd(s,e){const t=s.dataset[e]||s.dataset[Bl(e)];return jv.test(t)?t:Od(JSON.parse,t)}function Bv(s,e,t){t=Od(JSON.stringify,t),s.dataset[Bl(e)]=t}function Hv(s,e){if(!s){if(!this[0])return;const t={};for(const n in this[0].dataset)t[n]=Fd(this[0],n);return t}if(It(s))return arguments.length<2?this[0]&&Fd(this[0],s):jt(e)?this:this.each((t,n)=>{Bv(n,s,e)});for(const t in s)this.data(t,s[t]);return this}ae.data=Hv;function jd(s,e){const t=s.documentElement;return Math.max(s.body[`scroll${e}`],t[`scroll${e}`],s.body[`offset${e}`],t[`offset${e}`],t[`client${e}`])}_t([!0,!1],(s,e)=>{_t(["Width","Height"],(t,n)=>{const i=`${e?"outer":"inner"}${n}`;ae[i]=function(r){if(this[0])return ti(this[0])?e?this[0][`inner${n}`]:this[0].document.documentElement[`client${n}`]:Ss(this[0])?jd(this[0],n):this[0][`${e?"offset":"client"}${n}`]+(r&&e?yn(this[0],`margin${t?"Top":"Left"}`)+yn(this[0],`margin${t?"Bottom":"Right"}`):0)}})}),_t(["Width","Height"],(s,e)=>{const t=e.toLowerCase();ae[t]=function(n){if(!this[0])return jt(n)?void 0:this;if(!arguments.length)return ti(this[0])?this[0].document.documentElement[`client${e}`]:Ss(this[0])?jd(this[0],e):this[0].getBoundingClientRect()[t]-Nd(this[0],!s);const i=parseInt(n,10);return this.each((r,o)=>{if(!dt(o))return;const a=An(o,"boxSizing");o.style[t]=zd(t,i+(a==="border-box"?Nd(o,!s):0))})}});const Bd="___cd";ae.toggle=function(s){return this.each((e,t)=>{if(!dt(t))return;const n=Ed(t);(jt(s)?n:s)?(t.style.display=t[Bd]||"",Ed(t)&&(t.style.display=kv(t.tagName))):n||(t[Bd]=An(t,"display"),t.style.display="none")})},ae.hide=function(){return this.toggle(!1)},ae.show=function(){return this.toggle(!0)};const Hd="___ce",Wl=".",Vl={focus:"focusin",blur:"focusout"},Ud={mouseenter:"mouseover",mouseleave:"mouseout"},Uv=/^(mouse|pointer|contextmenu|drag|drop|click|dblclick)/i;function Kl(s){return Ud[s]||Vl[s]||s}function ql(s){const e=s.split(Wl);return[e[0],e.slice(1).sort()]}ae.trigger=function(s,e){if(It(s)){const[n,i]=ql(s),r=Kl(n);if(!r)return this;const o=Uv.test(r)?"MouseEvents":"HTMLEvents";s=Mn.createEvent(o),s.initEvent(r,!0,!0),s.namespace=i.join(Wl),s.___ot=n}s.___td=e;const t=s.___ot in Vl;return this.each((n,i)=>{t&&xs(i[s.___ot])&&(i[`___i${s.type}`]=!0,i[s.___ot](),i[`___i${s.type}`]=!1),i.dispatchEvent(s)})};function Wd(s){return s[Hd]=s[Hd]||{}}function Wv(s,e,t,n,i){const r=Wd(s);r[e]=r[e]||[],r[e].push([t,n,i]),s.addEventListener(e,i)}function Vd(s,e){return!e||!Rl.call(e,t=>s.indexOf(t)<0)}function po(s,e,t,n,i){const r=Wd(s);if(e)r[e]&&(r[e]=r[e].filter(([o,a,l])=>{if(i&&l.guid!==i.guid||!Vd(o,t)||n&&n!==a)return!0;s.removeEventListener(e,l)}));else for(e in r)po(s,e,t,n,i)}ae.off=function(s,e,t){if(jt(s))this.each((n,i)=>{!dt(i)&&!Ss(i)&&!ti(i)||po(i)});else if(It(s))xs(e)&&(t=e,e=""),_t(uo(s),(n,i)=>{const[r,o]=ql(i),a=Kl(r);this.each((l,c)=>{!dt(c)&&!Ss(c)&&!ti(c)||po(c,a,o,e,t)})});else for(const n in s)this.off(n,s[n]);return this},ae.remove=function(s){return Gn(this,s).detach().off(),this},ae.replaceWith=function(s){return this.before(s).remove()},ae.replaceAll=function(s){return g(s).replaceWith(this),this};function Vv(s,e,t,n,i){if(!It(s)){for(const r in s)this.on(r,e,t,s[r],i);return this}return It(e)||(jt(e)||Wi(e)?e="":jt(t)?(t=e,e=""):(n=t,t=e,e="")),xs(n)||(n=t,t=void 0),n?(_t(uo(s),(r,o)=>{const[a,l]=ql(o),c=Kl(a),h=a in Ud,u=a in Vl;c&&this.each((f,m)=>{if(!dt(m)&&!Ss(m)&&!ti(m))return;const b=function(C){if(C.target[`___i${C.type}`])return C.stopImmediatePropagation();if(C.namespace&&!Vd(l,C.namespace.split(Wl))||!e&&(u&&(C.target!==m||C.___ot===c)||h&&C.relatedTarget&&m.contains(C.relatedTarget)))return;let w=m;if(e){let T=C.target;for(;!Md(T,e);)if(T===m||(T=T.parentNode,!T))return;w=T}Object.defineProperty(C,"currentTarget",{configurable:!0,get(){return w}}),Object.defineProperty(C,"delegateTarget",{configurable:!0,get(){return m}}),Object.defineProperty(C,"data",{configurable:!0,get(){return t}});const S=n.call(w,C,C.___td);i&&po(m,c,l,e,b),S===!1&&(C.preventDefault(),C.stopPropagation())};b.guid=n.guid=n.guid||g.guid++,Wv(m,c,l,e,b)})}),this):this}ae.on=Vv;function Kv(s,e,t,n){return this.on(s,e,t,n,!0)}ae.one=Kv;const qv=/\r?\n/g;function Gv(s,e){return`&${encodeURIComponent(s)}=${encodeURIComponent(e.replace(qv,`\r -`))}`}const Yv=/file|reset|submit|button|image/i,Kd=/radio|checkbox/i;ae.serialize=function(){let s="";return this.each((e,t)=>{_t(t.elements||[t],(n,i)=>{if(i.disabled||!i.name||i.tagName==="FIELDSET"||Yv.test(i.type)||Kd.test(i.type)&&!i.checked)return;const r=Ld(i);if(!jt(r)){const o=lo(r)?r:[r];_t(o,(a,l)=>{s+=Gv(i.name,l)})}})}),s.slice(1)},window.$=g;function qd(s,e){if(s==null)return[s,void 0];typeof e=="string"&&(e=e.split("."));const t=e.join(".");let n=s;const i=[n];for(;typeof n=="object"&&n!==null&&e.length;){let r=e.shift(),o;const a=r.indexOf("[");if(a>0&&a1?i[r-2]:s,e[e.length-1]),o===void 0?t:o}catch{return t}}function Ln(s,e,t,n){let i;const r=Vi(s,e,void 0,o=>{i=o});return typeof r=="function"?r.apply(n??i,t):r}function Zv(s){return typeof s=="string"&&s!==""}function Se(s,...e){if(e.length===0)return s;if(e.length===1&&typeof e[0]=="object"&&e[0]){const t=e[0];return Object.keys(t).forEach(n=>{const i=t[n]??"";s=s.replace(new RegExp(`\\{${n}\\}`,"g"),`${i}`)}),s}for(let t=0;t(s[s.B=1]="B",s[s.KB=1024]="KB",s[s.MB=1048576]="MB",s[s.GB=1073741824]="GB",s[s.TB=1099511627776]="TB",s))(Gl||{});function ht(s,e=2,t){return Number.isNaN(s)?"?KB":(t||(s<1024?t="B":s<1048576?t="KB":s<1073741824?t="MB":s<1099511627776?t="GB":t="TB"),(s/Gl[t]).toFixed(e)+t)}const bn=s=>{const e=/^[0-9]*(B|KB|MB|GB|TB)$/;s=s.toUpperCase(),s.endsWith("B")||(s+="B");const t=s.match(e);if(!t)return 0;const n=t[1];return s=s.replace(n,""),Number.parseInt(s,10)*Gl[n]};let Yl=(document.documentElement.getAttribute("lang")||"zh_cn").toLowerCase().replace("-","_"),Rn;function Gd(){return Yl}function Xv(s){Yl=s.toLowerCase().replace("-","_")}function Yd(s,e){Rn||(Rn={}),typeof s=="string"&&(s={[s]:e??{}}),g.extend(!0,Rn,s)}function Pe(s,e,t,n,i,r){Array.isArray(s)?Rn&&s.unshift(Rn):s=Rn?[Rn,s]:[s],typeof t=="string"&&(r=i,i=n,n=t,t=void 0);const o=i||Yl;let a;for(const l of s){if(!l)continue;const c=l[o]||l.default;if(!c)continue;const h=r&&l===Rn?`${r}.${e}`:e;if(a=Vi(c,h),a!==void 0)break}return a===void 0?n:t?Se(a,...Array.isArray(t)?t:[t]):a}function Jv(s,e,t,n){return Pe(void 0,s,e,t,n)}Pe.addLang=Yd,Pe.getLang=Jv,Pe.getCode=Gd,Pe.setCode=Xv,Pe.map=Rn,Yd({zh_cn:{confirm:"确定",save:"保存",cancel:"取消",delete:"删除",reset:"重置",add:"添加",copy:"复制",close:"关闭"},zh_tw:{confirm:"確定",save:"儲存",cancel:"取消",delete:"刪除",reset:"重置",add:"添加",Copy:"複製",close:"關閉"},en:{confirm:"Confirm",save:"Save",cancel:"Cancel",delete:"Delete",reset:"Reset",add:"Add",copy:"Copy",close:"Close"}});function Ds(s,e,t){t!=null&&(Array.isArray(t)?t.forEach(n=>Ds(s,e,n)):!(t instanceof Blob)&&g.isPlainObject(t)?Object.entries(t).forEach(([n,i])=>{Ds(s,`${e}[${n}]`,i)}):s.append(e,t instanceof Blob?t:String(t)))}function mo(s,e){const t=e||new FormData;return s&&(typeof s=="string"&&(s=new URLSearchParams(s)),s instanceof URLSearchParams?s.forEach((n,i)=>{Ds(t,i,n)}):Array.isArray(s)?s.forEach(([n,i])=>{Ds(t,n,i)}):s instanceof FormData?s.forEach((n,i)=>{Ds(t,i,n)}):typeof s=="object"&&s&&Object.entries(s).forEach(([n,i])=>{Ds(t,n,i)})),t}function St(){return g.guid++}function go(s,e){if(s===e)return!1;if(s&&e){const t=typeof s,n=typeof e;if(t!==n)return!0;if(t==="object"&&n==="object"){const i=Array.isArray(s),r=Array.isArray(e);if(i!==r)return!0;if(i&&r){if(s.length!==e.length)return!0;for(let l=0;ln instanceof Ts?n.value!==t[i]:go(n,t[i])))&&(this._value=this._compute(),this._lastDependencies=e.map(n=>n instanceof Ts?n.cache:n)),this._value}}function Zl(...s){const e=[],t=new Map,n=(i,r)=>{if(Array.isArray(i)&&(r=i[1],i=i[0]),!i.length)return;const o=t.get(i);typeof o=="number"?e[o][1]=!!r:(t.set(i,e.length),e.push([i,!!r]))};return s.forEach(i=>{typeof i=="function"&&(i=i()),Array.isArray(i)?Zl(...i).forEach(n):i&&typeof i=="object"?Object.entries(i).forEach(n):typeof i=="string"&&i.split(" ").forEach(r=>n(r,!0))}),e.sort((i,r)=>(t.get(i[0])||0)-(t.get(r[0])||0))}const q=(...s)=>Zl(...s).reduce((e,[t,n])=>(n&&e.push(t),e),[]).join(" ");g.classes=q,g.fn.setClass=function(s,...e){return this.each((t,n)=>{const i=g(n);s===!0?i.attr("class",q(i.attr("class"),...e)):i.addClass(q(s,...e))})};const ni=new WeakMap;function yo(s,e,t){const n=ni.has(s),i=n?ni.get(s):{};typeof e=="string"?i[e]=t:e===null?Object.keys(i).forEach(r=>{delete i[r]}):Object.assign(i,e),Object.keys(i).forEach(r=>{i[r]===void 0&&delete i[r]}),Object.keys(i).length?(!n&&s instanceof Element&&Object.assign(i,g(s).dataset(),i),ni.set(s,i)):ni.delete(s)}function Ki(s,e,t){let n=ni.get(s)||{};return t&&s instanceof Element&&(n=Object.assign({},g(s).dataset(),n)),e===void 0?n:n[e]}function Qv(s){ni.delete(s)}g.fn.dataset=g.fn.data,g.fn.data=function(...s){const[e,t]=s;return!s.length||s.length===1&&typeof e=="string"?this.length?Ki(this[0],e,!0):void 0:this.each((n,i)=>yo(i,e,t))},g.fn.removeData=function(s=null){return this.each((e,t)=>yo(t,s))};function Zn(s,...e){return s.includes("RAWJS")&&(s=s.split('"RAWJS<').join("").split('>RAWJS"').join("").split("").join('"').split("").join(` -`)),new Function(`return ${s}`)(...e)}function vo(s,...e){return s.includes("RAWJS")?Zn(s,...e):JSON.parse(s)}function eb(s){return JSON.stringify(s,(e,t)=>typeof t=="function"?`RAWJS<${t.toString().split('"').join("").split(` -`).join("")}>RAWJS`:t)}function si(s,e){const t=g(s)[0];if(!t)return;const{prefix:n,getter:i,evalValue:r,json:o=!0,evalArgs:a=[]}={prefix:"z-",...typeof e=="string"?{prefix:e}:e},l=Array.isArray(r)?new Set(r):void 0;return Array.from(t.attributes).reduce((c,h)=>{let{name:u}=h;const{value:f}=h;let m=f;if(u.startsWith(n)){if(u=u.slice(n.length).replace(/-([a-z])/g,b=>b[1].toUpperCase()),i)m=i(u,f);else try{r&&(!l||l.has(u))||r===void 0&&f.includes("RAWJS")?m=Zn(f,...a):o&&(m=JSON.parse(f))}catch{}c[u]=m}return c},{})}function Xl(s,e,t="z-"){const n=g(s);Object.keys(e).forEach(i=>{let r=e[i];typeof r=="function"&&(r=`RAWJS<${r}>RAWJS`),typeof r!="string"&&(r=JSON.stringify(r)),i=i.replace(/[A-Z]/g,o=>`-${o.toLowerCase()}`),n.attr(`${t}${i}`,r)})}function tb(...s){var t;const e=s.length;if(!e)return si(this);if(e===1){const[n]=s;return typeof n=="string"?(t=si(this))==null?void 0:t[n]:(g.isPlainObject(n)&&Xl(this,n),this)}return Xl(this,{[s[0]]:s[1]}),this}g.fn.z=tb,g.fn._attr=g.fn.attr,g.fn.extend({attr(...s){const[e,t]=s;return!s.length||s.length===1&&typeof e=="string"?this._attr.apply(this,s):typeof e=="object"?(e&&Object.keys(e).forEach(n=>{const i=e[n];i===null?this.removeAttr(n):this._attr(n,i)}),this):t===null?this.removeAttr(e):this._attr(e,t)}}),g.Event||(g.Event=(s,e)=>{const[t,...n]=s.split("."),i=new Event(t,{bubbles:!0,cancelable:!0});return i.namespace=n.join("."),i.___ot=t,i.___td=e,i});const zn=(s,e)=>new Promise(t=>{const n=window.setTimeout(t,s);e&&e(n)}),Zd={};g.share=Zd;var bo,Ye,Xd;N.isValidElement=void 0;var $s,Jd,Qd,ef,tf,Jl,Ql,ec,qi={},nf=[],nb=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,Gi=Array.isArray;function On(s,e){for(var t in e)s[t]=e[t];return s}function tc(s){s&&s.parentNode&&s.parentNode.removeChild(s)}function v(s,e,t){var n,i,r,o={};for(r in e)r=="key"?n=e[r]:r=="ref"?i=e[r]:o[r]=e[r];if(arguments.length>2&&(o.children=arguments.length>3?bo.call(arguments,2):t),typeof s=="function"&&s.defaultProps!=null)for(r in s.defaultProps)o[r]===void 0&&(o[r]=s.defaultProps[r]);return _o(s,o,n,i,null)}function _o(s,e,t,n,i){var r={type:s,props:e,key:t,ref:n,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:i??++Xd,__i:-1,__u:0};return i==null&&Ye.vnode!=null&&Ye.vnode(r),r}function pe(){return{current:null}}function Xn(s){return s.children}function ge(s,e){this.props=s,this.context=e}function ii(s,e){if(e==null)return s.__?ii(s.__,s.__i+1):null;for(var t;ea&&$s.sort(ef),s=$s.shift(),a=$s.length,s.__d&&(t=void 0,i=(n=(e=s).__v).__e,r=[],o=[],e.__P&&((t=On({},n)).__v=n.__v+1,Ye.vnode&&Ye.vnode(t),nc(e.__P,t,n,e.__n,e.__P.namespaceURI,32&n.__u?[i]:null,r,i??ii(n),!!(32&n.__u),o),t.__v=n.__v,t.__.__k[t.__i]=t,hf(r,t,o),t.__e!=i&&sf(t)));wo.__r=0}function of(s,e,t,n,i,r,o,a,l,c,h){var u,f,m,b,C,w,S=n&&n.__k||nf,T=e.length;for(l=sb(t,e,S,l,T),u=0;u0?_o(o.type,o.props,o.key,o.ref?o.ref:null,o.__v):o).__=s,o.__b=s.__b+1,a=null,(c=o.__i=ib(o,t,l,u))!=-1&&(u--,(a=t[c])&&(a.__u|=2)),a==null||a.__v==null?(c==-1&&(i>h?f--:il?f--:f++,o.__u|=4))):s.__k[r]=null;if(u)for(r=0;r(h?1:0)){for(i=t-1,r=t+1;i>=0||r=0?i--:r++])!=null&&!(2&c.__u)&&a==c.key&&l==c.type)return o}return-1}function lf(s,e,t){e[0]=="-"?s.setProperty(e,t??""):s[e]=t==null?"":typeof t!="number"||nb.test(e)?t:t+"px"}function ko(s,e,t,n,i){var r,o;e:if(e=="style")if(typeof t=="string")s.style.cssText=t;else{if(typeof n=="string"&&(s.style.cssText=n=""),n)for(e in n)t&&e in t||lf(s.style,e,"");if(t)for(e in t)n&&t[e]==n[e]||lf(s.style,e,t[e])}else if(e[0]=="o"&&e[1]=="n")r=e!=(e=e.replace(tf,"$1")),o=e.toLowerCase(),e=o in s||e=="onFocusOut"||e=="onFocusIn"?o.slice(2):e.slice(2),s.l||(s.l={}),s.l[e+r]=t,t?n?t.u=n.u:(t.u=Jl,s.addEventListener(e,r?ec:Ql,r)):s.removeEventListener(e,r?ec:Ql,r);else{if(i=="http://www.w3.org/2000/svg")e=e.replace(/xlink(H|:h)/,"h").replace(/sName$/,"s");else if(e!="width"&&e!="height"&&e!="href"&&e!="list"&&e!="form"&&e!="tabIndex"&&e!="download"&&e!="rowSpan"&&e!="colSpan"&&e!="role"&&e!="popover"&&e in s)try{s[e]=t??"";break e}catch{}typeof t=="function"||(t==null||t===!1&&e[4]!="-"?s.removeAttribute(e):s.setAttribute(e,e=="popover"&&t==1?"":t))}}function cf(s){return function(e){if(this.l){var t=this.l[e.type+s];if(e.t==null)e.t=Jl++;else if(e.t0?s:Gi(s)?s.map(uf):On({},s)}function rb(s,e,t,n,i,r,o,a,l){var c,h,u,f,m,b,C,w=t.props,S=e.props,T=e.type;if(T=="svg"?i="http://www.w3.org/2000/svg":T=="math"?i="http://www.w3.org/1998/Math/MathML":i||(i="http://www.w3.org/1999/xhtml"),r!=null){for(c=0;c{!t||typeof t!="object"||Object.keys(t).forEach(n=>{let i=t[n];const r=s[n];i!==r&&(r!==void 0&&(n==="className"||n.endsWith("Class")?i=[r,i]:n==="children"?i=[...Co(r),...Co(i)]:typeof r=="object"&&(n==="style"||n.endsWith("Style")||n==="attrs"||n.endsWith("Attrs")||n==="props")&&(i=g.extend(r,i))),s[n]=i)})}),s}function rc(s){return Object.keys(s).forEach(e=>{s[e]===void 0&&delete s[e]}),s}function So(s,e=!0){const t=g(s),n=t[0],i="zui-disable-scroll";if(e){if(t.data(i))return;if((t.css("scrollbar-gutter")||"").includes("stable")){t.data(i,{overflow:t.css("overflow")}).css("overflow","hidden");return}const r=n===document.body||t.is("html")?window.innerWidth-document.body.clientWidth:n.offsetWidth-n.clientWidth;if(!r)return;const o=t.css("paddingRight")||"0";t.data(i,{paddingRight:o,overflow:t.css("overflow")}).css({paddingRight:`${r+Number.parseInt(o,10)}px`,overflow:"hidden"})}else{const r=t.data(i);if(!r)return;t.css(r).removeData(i)}}g.fn.disableScroll=function(s=!0){return this.each((e,t)=>{So(t,s)})},g.fn.enableScroll=function(s=!0){return this.disableScroll(!s)};function oc(s,e,t){if(!(t.on||"click").split(" ").includes(e.type))return;const n=t.selector?g(e.target).closest(t.selector):s;if(!n.length)return;const i=c=>c===""?!0:c,r=c=>{if(typeof c=="string")try{c=JSON.parse(c)}catch{}return c};if(i(t.once)){if(t.onceCalled)return;s.dataset("once-called",!0)}if(i(t.prevent)&&e.preventDefault(),i(t.stop)&&e.stopPropagation(),i(t.self)&&e.currentTarget!==e.target)return;const o=[["$element",s],["event",e],["options",t],["$target",n]],a=c=>typeof c=="function"?c(...o):g.runJS(c,...o);if(t.if!==void 0&&!a(t.if))return;const l=t.call;if(l){let c;if(typeof l=="string"?c=/^[$A-Z_][0-9A-Z_$.]*$/i.test(l)?Vi(window,l):a(l):c=l,typeof c=="function"){const h=[],u=t.params;t.params=h,typeof u=="string"&&u.length?u[0]==="["?h.push(...r(u)):h.push(...u.split(", ").map(f=>(f=f.trim(),f==="$element"?s:f==="event"?e:f==="options"?t:f.startsWith("$element.")||f.startsWith("event.")||f.startsWith("options.")?a(f):r(f)))):Array.isArray(u)?h.push(...u):h.push(u),c(...h)}}t.do&&a(t.do)}function ab(s){const e=g(this),t=s.type,n=e.attr("zui-on");if(n){const[o,a]=n.split("~").map(l=>l.trim());o&&o.split(" ").includes(t)&&oc(e,s,g.extend({on:o},a?a.startsWith("{")?Zn(a):{do:a}:si(e,{prefix:"data-",evalValue:["call","if","do"]})))}const i=e.attr(`zui-on-${t}`);i&&oc(e,s,g.extend({on:t},i.startsWith("{")?Zn(i):{do:i}));const r=e.attr("data-on");r&&r.split(" ").includes(t)&&oc(e,s,si(e,{prefix:"data-",evalValue:["call","if","do"]}))}function ff(s){g(document).off(".zui.global").on(s.map(e=>`${e}.zui.global`).join(" "),`[zui-on],${s.map(e=>`[zui-on-${e}]`)},[data-on]`,ab)}g(()=>{ff(["click","change","inited"])});function Qn(s,e){if(typeof s=="function")return Qn(s(...e||[]));if(typeof s=="number")return[s];let t=s.match(/(\d+)(%|px)?/);return t?[parseInt(t[1]),t[2]]:(t=s.match(/(\d+)\/(\d+)/),t?[100*parseInt(t[1])/parseInt(t[2]),"%"]:[NaN])}function Be(s,e){if(s==null)return null;const[t,n="px"]=Qn(s,e);return Number.isNaN(t)?typeof s=="string"?s:null:`${t}${n}`}async function Is(s,e){var n,i,r;if(s instanceof Blob){const o=document.createElement("a");return o.href=window.URL.createObjectURL(s),e&&(o.download=decodeURIComponent(e)),o.click(),o.remove(),s}if(s instanceof Response){const o=await s.blob();return e=e||((r=(i=(n=s.headers.get("Content-Disposition"))==null?void 0:n.split(";")[1])==null?void 0:i.split("=")[1])==null?void 0:r.replace(/"/g,"")),Is(o,e)}const t=await fetch(s);return Is(t)}class pf{constructor(e){this._$target=g(e)}on(...e){return this._$target.on(...e),this}one(...e){return this._$target.one(...e),this}off(...e){return this._$target.off(...e),this}trigger(...e){return this._$target.trigger(...e),this}}const _n=new pf(document);g.bus=_n,g.on=_n.on.bind(_n),g.one=_n.one.bind(_n),g.off=_n.off.bind(_n),g.trigger=_n.trigger.bind(_n);var lb=["Shift","Meta","Alt","Control"],mf=typeof navigator=="object"?navigator.platform:"",gf=/Mac|iPod|iPhone|iPad/.test(mf),cb=gf?"Meta":"Control",hb=mf==="Win32"?["Control","Alt"]:gf?["Alt"]:[];function ac(s,e){return typeof s.getModifierState=="function"&&(s.getModifierState(e)||hb.includes(e)&&s.getModifierState("AltGraph"))}function ub(s){return s.trim().split(" ").map(function(e){var t=e.split(/\b\+/),n=t.pop();return[t=t.map(function(i){return i==="$mod"?cb:i}),n]})}function yf(s,e){var t;e===void 0&&(e={});var n=(t=e.timeout)!=null?t:1e3,i=Object.keys(s).map(function(a){return[ub(a),s[a]]}),r=new Map,o=null;return function(a){a instanceof KeyboardEvent&&(i.forEach(function(l){var c=l[0],h=l[1],u=r.get(c)||c;(function(f,m){return!(m[1].toUpperCase()!==f.key.toUpperCase()&&m[1]!==f.code||m[0].find(function(b){return!ac(f,b)})||lb.find(function(b){return!m[0].includes(b)&&m[1]!==b&&ac(f,b)}))})(a,u[0])?u.length>1?r.set(c,u.slice(1)):(r.delete(c),h(a)):ac(a,a.key)||r.delete(c)}),o&&clearTimeout(o),o=setTimeout(r.clear.bind(r),n))}}function db(s,e,t){var n;t===void 0&&(t={});var i=(n=t.event)!=null?n:"keydown",r=yf(e,t);return s.addEventListener(i,r),function(){s.removeEventListener(i,r)}}function lc(s,e={}){if(!s)return;const t=Object.keys(e).reduce((n,i)=>(e[i].optional||(n[i]={...e[i]}),n),{});return Object.keys(s).forEach(n=>{const i=s[n];i?i===!0?e[n]&&(t[n]={...e[n]}):t[n]=i:delete t[n]}),Object.keys(t).reduce((n,i)=>{const{keys:r,handler:o}=t[i];return typeof r=="string"?n[r]=o:r.forEach(a=>{n[a]=o}),n},{})}function cc(s,e,t){const{timeout:n,event:i="keydown",scope:r,when:o}=t||{},a=yf(e,{timeout:n}),l=`.zui.hotkeys${r?`.${r}`:""}`,c="zui-hotkeys-composing";return g(s).on(`${i}${l}`,function(h){o&&o(h)===!1||g(h.target).data(c)||a(h)}).on(`compositionstart${l}`,h=>{g(h.target).data(c,!0)}).on(`compositionend${l}`,h=>{g(h.target).removeData(c)})}function hc(s,e){return g(s).off(`.zui.hotkeys${e?`.${e}`:""}`)}const fb=db;g.fn.hotkeys=function(s,e){return cc(this,s,e)},g.fn.unbindHotkeys=function(s){return hc(this,s)},g.hotkeys=function(s,e){cc(window,s,e)},g.unbindHotkeys=function(s){hc(window,s)};function xo(){return document.fullscreenElement||document.webkitFullscreenElement||document.mozFullScreenElement}async function vf(s){(typeof s=="string"||s instanceof Element||s instanceof g)&&(s={target:s});const{target:e,onError:t,onSuccess:n,afterExit:i,afterEnter:r}=s,o=g(e),a=o[0];if(!a)return;const l=a.requestFullscreen||a.webkitRequestFullscreen||a.mozRequestFullScreen;if(!l){t==null||t.call(a,new Error("[ZUI] The browser does not support full screen feature."));return}try{await l.call(a),n==null||n.call(a),g(a).off(".zui.fullscreen"),i&&o.on("exitFullscreen.zui.fullscreen",i),r&&o.on("enterFullscreen.zui.fullscreen",r)}catch(c){t==null||t.call(a,c)}document.zuiBindFullscreenChange||(document.zuiBindFullscreenChange=!0,g(document).on("fullscreenchange.zui webkitfullscreenchange.zui mozfullscreenchange.zui",c=>{const h=xo();let u=h;h?g(h).addClass("is-in-fullscreen"):(u=g(document).find(".is-in-fullscreen")[0]||document,g(u).removeClass("is-in-fullscreen")),g("body").toggleClass("has-in-fullscreen",!!h);const f={event:c,target:u,fullscreenElement:h};g(u).trigger(h?"enterFullscreen":"exitFullscreen",f).trigger("toggleFullscreen",f)}))}async function Do(s){const e=xo();return s===!1&&!!e===s?s:e?(document.exitFullscreen(),!1):(await vf(s),!0)}g.fn.fullscreen=function(s){return Do({target:this,...s})},g.getFullscreenElement=xo,g.toggleFullscreen=Do;function es(s){return!s||s.parentNode===document?!1:s.parentNode?es(s.parentNode):!0}g.isDetached=es,g.fn.isDetached=function(){const s=this[0];return!s||es(s)};const Ns=class Gy{constructor(e,t){var b,C;this._inited=!1,this._autoDestory=0,this._destroyed=!1;const{KEY:n,DATA_KEY:i,MULTI_INSTANCE:r,NAME:o,ATTR_KEY:a,ALL:l,TYPED_ALL:c}=this.constructor;if(!o)throw new Error('[ZUI] The component must have a "NAME" static property.');const h=g(e);if(h.data(n)&&!r)throw new Error(`[ZUI] The component "${o}" has been initialized on element.`);const u=h[0];if(!u)throw new Error(`[ZUI] Invalid selector "${e}" for component "${o}", can not find the element matched.`);const f=St();this._gid=f,this._element=u,this.resetOptions(t),this._key=this.options.key??`__${f}`;let m=l.get(u);if(m?m.add(this):(m=new Set([this]),l.set(u,m)),c.has(o)?(b=c.get(o))==null||b.add(this):c.set(o,new Set([this])),h.data(n,this).attr(a,"").attr(i,`${f}`).attr("z-use",[...new Set([...m||[]].map(w=>w.constructor.NAME))].join(",")),r){const w=`${n}:ALL`;let S=h.data(w);S||(S=new Map,h.data(w,S)),S.set(this._key,this)}this.init(),(C=this.options.$onCreate)==null||C.call(this),requestAnimationFrame(async()=>{var S;const{$fetcher:w}=this.options;if(w){const T=await it(w,[],{dataType:"js"});if(this.destroyed)return;T&&this.setOptions(T)}this._inited=!0,await this.afterInit(),this.emit("inited",this.options),(S=this.options.$onInited)==null||S.call(this)})}static get ZUI(){return this.NAME.replace(/(^[A-Z]+)/,e=>e.toLowerCase())}static get KEY(){return`zui.${this.NAME}`}static get NAMESPACE(){return`.zui.${this.ZUI}`}static get DATA_KEY(){return`data-zui-${this.NAME}`}static get ATTR_KEY(){return`z-use-${this.NAME}`}static get SELECTOR(){return`[${this.DATA_KEY}]`}get inited(){return this._inited}get destroyed(){return this._destroyed}get element(){if(!this._element)throw new Error("[ZUI] Component element is not available.");return this._element}get key(){return this._key}get options(){if(!this._options)throw new Error("[ZUI] Component options are not available.");return this._options}get gid(){return this._gid}get $element(){return g(this.element)}get $emitter(){return this.$element}get i18nData(){return[this.options.i18n,this.constructor.i18n]}init(){}afterInit(){}render(e,t){this.setOptions(e,t)}destroy(){var m;const{KEY:e,DATA_KEY:t,ALL:n,TYPED_ALL:i,NAME:r,MULTI_INSTANCE:o,ATTR_KEY:a}=this.constructor,{$element:l,element:c}=this;if(this.emit("destroyed"),this._destroyed=!0,l.off(this.namespace).removeData(e).removeAttr(a).removeAttr(t),o){const b=this.$element.data(`${e}:ALL`);if(b)if(b.delete(this._key),b.size===0)this.$element.removeData(`${e}:ALL`);else{const C=b.values().next().value;l.data(e,C).attr(t,String(C==null?void 0:C.gid))}}const h=n.get(c);h&&(h.delete(this),h.size===0&&n.delete(c));const u=i.get(r);u&&(u.delete(this),u.size===0&&i.delete(r));const f=n.get(c);f!=null&&f.size?l.attr("z-use",[...new Set([...f].map(b=>b.constructor.NAME))].join(",")):l.removeAttr("z-use"),(m=this.options.$onDestroy)==null||m.call(this)}autoDestroy(e=100){this._autoDestory&&clearTimeout(this._autoDestory),this._autoDestory=window.setTimeout(()=>{this._autoDestory=0,es(this.element)&&this.destroy()},e)}setOptions(e,t){if(t){const n={...this.constructor.DEFAULT,...(e==null?void 0:e.$optionsFromDataset)!==!1?this.$element.dataset():{},...e},{$options:i}=n;if(i){const r=typeof i=="function"?i.call(this,this.element,n):i;r&&g.extend(n,r),delete n.$options}this._options=n}else e&&g.extend(this._options,e);if(!this._options)throw new Error("[ZUI] Component options are not available.");return this._options}resetOptions(e){return this.setOptions(e,!0)}emit(e,...t){const n=g.Event(e);return n.__src=this,this.$emitter.trigger(n,[this,...t]),n}on(e,t,n){const i=this;this.$element[n!=null&&n.once?"one":"on"](this._wrapEvent(e),function(r,o){(!r.__src||r.__src===i)&&t.call(this,r,o)})}one(e,t){this.on(e,t,{once:!0})}off(e){this.$element.off(this._wrapEvent(e))}i18n(e,t,n){const{i18nData:i}=this;return Pe(i,e,t,n,this.options.lang,this.constructor.NAME)??Pe(i,e,t,n,this.options.lang)??`{i18n:${e}}`}get namespace(){return`${this.constructor.NAMESPACE}.${this._key}`}_wrapEvent(e){return e.split(" ").map(t=>t.includes(".")?t:`${t}${this.namespace}`).join(" ")}static get(e,t){const n=g(e);if(this.MULTI_INSTANCE&&t!==void 0){const i=n.data(`${this.KEY}:ALL`);return i?i.get(t):void 0}return n.data(this.KEY)}static isValid(e){return!0}static ensure(e,t){const n=this.get(e,t==null?void 0:t.key);if(n){if(this.isValid(n))return t&&n.setOptions(t),n;n.destroy()}return new this(e,t)}static getAll(e,t){var l;const{SELECTOR:n,ALL:i,TYPED_ALL:r}=this,o=[],a=c=>{c instanceof this&&(!t||t(c)!==!1)&&o.push(c)};return e?g(e).find(n).each((c,h)=>{var u;(u=i.get(h))==null||u.forEach(a)}):this!==Gy?(l=r.get(this.NAME))==null||l.forEach(a):i.forEach(c=>{c.forEach(a)}),o.sort((c,h)=>c.gid-h.gid)}static query(e,t,n){return e===void 0?this.getAll(void 0,n).pop():this.get(g(e).closest(this.SELECTOR),t)}static defineFn(e){let t=e||this.ZUI;g.fn[t]&&(t=`zui${this.NAME}`);const n=this;g.fn.extend({[t](i,...r){const o=typeof i=="object"?i:void 0,a=typeof i=="string"?i:void 0;let l;return this.each((c,h)=>{let u=n.get(h);if(u)o&&u.render(o);else{if(a)return;u=new n(h,o)}if(a){let f=u[a],m=u;f===void 0&&(m=u.$,f=m[a]),typeof f=="function"?l=f.call(m,...r):l=f}}),l!==void 0?l:this}})}static register(e,t){var i,r;e=e||this,t=(t??e.NAME).toLowerCase(),this.map.set(t,e);const n=(r=(i=e.toggle)==null?void 0:i.name)==null?void 0:r.toLowerCase();n&&n!==t&&this.toggleMap.set(n,e)}};Ns.DEFAULT={},Ns.MULTI_INSTANCE=!1,Ns.ALL=new Map,Ns.TYPED_ALL=new Map,Ns.map=new Map,Ns.toggleMap=new Map;let Ve=Ns;function Yi(s){return Ve.map.get(s.toLowerCase())}function To(s,e,t={}){let n=typeof s=="function"?s:Yi(s);if(n||(n=uc(s)),!n)return null;const{$update:i,...r}=t;if(!n.MULTI_INSTANCE){const o=n.get(e);if(o)return i&&o.render(r,i==="reset"),o}return new n(e,r)}function bf(s,e,t={}){requestAnimationFrame(()=>To(s,e,t))}function _f(s,e){Ve.register(s,e)}function uc(s){const{zui:e}=window;if(e){s=s==null?void 0:s.toLowerCase();for(const t in e){const n=t.toLowerCase()===s;if(s&&!n)continue;const i=e[t];if(!(typeof i!="function"||!i.NAME||!i.ZUI)&&(Ve.map.has(t.toLowerCase())||_f(i),n))return i}}}function pb(s){var e;s?(e=Yi(s))==null||e.defineFn():window._zuiDefined||(uc(),Ve.map.forEach(t=>{t.defineFn()}),Object.assign(window,{_zuiDefined:!0}))}function mb(s,e={}){const t=g(s);let n=t.attr("zui-create");const{update:i,onCreate:r}=e,o=(a,l)=>{if(l={$update:i,$optionsFromDataset:!1,...l},r){const h=r(a,l);if(h===!1)return;h&&(l=h)}const c=l.$lib;if(c){delete l.$lib,g.getLib(c).then(()=>bf(a,s,l));return}bf(a,s,l)};if(typeof n=="string"){n=n.trim();const a=n.length?n.split(",").map(h=>h.trim()):[],l=si(s,{prefix:"zui-create-",evalValue:!0})||{},c=Object.keys(l);if(!c.length&&a.length===1)o(a[0],t.dataset());else{const h=new Set;[...a,...c].forEach(u=>{if(h.has(u))return;const f=l[u];o(u,f),delete l[u],h.add(u)})}}else{const a=t.dataset(),l=a==null?void 0:a.zui;if(!l)return;console.warn("[ZUI] create component instance with [data-zui] is deprecated, use [zui-create] instead.",{element:s,options:e}),a==null||delete a.zui,o(l,a)}}function gb(){g(document).on("click.zui.toggle mouseenter.zui.toggle","[data-toggle],[zui-toggle]",function(s){const e=g(this),t=e.dataset("toggle")||e.attr("zui-toggle");if(!t)return;const n=Ve.toggleMap.get(t)||Yi(t),i=n==null?void 0:n.toggle;if(!i)return;const{trigger:r="click",skip:o="[disabled],.disabled",check:a}=i,l=s.type==="mouseover"?"hover":"click";if(!r.includes(l)||a&&!a.call(n,this,l,s)||o&&e.is(o))return;const{onGet:c,onCreate:h,setOptions:u=!0,getOptions:f,prevent:m=!0,handler:b,onToggle:C,convertHref:w}=i;let S=e.dataset();const T=e.attr(`zui-toggle-${t}`);if(T&&(S=g.extend(S,Zn(T))),w&&e.is("a")){const A=e.attr("href");if(A){const L=w===!0?{selector:"target",url:"url"}:w;"#.".includes(A[0])?L.selector&&S[L.selector]===void 0&&(S[L.selector]=A):L.url&&S[L.url]===void 0&&(S[L.url]=A)}}if(f&&(S=f.call(n,this,S,s)),b){b.call(n,this,S,l,s),m&&s.preventDefault();return}let I=c?c.call(n,this):n.get(this);if(I)u&&I.setOptions(S);else{const A=h?h.call(n,this,s,S):new n(this,S);if(!A)return;I=A}if(C){if(C.call(n,I,this,s)===!1)return}else{const{shown:A,show:L,hide:U,toggle:Y}=I;let Z;if(Y?Z=Y:L&&U?A?Z=U:Z=L:L&&(Z=L),Z)Z.call(I);else return}m&&s.preventDefault()})}function yb(s,e){const t=Ki(s),n=[];return Object.keys(t).forEach(i=>{if(!i.startsWith("zui."))return;const r=t[i];(e==null?void 0:e(r,i))!==!1&&n.push(t[i])}),n}let $o=0;function wf(s=100){if($o&&clearTimeout($o),s){$o=window.setTimeout(()=>wf(0),s);return}$o=0,Ve.ALL.forEach(e=>{e.forEach(t=>t.autoDestroy())})}function vb(){if(!document.body||Ki(document.body,"_autoDestoryMob"))return;const s=new MutationObserver(e=>{let t=!1;for(const n of e)if(n.removedNodes.length){t=!0;break}t&&wf()});s.observe(document.body,{childList:!0,subtree:!0}),yo(document.body,"_autoDestoryMob",s)}function dc(s,e){const t=g(s);t.find("[zui-create],[data-zui]").each(function(){var n;((n=e==null?void 0:e.beforeCreate)==null?void 0:n.call(e,this))!==!1&&mb(this,e)}),t.find("[zui-init]").each(function(){if(this.hasAttribute("z-zui-inited"))return;this.setAttribute("z-zui-inited","");const n=this.getAttribute("zui-init");n&&g.runJS(n,["$element",g(this)])}),t.find(".hide-before-init").removeClass("invisible hidden opacity-0"),t.find(".scroll-into-view").scrollIntoView(),t.find('[data-on="inited"],[zui-on-inited]').each((n,i)=>{const r=g(i);r.zui()||r.trigger("inited")}),e!=null&&e.runJS&&t.runJS()}g.fn.zuiInit=function(s){return dc(this,s),this},g.fn.zui=function(s,e){const t=this[0];if(!t)return;if(typeof s!="string"){const i={};let r;return yb(t,(o,a)=>{i[a]=o,(!r||r.gid1?t[0]:void 0,i=t[t.length>1?1:0],r=g(this).zui(n),o=r==null?void 0:r[i];typeof o=="function"&&o.apply(r,e)}),this},g(()=>{g("body").zuiInit({update:!0}),gb(),vb()});class Io extends Ve{get $targets(){const{$element:e}=this,{targets:t}=this.options;return t?e.find(t):e}_handleScroll(e,t,n){const{offset:i=1}=this.options,r=this.$targets,o=e.getBoundingClientRect(),{scrollTop:a,scrollLeft:l}=e;r.each((c,h)=>{const u=h.getBoundingClientRect(),f=t==="top"&&a>0&&u.top<=o.top+i||t==="bottom"&&u.bottom>=o.bottom-i||t==="left"&&l>0&&u.left<=o.left+i||t==="right"&&l{this._raf&&cancelAnimationFrame(this._raf),this._raf=requestAnimationFrame(()=>{this._raf=0,this._handleScroll(l,t,i)})};this._scrollListener=c,l.addEventListener("scroll",c)}this._container=l,requestAnimationFrame(()=>{this._handleScroll(l,t,i)})}else this._ob=new IntersectionObserver(l=>{l.forEach(c=>{c.target.classList.toggle(i,c.intersectionRatiothis._ob.observe(c))}destroy(){var e;(e=this._ob)==null||e.disconnect(),this._container&&(this._container.removeEventListener("scroll",this._scrollListener),this._raf&&cancelAnimationFrame(this._raf))}}Io.NAME="Sticky";const ri=24*60*60*1e3,Ze=s=>s===void 0?new Date:(s instanceof Date||(typeof s=="string"&&(s=s.trim(),/^\d+$/.test(s)&&(s=Number.parseInt(s,10))),typeof s=="number"&&s<1e10&&(s*=1e3),s=new Date(s)),s),Cf=(s,e,t="day")=>{if(typeof e=="string"){const n=Number.parseInt(e,10);t=e.replace(n.toString(),""),e=n}return s=new Date(Ze(s).getTime()),t==="month"?s.setMonth(s.getMonth()+e):t==="year"?s.setFullYear(s.getFullYear()+e):t==="week"?s.setDate(s.getDate()+e*7):t==="hour"?s.setHours(s.getHours()+e):t==="minute"?s.setMinutes(s.getMinutes()+e):t==="second"?s.setSeconds(s.getSeconds()+e):s.setDate(s.getDate()+e),s},ts=(s,e=new Date)=>Ze(s).toDateString()===Ze(e).toDateString(),Zi=(s,e=new Date)=>Ze(s).getFullYear()===Ze(e).getFullYear(),fc=(s,e=new Date)=>(s=Ze(s),e=Ze(e),s.getFullYear()===e.getFullYear()&&s.getMonth()===e.getMonth()),bb=(s,e=new Date)=>{s=Ze(s),e=Ze(e);const t=1e3*60*60*24,n=Math.floor(s.getTime()/t),i=Math.floor(e.getTime()/t);return Math.floor((n+4)/7)===Math.floor((i+4)/7)},_b=(s,e)=>ts(Ze(e),s),wb=(s,e)=>ts(Ze(e).getTime()-ri,s),Cb=(s,e)=>ts(Ze(e).getTime()+ri,s),pc=s=>s!=null&&!isNaN(Ze(s).getTime()),st=(s,e="yyyy-MM-dd hh:mm",t="")=>{if(s=Ze(s),!pc(s))return t;if(typeof e=="function")return e(s);const n={"M+":s.getMonth()+1,"d+":s.getDate(),"h+":s.getHours(),"H+":s.getHours()%12,"m+":s.getMinutes(),"s+":s.getSeconds(),"S+":s.getMilliseconds()};return/(y+)/i.test(e)&&(e.includes("[yyyy-]")&&(e=e.replace("[yyyy-]",Zi(s)?"":"yyyy-")),e=e.replace(RegExp.$1,`${s.getFullYear()}`.substring(4-RegExp.$1.length))),Object.keys(n).forEach(i=>{if(new RegExp(`(${i})`).test(e)){const r=`${n[i]}`;e=e.replace(RegExp.$1,RegExp.$1.length===1?r:`00${r}`.substring(r.length))}}),e},kb=(s,e,t)=>{const n={full:"yyyy-M-d",month:"M-d",day:"d",str:"{0} ~ {1}",...t},i=st(s,Zi(s)?n.month:n.full);if(ts(s,e))return i;const r=st(e,Zi(s,e)?fc(s,e)?n.day:n.month:n.full);return n.str.replace("{0}",i).replace("{1}",r)};function mc(s){let e=0;if(typeof s!="string"&&(s=String(s)),s&&s.length)for(let t=0;t{try{a.includes("%")&&(a=decodeURIComponent(a)),a=JSON.parse(a)}catch{}return[o,a]})),params:n.map(o=>{if(o!=="undefined"){if(o==="null")return null;try{return o.includes("%")&&(o=decodeURIComponent(o)),JSON.parse(o)}catch{return o}}})}}function kf(s){if(Array.isArray(s))return{commands:s.map(No).filter(Boolean)};if(typeof s=="object")return s;s=s.replace(/^#!?/,"");const e=s.includes(">"),t=s.split(e?">":"|").map(No);return{async:e,commands:t.filter(Boolean)}}function gc(s,e,t){if(typeof s=="string"&&(s=No(s)),!s)return;const{execute:n,event:i,scope:r}=e;if(!(r&&s.scope&&s.scope!==r))return n({name:s.name,options:{...e.options,...s.options},event:i,scope:s.scope,prevResult:t},s.params)}async function Sf(s,e){const{async:t,commands:n}=kf(s);if(!n.length)return[];const{signal:i}=e;if(t){const o=[];let a;for(const l of n){if(!(i!=null&&i.aborted))break;a=await gc(l,e,a),i!=null&&i.aborted&&(a=void 0),o.push(a)}return o}return await Promise.all(n.map(o=>{if(!(i!=null&&i.aborted))return gc(o,e)}))}const oi="zui.commands",ai="z-commands",yc="zui-commands-proxy",xf="zui-command",Eo={};function Df(s,e){typeof s=="string"&&e?Eo[s]=e:typeof s=="object"&&Object.assign(Eo,s)}function Mo(s,e){typeof e=="string"?e={scope:e}:typeof e=="function"&&(e={onCommand:e});const{scope:t="",events:n="click"}=e??{},i=g(s),r=(i.attr(ai)||"").split(",");t&&!r.includes(t)&&r.push(t),i.attr(ai,r.join(",")).data(oi,{[t]:{...e,scope:t,events:n,gid:St()},...i.data(oi)})}function Ao(s,e=!0){const t=g(s);if(e===!0)t.removeAttr(ai),t.removeData(oi);else if(e.length){const n=t.data(oi)||{};e.split(",").forEach(r=>{delete n[r]});const i=Object.keys(n);i.length?t.attr(ai,i.join(",")).data(oi,Mo):Ao(t,!0)}}function Tf(s,e){let t=s.closest(`[${ai}],[${yc}]`).first();if(t.attr(yc)!==void 0&&(t=g(t.data("zui.commandProxy")||t.attr(yc)).closest(`[${ai}]`)),!t.length)return;const n=t.data(oi)||{},i=Object.values(n).sort((o,a)=>a.gid-o.gid);let r;return e!=null&&e.length?(r=i.find(o=>o.scope===e),r||(r=i.find(o=>{var a;return!((a=o.scope)!=null&&a.length)&&!o.scoped})),r):(r=i.find(o=>{var a;return!((a=o.scope)!=null&&a.length)&&!o.scoped}),r||(r=i.find(o=>!o.scoped)),r?r.element=t[0]:r=Tf(s.parent(),e),r)}function Sb(s){if(!s.currentTarget)return;const e=g(s.currentTarget);if(e.closest(".disabled,[disabled]").length)return;const t=e.attr(xf)||(e.is('a[href^="#!"]')?e.attr("href"):"");if(!t)return;const n=new AbortController,i=()=>n.abort();Sf(t,{signal:n.signal,execute:(r,o)=>{const{scope:a,name:l}=r,c={...r,abort:i};let h;const u=Tf(e,a);if(u){c.element=u.element;const m=(u.commands?u.commands[`${a}~${l}`]||u.commands[l]:null)||u.onCommand;if(m&&(h=m(c,o),s.commandHandled))return h}const f=[c,o];if(e.trigger("command",f).trigger(`command:${a?`${l}.${a}`:l}`,f),a&&e.trigger(`command:.${a}`,f),s.commandHandled)return h;if(a==="event"){l==="stop"?s.stopPropagation():l==="prevent"?s.preventDefault():Ln(s,l,o);return}if(a!=null&&a.startsWith(".")){let m;if(a===".")m=e.closest("[z-use]").zui();else{const b=a.substring(1);m=e.closest(`[z-use-${b}]`).zui(b)}if(m)return Ln(m,l,o);console.warn(`[ZUI] Command "${l}" not found in scope "${a}".`);return}return a==="window"?Ln(window,l,o):a==="zui"?Ln(window.zui,l,o):a==="target"?Ln(e[0],l,o):a==="$target"?Ln(e,l,o):a==="$"?Ln(g,l,o):a===""&&Eo[l]!==void 0?Eo[l](c,o):h},event:s})}g.fn.command=function(s,e){return this.on(`command:${s}`,e)},g.fn.offCommand=function(s,e){return this.off(`command:${s}`,e)},g.fn.commands=function(s){return this.each((e,t)=>Mo(t,s)),this},g.fn.unbindCommands=function(s){return this.each((e,t)=>Ao(t,s)),this},g(()=>{g(document).on("click.zui.command",`[${xf}],a[href^="#!"]`,Sb)});function Xi(s,e,t=!1){var i;const n=g(s);if(e!==void 0){if(typeof e=="string"&&e.length){const r=`zui-runjs-${St()}`;n.append(`